This document discusses design guidelines for SUSE Studio APIv3.
Contents
Extensibility, scalability, pragmatism.
These are forward-looking statements covering v3 and onward:
- We want the API to be durable in face of time and scale.
- We want to be able to evolve both the interface and implementation, potentially keeping compatibility with old clients.
- We want to afford the same to clients.
- We want the API to cover the whole feature set of SUSE Studio.
- We do not want to close the door to converging the api and web-ui controllers without a very good reason.
- We want the API to be usable with low effort on the part of the client software authors.
- Inexperienced programmers should be able to use the API.
We could keep the current API (Interface, not Implementation)
around indefinitely, extend it with new endpoints, and current
endpoints with new behaviors through Prefer
and content negotiation,
the opinion that this is not worth the effort seems to prevail in the
team.
Generality, readability, coarseness, late binding, interfaces first.
- The web-ui URLs should be meaningful to humans which means preference for natural identifiers.
- The quality of the interface should trump implementation concerns (up to a limit).
- As is the case with all remote services, each use has large overhead both in time and computer resources. It's cheaper to give clients more information than to force them to access the API twice.
- Late binding, or independence of URIs and representations, enables "content negotiation to take place based on characteristics of the request", and "to reference the concept rather than some singular representation of that concept, thus removing the need to change all existing links whenever the representation changes".
APIv3 will use JSON instead of XML.
Transparent versioning of the API would call for custom media types (they cost nothing), and a form of versioning those. I (roman) favor this over other ways to version the API. For an in-depth discussion see Further Reading and REST.
Partial updates (eg. appliance configuration) should use PATCH
.
HTTPbis:
Partial content updates are possible by targeting a separately identified resource with state that overlaps a portion of the larger resource, or by using a different method that has been specifically defined for partial updates (for example, the PATCH method defined in [RFC5789]).
The Expires
header should reflect real-world considerations such
as the build expiration policy.
We should issue status codes in conformance with HTTP and related standards. This is especially important in non-interactive software, where using a wide brush can deprive the client of ability to take the most appropriate action and force a human intervention to disambiguate the situation.
See HTTP Status codes for an in-depth discussion.
APIv2 abuses 400 Bad Request for all kinds of error conditions. This status code is intended for "malformed syntax" situations, where syntax refers to the syntax of the HTTP request, not to application-level semantic problems with an otherwise correct HTTP request. A good chunk of current 400 responses should be 405 Method Not Allowed instead.
Routes exposed by v3 should use natural ids as much as possible.
Routes with two synthetic ids where one id implies the only possible
value of the other necessitate extra code to detect and mitigate
inconsistencies.
What happens with GET /appliances/3/files/12
if the file with id=12
is in fact part of appliance #6?
Only unique and/or stable natural ids can be used.
- appliance names are not unique even within the scope of a single user -> bad
- overlay file paths in an appliance (image) are not stable (can change over time) but they're unique at any moment -> ok
We can keep relying on informal descriptions, or employ a formal format. Informal descriptions tend to be incomplete and ambiguous, formal descriptions do not suffer from ambiguities and would enable testing and validation (both server- and client-side).
I propose describing representations used by the API using JSON Schema v4, which is being prepared for submission to IETF "in early 2013".
Canonical JSON Schema documents are JSON documents.
JSON is great as a serialization format, but all the curly braces
and quotes make my eyes bleed. For this reason, the proposals
under schema/
employ CoffeeScript syntax.
We can easily canonicalize these with a bit of coffee(1)
and
JSON.stringify
.
- http://json-schema.org/latest/json-schema-core.html
- http://json-schema.org/latest/json-schema-validation.html
- HTTP 1.1
- http://tools.ietf.org/html/rfc2616
- HTTPbis
- http://tools.ietf.org/wg/httpbis/
- PATCH method for HTTP
- https://tools.ietf.org/rfc/rfc5789
- Content-Disposition Header in HTTP
- https://tools.ietf.org/html/rfc6266
- HTTP State Management Mechanism (cookies)
- http://tools.ietf.org/html/rfc6265
- Prefer header
- http://datatracker.ietf.org/doc/draft-snell-http-prefer/
- Uniform Resource Identifier (URI): Generic Syntax
- http://tools.ietf.org/html/rfc3986
- URI Template
- http://tools.ietf.org/html/rfc6570
- JSON, application/json
- http://tools.ietf.org/html/rfc4627
- application/json-patch
- http://tools.ietf.org/html/rfc6902
- JSON schema
- http://tools.ietf.org/html/draft-zyp-json-schema-04
- JSON pointer
- http://tools.ietf.org/html/rfc6901
- Link relations
- http://datatracker.ietf.org/doc/draft-snell-additional-link-relations/
- XML media types (foo/bar+xml)
- http://datatracker.ietf.org/doc/draft-ietf-appsawg-xml-mediatypes/
- On Linking Alternative Representations To Enable Discovery And Publishing
- http://www.w3.org/2001/tag/doc/alternatives-discovery.html
- REST
- http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
- http://www.subbu.org/blog/2011/03/performance-of-restful-apps
- http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http
- http://developer.github.com/
- http://www.infoq.com/news/2010/03/rest-versioning-strategies
- http://www.subbu.org/blog/2007/12/vary-header-for-restful-applications
- http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
- http://www.w3.org/DesignIssues/Axioms.html
[Top]