Spore (Specifications to a Portable REST Environment) Description Implementation
Spore is a specification for describing HTTP APIs which happen to suffice some constraints laid out by the REST architectural style. It can be parsed and used automatically by client implementations to communicate with the described API.
This document describes what features are required in a Spore client implementation.
An API is the interface to an application that can exchange data with client applications over HTTP/HTTPS. It presents one or more method endpoints which accept HTTP requests with varying headers, parameters and body content to perform specific operations.
- Client implementation
A Client implementation is a library targeting a specific system or language. It can use Descriptions files to create programmatic interfaces usable in applications.
- Description file
A Description file is a file in JSON format describing an API (see specification). It can directly be used by a Client implementation to create a programmatic interface in the target system.
A Middleware is Spore component that is added to the workflow of the Client implementation to modify the Requests and responses sent and received. It can also shortcut the rest of the workflow if needed. It can be thought of as a plugin to extend Spore.
A Request is a data structure that contains standardized data and metadata inspired by the CGI specification. It is used by the Client implementation to create the HTTP request that will be sent to the API.
A Response is a data structure that contains standardized data and metadata inspired by the CGI specification. It is created from the HTTP response sent by the API and is used after being processed by the Middlewares to create the structure returned to the user.
A Client implementation MUST provide a function or method (e.g. new_from_spec) to generate the specific API methods in the target system by reading the JSON string from a Description file (and optionally directly from the file itself).
A Client implementation MUST also provide a method to enable or disable spore middlewares at run-time. The order in which the middlewares are enabled is the order in which the request will go through each middleware, and the inverse order in which the response will go through each optional middleware post-processing callback. It MUST also have a method to selectively enable a middleware or not for each method according to the method properties in the specification.
If middlewares I<A>, I<B> and I<C> were enabled in this order, then the processing order will be: I<A>, I<B>, I<C> ... make request ... I<C>, I<B>, I<A>
Each middleware MUST accept arbitrary initialization parameters. It MUST provide a way to only conditionally use a middleware (e.g. enable_if). It MUST also provide a function to which the request environment or an object containing it will be passed. The function can have 3 types of return values:
Control is passed to the next middleware in the chain.
- A callback
Control is passed to the next middleware in the chain. The callback is stored and will be passed the response later on after the request is made.
- A response
The response is directly passed to the first stored callback in the chain. No further middlewares are used and no request is sent. Useful if a middleware needs to short-circuit the remaining of the chain, for testing or caching purpose for example.
The request environment MUST be a data structure that includes CGI-like headers, as detailed below. Each middleware is free to modify the environment. The environment MUST include these keys (adopted from PEP 333, Rack, PSGI and JSGI) except when they would normally be empty. The environment is used by the Client implementation to build the final HTTP request that will be sent to the API.
REQUEST_METHOD: The HTTP request method, such as "GET" or "POST". This MUST NOT be an empty string, and so is always required.
SCRIPT_NAME: The initial portion of the base URL's path, minus the scheme and domain name. This tells the client what is the API virtual "location". This may be an empty string if the method corresponds to the server's root URI.
If this key is not empty, it MUST start with a forward slash (
PATH_INFO: The remainder of the request URL's path, designating the virtual "location" of the request's target within the API. This may be an empty string if the request URL targets the application root and does not have a trailing slash. It still contains the placeholders which will be interpolated later with the parameters.
If this key is not empty, it MUST start with a forward slash (
REQUEST_URI: The undecoded, raw request URL line. It is the raw URI path and query part that appears in the HTTP
GET /... HTTP/1.xline and doesn't contain URI scheme and host names. It still contains the placeholders which will be interpolated later with the parameters.
SERVER_PORT: When combined with
PATH_INFO, these keys can be used to complete the URL. Note, however, that
HTTP_HOST, if present, should be used in preference to
SERVER_NAMEfor reconstructing the request URL.
SERVER_PORTMUST NOT be empty strings, and are always required.
QUERY_STRING: The portion of the request URL that follows the
?, if any. May be empty, but is always required. It will always be empty before the request is actually made and sent.
spore.payload: The actual content body of the call. Modified in place by the middlewares.
spore.params: A list of key/value pairs. These will be interpolated in the URL with the placeholders when the request is made. The rest of them will be used in the
QUERY_STRINGpart of the URI and the payload key will define the actual content. MAY be empty but MUST always be present.
spore.redirections: An ordered list of all the intermediate URL that were tried by the fetcher.
spore.scheme: The scheme of the URL.
spore.expected_status: The list of expected HTTP statuses for this request in the response.
- Initial version.
Some parts of this specification are adopted from the following specifications.
- PSGI Specification PSGI
- PEP333 Python Web Server Gateway Interface http://www.python.org/dev/peps/pep-0333
- Rack http://rack.rubyforge.org/doc/SPEC.html
- JSGI Specification http://jackjs.org/jsgi-spec.html
I'd like to thank authors of these great documents.
Copyright XXX, 2010.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.