Following the fanfare of its introduction in late 2015, the OpenAPI Initiative has now been in existence for six months. As discussed on their blog a great deal of progress has been made towards creating the governance structure that will help the OpenAPI Specification (OAS) move forwards, including a home on GitHub that has been steadily collecting new issues for consideration and possible inclusion in the next version.
One of these (now closed) issues, raised by Darrel Miller discusses whether OAS represents an Open World contract. The Open World school of thought allows individuals to make assumptions safe in the knowledge there is no guarantee of certainty: This allows for statements to be made without those statements implying absolute truth. This is opposed to Closed World assumptions, which asserts that any statement has been proven to be true before being made.
In the context of OAS, an API specification which adheres to an Open World assumption will therefore only describe the API itself and will not necessarily describe all the status codes or behaviors the HTTP server hosting the API might return or exhibit. As a whole, the description therefore describes only what is known and not everything an API will return. Essentially (as suggested by Zdenek Nemec) this means that an OAS API description is a statement of what a client should get when they call an API, and if they get it what it means. The converse Closed World assumption would mean that API descriptions are an absolute declaration of API, with all behaviors described and known to exist.
The main advantage of the Open World approach is fairly obvious: It avoids falling down the constraining rabbit holes that protocols like SOAP led to, instead using an ethos that implies extensibility from the outset and allows for differences in implementation across technologies and transports. The protagonists discussing the GitHub issue clearly favor it, but maintaining this approach across all issues in the backlog will be easier said than done. We’ve taken a look at them in an effort to judge whether the next version really does promise to be an Open World format.
Formal HATEOAS Support
One of highlights of the backlog is almost certainly issue 577, which discusses the possibility of including formal support for hypermedia as the engine of state (HATEOAS). HATEOAS is one of the original principles of REST defined by Fielding and describes a mechanism for passing state to the client by way of hypermedia. HATEOAS could possibly be described as the API description anti-pattern: As the server provides state to the client, it therefore describes itself on the fly, with less impetus to document resources upfront. The GitHub issues itself describes this in terms of a “pathless” construct, removing the tautology of using links in responses but also defining those links in the API description.
Whilst HATEOAS support will undoubtedly please many people in the API community, it’s not clear whether introducing this feature will support an Open World contract. At a practical level, and while RESTafarians may argue otherwise, implementing HATEOAS in an API tends to be largely a matter of taste and resonance with the developer community for a given subject matter rather than “technical correctness”. However, and more importantly from the Open World perspective, the need to explicitly convey state to the client means that the API is largely duty bound to convey an exact and prescriptive version of the truth, as without this approach it risks breaking the client. When describing a HATEOAS API the description should therefore support a prescriptive, single version of the truth in the manner of a Closed World contract.
Without diving into a candidate design in an effort to iterate through the issue, on face value it appears OAS must therefore support a Closed World contract to some extent to correctly support HATEOAS. Whether this can be done and still be consistent with an Open World approach will be largely dependent on how cleverly it is implemented. However, given that HATEOAS is a feature of Fielding’s original definition of REST that is not routinely implemented by API developers, it is likely that OAS could support both Open and Closed World assumptions simultaneously.
Standardized Error Responses
Improvements to error handling and responses are present throughout the OAS backlog. Of particular note is issue 567, which discusses introducing a dictionary of responses in the 400 and 500 range of HTTP return codes that adds extra information in the form of a code (either an integer or a constant) and a message. While any developer would welcome this standardization feature as a labor saving device, regardless of the Open World debate it should tempered with caution — there are many good reasons for being opaque, especially with Unauthorized and Forbidden return codes. Cyber security practitioners would argue that no additional information should be returned with such codes, introducing an interesting dichotomy between security and ease of use.
In terms of OAS as an Open World contract, this issue highlights the crux of the must vs should debate: Extended error handling is great, but to remain consistent with an Open World philosophy it shouldn’t be prescriptive and should only be returned where practical and available. Additional error information should therefore be considered a useful extra and would certainly be welcomed by the majority of the API community. If this feature can be implemented with the requisite flexibility the Open World approach can also be maintained.
There are a couple of issues in the backlog on the subject of endpoint status that warrant discussion in the context of an Open World contract. One that has yet to be marked for the next version is 608, which describes a means to mark an endpoint out of service: Given an API description is essentially a static document this is an interesting concept when taken at face value. However, should this be considered a feature to be included in OAS, the implementation is very likely to incorporate a status endpoint, where the status of the API itself can be gleaned.
Standardizing this mechanism within the OAS specification would of course be helpful, but is probably the tip of the iceberg for the kind of data that could be provided by a status endpoint, including:
- Discovery: Finding the API and description in the first place;
- Capability: A definition of the service level offered, including rate limits, support hours, cost, etc.;
- Subject Matter: What the API is concerned with, e.g. Payments, foreign exchange, news, etc. Such classifications, together with published capabilities would allow APIs to be looked up and utilized on a “best fit” basis.
The spirit of this issue lends itself to OAS being an Open World contract. Going back to the idea of what should be available, this gives the API consumer a much better view of what should exist from a schematic perspective. Conversely, the runtime implication is that this is a Closed World concept because the status endpoint dictates the status of the API and the API consumer is obliged to obey the status endpoint regardless of whether the API is actually available or not. The implementation therefore introduces many practical issues that will need to be carefully considered to ensure they remain consistent with the spirit of an Open World contract.
Issue 433 introduces the concept of adding support for private and hidden endpoints. The rationale for this issue being raised is that an API description is a complete and homogenous definition that can be tailored to specific audiences based on attributes in the document. Clearly this lends itself to a Closed World approach, as it implies everything should be defined in the API description. If an Open World approach prevails, the implementation of this feature needs to ensure that the definition of endpoints, whether public, private, or hidden is not defined as being mandatory.
The question of implementing an Open World vs Closed World contract may seem philosophical in nature, but it has many practical implications for how the OAS continues to evolve. As we’ve shown in the issues we’ve highlighted, it will be difficult to implement features that consistently support an Open World contract. It would seem obvious to the majority of contributors to the debate that an Open World contract gives the most flexibility and greatest ease of use, but this also comes at the risk of not being specific enough. The Closed World approach, on the other hand may start to stifle flexibility but may be easier to code against given its didactic nature.
Ultimately a modicum of common sense from the team stewarding the OAS will apply the correct features, whether they qualify as Open World or not. If common sense does prevail it will allow the specification to continue to evolve and resonate with the developer community with the same degree of success as Swagger.