The API world is one of constant evolution and mutation. The data that we dealt with in the 1990s is not the same as the data we might deal with in 2017, and because of this, our APIs have had to drastically change in their approaches. These changes are issues in the API architecture space that we are only just now becoming aware of.
Thankfully, these issues are being resolved by new technologies, approaches, and concepts, and as such, warrant some discussion. In this piece, we’re going to talk about 7 growing API design trends, and what they mean within the context of past API design. We’ll discuss the implications of incorporating new API designs, and what they mean for the modern API and its future applications.
The Lense of the Past
The API world is largely one of evolution and iteration. It should come as no surprise, then, that many of the issues in the modern API space derive from the fact that we’ve been effectively putting a band-aid over the inequities and issues of past implementations and approaches. In the 1990s, the concept of Distributed Object Integration reigned supreme, allowing resources to be collated and linked to one another for users to more fully manipulate and integrate with.
Following this, in the early 2000’s, the movement to and support for SOAP for corporation-to-corporation integration and resource sharing made DOI-style systems somewhat obsolete for most use cases. SOAP reigned on high for many use cases, but itself had significant issues that required further systems to be developed, iterated upon, and implemented in the foreseeable future.
With the coming of the 2010’s, APIs shifted away from stateful APIs designed for network stacks and into the concept of stateless design with a focus on mobile data integration. Smartphones, once thought a limited field of telecommunications, now held the promise of micro-supercomputers in the palms of our hands, and our data solutions appropriately had to scale to meet this demand. RESTful design was quickly taken to by developers as a de facto standard, and solutions like GraphQL promised to negate many of the issues with SOAP and earlier solutions.
The fundamental problem in all of this, though, is that we’re still stuck in the earliest designs of the internet and of the APIs that drive communication — we may iterate more complexity, but at the end of the day, our modern mansion is still built upon a 30 year old foundation.
CRUD – Why it’s Cruddy
APIs are fundamentally stuck in the land of CRUD – that is Create, Read, Update, Delete. In the regular process of an API, the user requests a resource be created, that they read a resource, that a resource is updated, or that the resource is deleted — and that’s all they request. Every single function a CRUD-centric API will do is a simple combination of those four elements, and nothing more.
This was fine in the early 2000’s when all we needed was the timestamp on a file, but the modern media landscape requires more permeability, and increased flexibility in how we deal with information. Because of this, the CRUD model is inefficient because it does not mirror what we actually use APIs for anymore.
Interfacing with voice-assistants like Alexa requires collations of resources and AI-like functions to discern relevance, interest, and value – this is not something easily done with a CRUD system, which is why CRUD is not the design structure of the frontend systems that drive Alexa. Other such implementations, ranging from Google Home to interconnected Apple devices show that CRUD is no longer applicable to all design requirements.
With all of this being said, what alternatives do we have?
1. Hypermedia and HATEOAS
Hypermedia and HATEOAS (Hypermedia as the Engine of Application State) is one answer to this dilemma, and is a solution principally concerned with the linking of resources. In a classic CRUD API architecture, this isn’t necessarily something that’s easily done. Simply put, hypermedia provides a more detailed response to a simplified query by including hypermedia links with each response dynamically.
As an example, a user might send a request on information about a project. A hypermedia system will then respond to that project with the information requested, as well as the status of the project, links to related resources, and sometimes even options for manipulation of that project.
Often, these projects are given a metatag or some other method of linking, allowing for even more complex interactions governed by relation, type, and function. In many ways, this mimics (and could arguably be the precursor to) modern AI applications that intelligently link resources by relation. Hypermedia types like HAL, Siren HAL, Collection+JSON, or Atom/AtomPub provide a standard means to implement this.
2. Event Subscriptions
In this type of design approach, the usual interaction between the API and the user is reversed. In a traditional architecture, the user comes to the API, makes a request, and then voluntarily terminates that interaction. The actual relationship between the user and the provider is terminal and temporary, and as such, is expressly limited.
In an event subscription architecture, this relationship is inverted. While the user does make the initial contact, the relationship is not temporary and terminal – a continual relationship is created in which the user subscribes to the information and its future updates.
In this type of architectural design, a user subscribes to the entity, and when a change is made, the changes are given in the metadata and provided as an up to date resource representation. The API in this case serves two primary functions – first, the API serves the function of actually delivering the resources to the requesting user, and second, the API serves as a message broker to collate publisher additions and update those who have subscribed.
This fundamentally changes the relationship between user and API, and assures a continual, active experience for subscribed users.
3. Capability-Driven API Design
Many of the design trends discussed in this piece are modifications of the traditional CRUD methodologies and approaches in order to extend the function. Capability-driven API design, however, eschews CRUD methods altogether. Capability-driven architecture builds upon the functions actually required by the user, and is typically a series of custom relationships or instructions based upon a narrow set of functions within a greater range of predefined functions, services, and applets.
As an example, there are numerous integrations that exist which allow sharing tweets from a list of Twitter accounts routinely, creating a unique Trello card on a weekly basis, automatically saving Gmail attachments to Dropbox as a unique file, and even updating local files in a Dropbox backup when a remote file is changed — these are all possible due to capability-driven APIs; the type of interactions don’t match well to a typical CRUD system.
4. Content Negotiation
If capability-driven API design is a way to design for application specificity, content negotiation is arguably a way to design for a lack of specificity. Content negotiation is a process in which a given set of possible input variations is narrowed down to a singular likely input that is the best possible representation of that request for the requesting entity.
”HTTP has provisions for several mechanisms for “content negotiation” – the process of selecting the best representation for a given response when there are multiple representations available.”
– RFC 2616 Fielding
5. Frontend Context APIs
Whereas content negotiation is centered upon catering content to the requesting user, frontend context APIs enable even more dynamic interactions. A frontend context API will map APIs to devices and manage these interactive sessions dynamically. Chief of these ways is by asking for additional content and information to frame the request with — a frontend context API essentially enables more complex, detailed requests, and then ports this in a packaged form to the backend.
This ultimately results in a situation in which the user is drilled for information to complete the request that they actually want, rather than the request they authored. This might seem counterintuitive – after all, the user should know exactly what they want – but it ultimately results in richer requests, and thereby more accurately delivered data.
6. On-Device APIs
An internal, on-device API handles versions and synchronization between the online repository and the local one. A good example would be that of storing and forwarding for offline synchronization.
This can’t be handled in an easy way using CRUD, because it details internal versioning unique from the external repository, and requires versioning and updating that would otherwise require multiple interacting APIs. If the API itself is built from the beginning to be on-device and working in tandem as a disjointed pair, however, this is made much easier.
Another implementation would be a bot serving as an internal entry point to the API itself. An example of this would be on Slack, when you talk to the internal bot to set up a meeting, save a file, or do some other function. You’re not expressly talking to an API per se, but you’re not talking to a person – you’re instructing an API to do something on the device on your behalf, and this command is communicated to the system as a whole.
7. Bots as Next Generation APIs
Bots now serve an ever growing range of purposes, and as the internet grows and becomes more demanding, it’s to be expected that APIs will become more numerous alongside them. The current assumption that bots are talking to humans may not always be true – in future applications, bots may talk to bots, and applications could talk to bots as if they were APIs.
These communications leverage more than just a single API – they collate many APIs and many bots into a single network in which their collaborative sum is greater than their combined whole. This will become more and more standard as bots become smarter and more capable – and as AI develops in the future, it will likely take the form of a bot interfacing with other bots rather than an AI taking requests.
The simple fact is that CRUD is no longer the most applicable and capable of design architectural approaches as it used to be. The internet is evolving, and so too are the needs of the average user. With this evolution of need, API developers need to start considering additional methodologies and design approaches. In the future, failing to do so may result in the propagation of stopgaps and bandaids designed to make CRUD do things that it’s not really meant to do.
All of that being said, these 7 trends are strong ones, and they’re promising to say the least. It will be interesting to see what these designs ultimately create, and whether or not they will be able to fully break free of the CRUD archetype. What do you think? Is CRUD still applicable for these modern use cases? Let us know in the comments below.