API Standards
In OPG we primarily follow the CDDO API technical and data standards when building new APIs. However, as these are designed to support all Government departments, they sometimes do not go into enough detail.
The OPG API Standards provide additional guidance for designing and building APIs. They intend to make the API build process easier by answering common questions about what best practices are.
You should adopt these standards if there is no reason not to, but you may break any of them if you have a contradicting need.
Design
- Use JSON for request and response bodies
- Use lowerCamelCase for keys
- Prefer flat structure, we don’t have a standard response format and should keep things as minimal as possible (e.g. don’t use JSON:API, or have all responses like
{"data": ...}
) Use RFC3339 to format dates
Examples of RFC3339 formatted dates:
- 2023-06-16
- 2023-06-16T09:04:38Z
- 09:04:46Z
Resource naming
As the CDDO API standards outline, we use a REST API architectural style. Additionally:
- Resources are represented by nouns. Resource names can be “real” nouns or abstract collections e.g.
/users
or/user-management
- A resource can be a singleton or a collection. Collections are pluralised and singletons are addressed by ID
/users
is a collection/users/1
is the singleton in that collection
- Resources are hierarchical, and resources may contain other resources. These relationships are denoted with forward slashes. e.g.
/teams/1/users
- A URI addresses the resource, not the action. HTTP methods should be used to indicate the action being performed. e.g.
HTTP POST /users
, not/users/create
- Use query parameters to filter a resource collection instead of creating a new URI. e.g.
/users?role=admin
- Use hyphens to improve readability. Avoid underscores and other separators. e.g.
/device-management/os-versions
- Use lower case only. Case sensitivity is dependent on the browser, server, and host OS, so mixed-case should be avoided.
- Do not use file extensions in URIs. If this information needs to be communicated, use the
Content-Type
header.
Sometimes it is impractical to follow a REST style absolutely, e.g. executing actions via an API call. In these instances, you must provide adequate documentation so consumers are aware it is not addressing a resource.
Versioning
- Avoid versioning until there is a definite requirement
- Use semantic versioning to provide meaning and context to version changes
- Encode version in the header via Content Negotiation (
Accept
header) e.g.Accept: application/vnd.opg-data.v1+json
- Prefer additive changes over destructive ones
- Provide clear documentation
- Provide concrete deadlines to consumers when removing part of an API
- Ensure network traffic is well-monitored to detect abuse
For further information, see the OPG Data versioning strategy
Documentation
- Use the OpenAPI Specification for documenting APIs
- Store your OpenAPI Specification file in the repo at
/docs/openapi/openapi.yml
Authentication
- Use JSON Web Tokens (JWTs) to authenticate requests between OPG services
- Each JWT must contain the following claims:
- sub: Either an identifier of the user making the request (e.g. email address) or a service identifier if not user is involved
- iat: The timestamp of when the token was issued
- exp: The timestamp of when the token will expire
- iss: The service that issued the token
- APIs must validate “exp”, “iat” and “iss” claims, and the “nbf” claim if provided
- Each JWT must contain the following claims:
- Where APIs only have consumers inside OPG, use infrastructure tools (e.g. AWS IAM) to restrict access to those services
Performance
- We have no explicit departmental performance requirements, but you should discuss as a team if you can set any for yourselves.
- Monitor realtime performance of your production services with the tools provided by AWS, such as CloudWatch Metrics and X-Ray
- Consider alternative techniques for slow-running transactions such as using asynchronous request/response patterns, or queuing onerous processes to execute after the response has been sent