An Origami web service is a hosted service, offered as a URL endpoint that delivers content or data services. See our services documentation page for example services.
All services must adhere to the FT’s engineering checklist.
Node.js and Origami Service, which extends Express, should be used as a starting point to help meet service requirements.
All of our services should be named in the pattern “Origami <name> Service”, e.g. Origami Build Service, Origami Image Service. Services may make exceptions to this naming structure in circumstances where “Service” doesn’t effectively describe what the application does, e.g. with Origami Bower Registry. If you think that a different name might be required then discuss with the team.
Names may be slugified where needed (this is a lower case, hyphenated version of the name, e.g. origami-build-service, origami-image-service). For instance, a slugified name must be used for the service’s:
In addition to the slugified service name, Heroku applications must be suffixed with an environment identifier for non-production applications, and a region identifier for production applications. E.g. origami-build-service-qa, origami-build-service-eu.
Origami web services should exist on a path under
ft.com if users would benefit from HTTP2 in this case. If this is not possible for some reason then a subdomain must be used.
When using a path, it should be
/__origami/service/<short-name>. The short name in this case is the slugified service name with origami- and -service removed, E.g.
When using a subdomain, it should be
<short-name>.ft.com. The short name in this case is the slugified service name with -service removed, E.g.
Services must also include a mandatory version number for all API endpoints. This must not expose minor version changes and must be prefixed with a
v. The only exception to this rule is when the service is replicating a third-party API. E.g. a Bower registry. Good examples include:
The api endpoint which follows the service version must be RESTful, i.e. use the most appropriate HTTP verb and URLs that semantically describe the resource to be acted upon.
The service’s root path
/ must redirect to the latest API version.
|Service name||Repository||Heroku app||URL|
|Origami Tweet Service||origami-tweet-service||origami-tweet-service-eu||
|Origami Most Popular Service||origami-most-popular-service||origami-most-popular-service-eu||
Services must require API endpoint requests to contain a
source query string parameter to identify the requesting application, unless the service is replicating a third-party API. E.g. a Bower registry. If the
source query parameter is missing, the service must return a
400 Bad Request response status code.
Requests to non-API endpoints such as the root path or
/__about should not require the source parameter.
If you are building a Node.js/Express service, we provide an Express middleware to check source parameters.
Services must include an explicit
Cache-Control header in all HTTP responses that have a
Services must serve permissive CORS response headers to allow the endpoints to be consumed in-browser from any origin (though consuming in-browser is discouraged). If CORS is supported, the service must support all potential pre-flight requests that would be required in the case of requests for HTTP methods other than GET.
When an error occurs that prevents the service from returning the output requested, the HTTP response code must be in the
In the case of breaking changes, a service must:
To decommission a previous version you must:
sourceparameter and proactively notify their owners.
410 Gone, a static copy of the last content to be generated, or redirect to the new version if the API is compatible.
Services must serve content on the bare versioned endpoints (e.g.
/v1/) that documents the service, or links to documentation under a
documentation path (e.g.
/v1/documentation/). Documentation should use the o-layout component for formatting and layout.
Services must use the querystring parameter
callback if JSONP is supported. JSONP support is, however, not required.