API Guidelines
If you have never used an API yourself, you shouldn’t be building one
High-level architecture
First of all, a check-list:
API’s should be
- Web Based
- accessible through a browser
URL - URL encoding/decoding of strings
- accessible through a browser
- Use open data formats and syntaxes
ISO 8601dates- UNIX timestamps
XML&JSONdatatypes supportedUTF-8encoding
- RESTful & Stateless
- correct usage of URL’s vs query strings
- URL’s of endpoints should be totally self-describing (resource based)
- no cookies or state parameters / headers
- correctly use
HTTPresponse codes - whatever your API returns for an URL at deploy time, will return the same result forever
- Provide utility functions for system information
- like an alive checker
- status information
- Intuitive to develop with
- you shouldn’t need to read documentation to understand what an endpoint does
- return all necessary and related information to a resource
- have link attributes to send you to related resources
- Responsive
- resources that take a long time to respond are wrong
- implement defensively - your system should behave properly if a dependency fails
- dependencies should not bring your entire API down (like your alive function should still work)
- expect everything to fail
- do not rely on other processes
- Expose all aspects of your system
- there is no point only making your system partially accessible
- limiting your API scope effectively means you are creating a new system / interface to a system, not exposing the system itself
Façade Architecture
The façade architecture means you spend more time focusing on exposing your system functionality and URL design than all the boring API functional stuff. Your facade is proxied through another layer of software, a gateway, that handles authentication, data format translation, caching, flow-control, load balancing etc.
A good explanation of the façade architecture can be found on the Apigee blog.
We have an internal API gateway called flo that anyone in Universal is free to put their facade behind and help contribute to.
Development Strategy & Versioning
Planning on how your API will evolve is important to consider prior to construction. Once your API is live you cannot change it - your declared endpoints are an agreed contract between other developers and your system that precisely describes what your system does. You can’t just change things willy nilly.
Your URL should indicate the version of the API being referenced. All URL requests should be rooted at this (so in the diagram below, version 0 would be <host>/v0/<your endpoints>)
API Design
By adopting a test-driven approach to your endpoint design you can ensure any changes you do make to your API do not break. If your endpoint requires extensive documentation to understand it, you need to re-design your endpoint so it doesn’t. You need to enforce the correct usage of the API to your users. If you make it complicated your users will a) do something wrong b) misinterpret the results or c) not use it.
Design Process
The following iterative flow will help you design your API and demonstrate when to change and deploy a new version.
Basically, if any change you make breaks your tests (no matter what your tests are), then you deploy a new version at a new root URL.
Versioning
Versioning of your API should follow the standard semantic method.
Statistics & Reporting
Your façade should log operations that happen against it independently from your application and a method of reviewing in real-time. The logging should be non-blocking (nothing should get in the way of giving a fast response time). You should log at a minimum:
- start-up / shut-down
- start of request (including the
HTTPmethod and the endpoint URL) - the response (and the
HTTPresponse code) - internal errors
We recommend using statsd for event reporting and graphite for monitoring.
Testing
The testing of your façade is independent of testing of the application you are exposing. This is not to say you can use your API as a method of testing your application (indeed this is an excellent idea), but the tests of the API / façade itself need to be purely for and unto itself.
Your tests should reflect exactly the requests you are expecting to receive and the responses you intend to give. Your tests should cover everything that is to be included in your response. Effectively your test suite becomes a contract to describe exactly how your API should behave. If any code changes will break your tests, you need to deploy a new version.
The following should be tested for each endpoint
- HTTP
- a response actually gets served
- the response
status code - the response
content-type cache-control- expected header behaviour
- Body
- is of the type you expect (
JSONetc) - every element you expect exists and is of the right type
- is of the type you expect (
- Security / obvious issues
- strings are not too long
- numbers do not over/underflow or are in acceptable ranges
- URL encoding works
- SQL injection attacks on strings
These tests should be run against your façade and through the gateway separately. By writing your tests using a test suite (like mocha) you can use your tests for load-balancing. Ideally you should run your tests every 24 hours and any alerts reported to you.
Documentation
Writing API documentation is an art. There are many styles and forms of API documentation to choose from. Remember: if your endpoint cannot be described by its URL you need to re-build it. We use the following as a bare-bones:
A list of every endpoint
Developers don’t have time to hunt through manuals or code. Give a simple list of every endpoint exposed, grouped together by function
A detailed description of every endpoint
In addition to a list you should have another document that details information about each endpoint
Accepted Parameters
For every endpoint list the required parameters / headers it takes, and what are the valid values
Give Examples
Again for every endpoint give an example of a request that will work (using all the parameters you describe if possible) and the response of that request.
Working examples
Give 3 or 4 examples / walk-through’s of what you can do with the API that solve some key problems so your developers can get off the ground quickly.
Note: if you need any more documentation than that (plus some bits about general stuff like API keys etc), your endpoints are wrong and need re-designing.
flo
flo is an API gateway developed by the New Technology team at Universal.
Features
- Authentication (API keys) and we are looking at forwarding Active Directory headers, OAuth etc
- Client rate limiting
- Endpoint control (allow/disallow application api keys from select endpoints)
- Can sit in front of multiple API’s
HTTPSconnectionsCSRFattack protection- Compression
- Statistics reporting
- Transformations (currently
JSONtoJSONP, looking atXMLbut that’s a bit trickier) - Caching, including honouring the underlying API’s caching instructions in
HTTPresponses - Concurrency settings (so the underlying API is not hit a gazillion times when it is busy, requests are queued to a queue size)
- A whole bunch of intelligence around the above - so things like similar URL’s not being let through, if lots of requests to the same response come simultaneously only 1 goes through etc
- Admin control panel for all the above, with API access to it
- Can even host applications inside of it
- Scales vertically and horizontally
Useful resources
- Google Developer Guides
- Apigee
- O’Reilly RESTful Web Services


















