API Evangelist and Storyteller: Checking in.

Throughout most of my career as a Software Engineer, one constant trend I have seen has been the increasing need to provide context to technical solutions and how to adapt a business requirement to technical limitations.  Sometimes the tool was not mature enough to accomplish what was wanted, and a bargain was struck on what was feasible in the short term using the tools on hand.  Other times the tools might have existed, but the solution was prohibitively costly in time, money or both.  There were countless other causes as well, but the crux of the issue was business was bending towards the will of technology, because computers don’t work the way humans do.  It was becoming my job to explain, convince, cajole, and bargain an adequate solution to a requirement instead of working towards the right solution.

History has shown tools which have provided even a small portion of the right solution, have enjoyed vast success by allowing the technical problem to be circumvented to deal with the business requirement.  WordPress, the very software this blog is running on is testament to the wild success a human tool can achieve when released into the wild.  Salesforce.com has enjoyed massive growth and penetration, despite being largely disliked by the technical community because it satisfies real business needs in a more human way.  As a developer who held a salesforce certification as a requirement of employment for a consulting company, I know how painful the experience can be for developers, but I was also able to see how well loved the platform was by users who leveraged its power with great success.

It is absolutely vital to take the next step in APIs that we don’t lose sight of the human perspective.  We must internalize the lessons of past success and push towards a human centric API space.  We are poised to fundamentally alter the course of human history.  Soon we will be able to build distributed systems upon other distributed systems, laying the groundwork functional composability on a unfathomable scale.  All of our success hinges on how many people can participate in building these new systems, and involve the most people we need to make our APIs as human as possible.

Every realized dream started with a crazy vision, beyond the realm of possibility and slowly materialized.  My vision is to humanize the API space, open the floodgates to the population, and allow everyone to participate.  This is where I am pushing, and with my guidelines for hypermedia web APIs, this is just the beginning.  The story I am going to tell is a story of inclusion, and I intend to include as many as possible.

 

Hypermedia APIs: Don’t version anything.

In my last post I, perhaps controversially, set the constraint that an API should not couple itself or document tightly to URI paths and patterns.  This comes as a stark contrast to many of the popular trends within the API space, but the long term benefits to the service over its life far outweigh the complexity and cost of implementation.  In this post I would like to discuss an additional constraint which is in part corollary to the last guideline: do not version anything at all in the service.

I will first start out by addressing the elephant in the room, this guideline also comes at a stark contrast to popular trends in the API space, as well as the established trend from some of the largest Silicon Valley technology companies.  These two guidelines add a great deal of complexity to initial API design and architecture for public APIs.  Most of these leading organizations are driven by concerns with speed to market, and therefor do not allow themselves the appropriate design time before beginning to build applications, or are far more concerned with a larger audience’s familiarity with a particular design strategy than creating a better API design.  These concerns are certainly important from a business perspective, however it is often incorrectly presented as a technical limitation and guideline, when in fact it is driven almost entirely by business motivations.

If the rush for faster minimum viable products is driven by a business concern, what are the technical benefits associated with a hypermedia web API style?  The often cited axiom in the hypermedia web API space is WWBD, or what would browser do?  This is particularly apt given HTML is probably the most familiar hypermedia format to any user of the internet regardless of their awareness of this fact.  Netflix and other continuous delivery champions are famous for deploying code to production hundreds of times per day, however as a user of their services you are never aware of any change in the service platform.  The only way this can be done is if you are never aware or tightly coupled to any type of versioning within the service interface.  Your browser never knows, or is concerned in any way with, the version of the Netflix software it is querying.  This point perfectly addresses the style of CRUD api which includes a version number within its URI pattern, but does not cover all ways to version.

The other shortcut often taken during API design is to apply a version to the MIME type itself, and has been demonstrated to be beneficial in the very near term.  This solution does manage the version disconnect at the service layer, but leaves un-patched clients unable to fully consume the service until new client versions can be distributed.  Even though this strategy is one we are very familiar with as API service integrators, it is extremely consumer hostile as all the service version management responsibility have been dumped on the consumer.  Worse still this type of versioning is unique to each integration, greatly increasing the difficulty of a service which aggregates functionality from multiple APIs to create some or all of its responses.  This strategy will solve your concerns for versioning, but it comes at a hefty cost to the API’s consumers, and if there is completion in the space, this poor experience could result in the loss of a client or consumer.

