API First is the approach of consciously designing APIs instead of treating them as by-products of implementation work. It is the same mindset that is popular for human-facing Web sites: Design these consciously, and they will be much more likely to support users in achieving their goals, leading to a better User Experience (UX) and thus a more successful Web presence. Observe and listen to your users when it comes to improving the site.
If an API First strategy has the goal of using hypermedia, then it should follow the same general trajectory as UI sitemaps: Design an interconnected set of API resources with clear ideas and support of why and how API consumers will follow certain paths. This is what reflects REST's hypermedia constraint, where the connectedness of resources is key, and everything is driven from that fundamental design aspect. For added robustness, because well-designed hypermedia is extensible, this design can always be updated with additional navigational paths and/or features if necessary.
Readers may note how this is remarkably different from today's mainstream API documentation and design approaches, which are focused on just listing resources as a disconnected set, without looking at their connectedness as a key part of the API and resource design process. This "disconnected" approach to APIs is a close reflection of the (badly named) Google XML sitemap format, which is useful for crawlers, but does not consider goal-driven interactions. In both cases, the focus is just on the resources, and as a result ignores their connectedness. This means missing a key design aspect, if the goal is to use REST's hypermedia constraint as one of the important aspects of API design.
"Design depends largely on constraints" is a popular quote by Charles Eames, which acknowledges that having and honoring constraints is one of the driving forces of any kind of design. For hypermedia APIs, the connectedness is one of the key aspects of design, requiring API designers to envision and support the same kind of "user journey" that UI Web designers focus on for Web sites. API UX is gaining momentum in the API Economy, where APIs may not just compete by features, but also by how easily and robustly they can be used.
This post describes the "API Map Design" part of API maps, going through a sequence of simple steps that will help you to start designing and implementing an API that is the result of a conscious design process, and supports hypermedia as one of the foundations of its design.
As an explanation, analogous steps of a Web site design process are described, so that it easier to follow the sequence of design steps, and how they compare to the more established practice of Web site design using sitemaps.
Resource Inventory
A necessary first step is to identify core resources that an API is supposed to expose. These are usually the core resources of the domain that the API is designed for. Depending on your preferred modeling method, these resources may have different classifications. In Domain-Driven Design (DDD), this starting set of API resources would consist of those artifacts that DDD refers to as an entity, an aggregate, or a service.
A resource inventory serves as a starting point for an API map. It puts the most important resources on the drawing board as a starting point, which are the ones that are supposed to be the core resources around which client interactions will occur. Imagine a customer management service, for which core resources may be individual customers, customer classifications (think frequent flyer status tiers), and services for finding and analyzing customer data. These are the key resources users care about, so most control flows will use at least one of them.
Resource Sitemap
Using the resource inventory, first navigational paths along them are designed, possibly resulting in more detailed and specialized resources that are added to the sitemap. Often these may be intermediate or secondary resources that provide services that add value to the basic set of resources identified in the previous step. For example, for search services instead of just having a simple search form resulting in collection and individual result resources, there may be additional resources for more advanced search features, such as faceted search or other drill-down features.
A first and valuable step when designing and building a Web site is to design a minimum viable product, and then using this as a foundation for a first implementation and further design iterations. This not only makes it possible to get valuable user feedback as quickly as possible, it also makes sure that as little time as possible is spent before the first usable and used release. Many Web sites have started this way and were able to evolve quickly based on real user feedback. The main constraint to allow this kind of evolution is to make sure that the design is robustly extensible, so that the service can evolve without versioning.
Connecting Resources
With the resource inventory and the resource sitemap in place, the connections now need to be cleanly designed so that they can serve as clear input to the resource representation design. In order to support stateless interactions, one important aspect is to keep in mind that each and every interaction needs to be self-contained and self-descriptive: All information required by the target resource to support the interaction needs to be provided as part of the interaction with it. This constraint makes it possible for additional navigational paths to be added later on, without the need to change the interactions along existing ones.
Using the hypermedia constraint this step essentially boils down to looking at each resource, and deciding which other resources/services should be discoverable from it in just one step. In REST, clients are driven by their goals and by making choices along the navigational path that they are choosing, but they never have a "horizon" that goes further than just the next set of linked resources. For each of those linked resources, the link must identify which interaction it is that this particular link supports, and it also must be self-describing so that the client knows how to follow the link.
Returning to the customer management example mentioned earlier, services for creating new customers need all the information required to create a customer as part of that request. How exactly the interactions will look like is the next step of the design process, but before proceedings to that one it should be clear which information is necessary for those interactions.
Designing Interactions
Now that in the previous steps the resources have been connected, and it has been identified which kind of information is necessary for the interactions along those connections, the question is how exactly these interactions are designed. As one important part of REST design, it is necessary for each interaction to determine whether it is safe or idempotent. This is necessary so that intermediaries and clients know how to handle requests, which on the one hand allows optimizations such as caching, and on the other hand allows clients to better deal with failures.
Part of the design process is to decide which exiting concepts to reuse. There is a large number of existing design patterns of Web concepts (webconcepts.info
is a growing collection of the standardized ones), and it is likely that at least some of these can be reused. This will lead to a smaller design effort on the service provider side, and will make it easier for service users to recognize and use well-known mechanisms.
For many aspects it also is helpful to consistently use certain design patterns. For example, when it comes to encoding parameters that are necessary in requests, available options are using URI Templates or instead using a representation that is sent in the request body. Which one to use in part is a question of preference, but also is based on additional constraints such as data size, and the used HTTP methods.
By consistently using existing standards and design patterns, services can be easier to use for users. For example, by inferring user location from hints such as browser settings, sites can make educated guesses about user language and timezone, reducing the need for manual adjustments.
Designing for Change
The above steps are sufficient to design and implement an initial API map. However, like Web sites, services evolve, and thus a usual feedback API providers get is something along the line of "I would like to do something and the API does not make that easy for me." This might either mean that a feature is missing, or that navigational paths are missing that would make it easier for developers to use the API. In both cases, open and extensible designs help with allowing a service to evolve, without disrupting existing users.
The details of "Patterns for Robust Extensibility" are not described here. From the API map perspective, they boil down to two major principles: (1) The representation design and associated processing model must be open so that new links can be added without disrupting existing clients. (2) Service evolution is monotonic, meaning that existing features or links are never removed (unless they were optional by design, in which case removing them is a monotonic change).
In order to make sure that clients actually follow the expectations, future-proofing REST clients through a test version of the service (or even doing this in production such as Amazon's Chaos Monkey) is a good idea, in particular when it comes to proper implementation of the processing model of extensible types.
Web sites evolve by adding new features, which often show up as new navigational options along existing navigational paths. Robust evolution from the API perspective means that new links can show up, and existing users will not get confused by them since a rule of the site is that new links can show up and can be safely ignored. However, if a link that was guaranteed to show up previously suddenly stops appearing, then users depending on that link would be disrupted and could no longer use the site as they used to.
Finishing Touches
This process of using an API map for designing and evolving an hypermedia API will create an interlinked set of resources that API users can conveniently and safely navigate. This final section proposes some finishing touches that may help to make the API experience even better. All these options are based on existing (or evolving) standards, and thus do not need much design effort. The main question is if any of these convenience functions is considered to be worth the implementation effort to support them.
Problem Reports: HTTP has a rather simple way of signaling problems, which is through status codes. Often, it may be useful to be a bit more specific when it comes to indicating what a problem is all about, and "Problem Details for HTTP APIs" specified in RFC 7807 are one way of doing this. They are the equivalent of informative error pages on Web sites that are more helpful than just saying "something went wrong."
Home Documents: In the same way as Web sites often provide "landing pages" that provide entry points for a site's control flows, the same can be done by using "home documents" (in JSON or XML) for an API. A home document is a good place to serve as a collection of most helpful links for a site/API as well, including not only links to control flows, but other helpful resources such as status pages and documentation as well.
API Documentation: Making API documentation discoverable helps to make services easier to use. Depending on the documentation approach taken, some documentation is more machine/tooling-oriented, while other is more targeted at human readers. "Link Relation Types for Web Services" define link relations for both kinds of documentation. In many cases, it may seem a bit too noisy to add these links to all API resources, so they simply can be added to the home resource, which in turn can be made discoverable using a
home
link.
Comments
You can follow this conversation by subscribing to the comment feed for this post.