Both of these reasons taken in isolation or together should be enough to convince a reasonable designer of the importance of removing all versioning from their API.  However, there is a more fundamental reason to exclude versioning entirely and it goes back to the very first guideline.  Versioning is a solved problem within the HTTP application protocol.  I previously discussed the ETag strategy to perform cache control, but this is nothing more than a more specific form of representation versioning.  If part of the structure or field of a message representation changes between versions, normal validation processing should handle this change, and the client can update its local representation and model cache for the service from the service itself.  If a historical representation of a resource is required for audit or some other need, the memento header exists to handle requesting a resource and representation as it existed at a certain point in time.

Clearly this is not be the simplest solution, however it is a far more useful and standard way to version the resources and messages of an API.  By adhering to the standard way to perform this action, a sophisticated http consumer can always know the status of any data it holds locally and remain unconcerned about the version of the service running.  Furthermore, this sophisticated client can be used to consume other APIs which follow these guidelines, with little or no additional integration effort.

Hypermedia APIs: Stop worrying about your URI patterns.

In my last post I discussed the need to carefully construct your resource and message representations in order to increase the flexibility of your design over time.  Great care needs to be taken to avoid many of the pitfalls which can befall your design with insufficient attention.  A considerable portion of your time as a designer of a hypermedia web api should be spent designing your representations.  This post may then come as a small relief as I would like to talk about removing an entire concern from your API designer mind to free up time for the previous discussion; the URI pattern.

For the most part the guidelines previous to this one could largely be followed in a crud or hypermedia web api and you could expect improved results regardless.  This trend ends now, and depending on your attachment to the tools or strategies I’m about to reference, this might upset you.  Immediately stop spending any design energy on your URI pattern philosophy, rotation, choice, or strategy as you simply won’t need it.

The documentation and standardization around a hierarchical URI pattern generally wastes an inordinate amount of designer and developer time before some semblance of a workable design reaches the hands of a capable developer.  In order to help speed up this process of wasting time, many solutions like OAS (Swagger), Apiary.io, RAML, etc.. have been created to cut out chunks of effort to disprove a design.  This statement isn’t to be taken out of the appropriate context, as previously stated hypermedia web api’s are not right for every situation.  There are many viable situations where the solutions they offer are the correct tool for the job.  However, scaling those solutions to a large domain size with limited or no control over consumer code, and desiring high utilization endurance over time, it becomes an exceptionally difficult task to accomplish.  I would argue the longer you desire the API to run unmodified, the closer to effectively impossible the task becomes, and the point where this occurred wouldn’t be anywhere near as far in the future as you might believe.

Overloading the URI structure to contain semantic information places a tremendous amount of pressure on the designer to allow enough gap for future growth and needs within the hierarchy.  It also places a huge burden on the consumer of the service to know a lot of information about your service before being able to fully utilize it.  Kin Lane (“the api evangelist”) on the recent Api Academy podcast described this as human targeted documentation and tooling.  Meaning that while tooling can help set up some of the boilerplate code, the responsibility for tying things together is left for the human developer.

When utilizing a hypermedia web api which matches the preceding four guidelines, the URI pattern for resources is entirely irrelevant as the actual URIs are completely opaque to a consumer of the API.  With the root resource representation name of ‘user’, and assuming complete home document, and vocabulary definitions, the actual URI for the resource is meaningless.

With the same conditions stated above, the user resource being under ‘/uusdfskd231232/’ and the hypermedia client would have no difficulty whatsoever discovering the resource, nor surfacing the context to a human consumer.  The same is obviously not true of the human integration developer, whom must consult some external documentation to identify the change.  As a consequence, moving the resource to another URI would simply be a matter of making some small modifications to the profile, and this would be entirely unrecognized by the clients.  It is important to not, I do not advocate obscuring the URLs of the resource unless your design absolutely calls for it, where possible an intelligible and human friendly format should be used but it should not become an obstacle of any note.

By utilizing the representations painstakingly created following the previous guideline, your service doesn’t need to worry about creating the perfect hierarchy structure for your API, it just doesn’t.

Hypermedia APIs: Flatten those resources!

In my previous post, I discussed the need to present a Home document.  Through its presentation your API design is able to be flexible and adaptive over time, while still being easy for clients to consume and discover functionality.  In this post, I want to discuss the design and handling of the resource representations themselves.

In traditional Object Oriented design, the principles of encapsulation encourage a class designer to hierarchically wrap atomic representations in increasingly more complex representations to compose a complete model which is self-sufficient.  In the OO world, this will enhance the flexibility of the implementation as it adheres to the information hiding principle.  A class implementer is free to make any changes to the encapsulated code, and any execution of the code is bound to the interface provided by the object, and is not impacted by internal design changes.  The following json serialization might represent a good OO model for a User class, it has been truncated for brevity.

{"user":{
  "address":{
    "street":"742 Evergreen Terrace",
    "city":"Springfield",
    "state":"?",
    "zip":"doh"
  },
  "userProfile":{
    "name":{
      "first":"Homer",
      "last":"Simpson"
    },
    "accountCredentials":{
      "userName":"homers",
      "email":"homers@example.com"
    }
  }
}}

When designing the representations for resources and messages, a designer needs to abandon this long standing practice and focus on creating the least complex but semantically complete representation possible.  The value of the atomic resource and message design is the enhanced flexibility gained by the API designer to bind related resources via relationships which allows mutability of the interface over time.  This guideline can clearly be taken to an unreasonable extreme, therefor it is important to always keep an understanding of the caveat ‘semantically complete’ in mind as there will be occasions when a representation is not entirely flat.  When successfully completed, a resource model should look to the OO designer eye to be remarkably flat and in desperate need of factoring.  For example, the representation of the above OO model could be 3 separate resources with the following representations.

{
  "user": {
    "userName": "homers",
    "email": "homers@example.com"
  }
}
{
  "userProfile": {
    "name": {
      "first": "Homer",
      "last": "Simpson"
    }
  }
}
{
  "address": {
    "street": "742 Evergreen Terrace",
    "city": "Springfield",
    "state": "?",
    "zip": "doh"
  }
}

If this was the end of the process, the resulting implementation of our API design could be a disastrous and unworkable torrent of traffic for even the most minute of tasks at scale.  In order to aggregate the same collection information in a resource representation, the design must compose the related resources through embedding, transcluding, or link relation.  Through these means, and fine grained use of cache-control, a hypermedia web api can have surprisingly low overhead while still retaining the flexibility and robust nature we seek.

At this point in the discussion of these 11 guidelines for designing a hypermedia web api the reader might have noticed the heavily referential nature towards previous guidelines.  Each guideline addresses a particular constraint or sets of constraints which a designer might be inclined bypass.  However, each step is a crucial building block on the path towards a fully functional hypermedia web api.  In order to achieve the benefits of a flexible, robust, and enduring API we must focus on designing the API right the first time, and allowing it to grow as resource and affordance understanding changes.

Hypermedia APIs: Present a Home document.

In my last post, I discussed the need to document resources through vocabularies.  By leveraging vocabularies, you can provide separate documents which describe the APIs resource representations and behaviors, however you aren’t quite yet capable of presenting a uniform interface.  In this post I’ll go through the final piece we need in order to present a uniform interface to facilitate a completely discoverable hypermedia web api; a Home document.

There are a few names which have been floated to describe this resource, root document, directory, index, and home document to name a few.  The name isn’t terribly important, however the important part is to present the single valid entry point from which all clients MUST discover your APIs resources and functionality.  The Home Document specification is a great example of one method for providing the discoverability of all resources and meta-data for your service.  There are many added functionalities, but the root of the document is a list of root resources and meta-data through which a client can begin to interact and discover your API.

Another very important role of the home document is to provide a starting point to expose multiple dimensions of negotiation the service supports.  These dimensions would include the media type, goals, and even vocabularies in addition to more standard protocol negotiation elements.

By utilizing the home document, a hypermedia web api can present the uniform interface it needs to provide robust flexibility and discoverability for consumers of all types.