1.2.3. API design principles

This section assumes that API principles defined in Part A: API concepts and managment 2022 of these guidelines have already been read.

1.2.3.1 Future-focused design

APIs should not be tightly coupled to legacy applications, exposing whatever capabilities the legacy system offered. Nor should they be designed to work in the way the legacy system currently works.

Instead APIs should be consumer driven — built to expose the resources that consumers need, whether those resources are in legacy systems or new. There should not be a drive to expose an entire product via the API or to wait for the perfect backend system to be available. The recommendation is to just offer as much as is practically useful, then evolve it to meet needs. The API interface should be abstracted from the backend, so that backend systems can be changed or replaced over time without needing to change the interface.

The aim is to be future focused (while still pragmatic) and develop APIs to meet future needs. A good example of being future focused is building APIs to support Hypermedia as the Engine of Application State (HATEOAS). This is where an API, in response to a consuming application’s request, is programmed to return hyperlinks (URLs) that indicate the options for subsequent actions or information.

1.2.3.2. Layering

When designing and developing an API it is important to consider that an API is made up of the following distinct functional layers:

Security

Every API will have a security component. It is important to recognise that this is not only authentication and authorisation for access to an API, it also includes threat protection (Distributed Denial of Service (DDoS), Structured Query Language (SQL) Injection, Cross Site Scripting, and so on) as well as availability and Quality of Service (QoS). When designing and developing APIs it is often cost effective to create a common framework that handles security for all APIs. See Part B: API security 2022 for more details.

Caching

Caching can dramatically improve the performance of an API. When designing APIs consider what, when and where to cache. Understanding how data is changed and how often it is changed is an important consideration, as well as which layer it is most appropriate to cache at. A common caching strategy should be developed for APIs that would benefit from it.

Representation

When designing and developing an API it is important to consider the representation of that API. This commonly includes an interface specification that fully describes the API. To ensure the success of an API it should be easy to consume driving a well-considered representation layer.

Figure 2: API layering

Detailed description of figure

Figure 2 illustrates the functional layers that make up an API. A stylised image of a person sits at the top above an image of a computer, the consuming application. An arrow points down from the consuming application through the layers of security, caching and representation to the API at the bottom. An arrow from the API points back up through the same layers to the consuming application.

View larger image (PNG 21KB)

1.2.3.3. Standards based

Web standards have rapidly become powerful agreements, which span not just local regions but are internationally accepted and enable commonality and consistency. Using standard HTTP and URLs, the core technologies of the web, along with standards such as JSON and OAuth (Open Authorization) ensures that agencies are not creating bespoke or proprietary technologies.

Hence the principle is to build to the latest versions of existing open and accepted standards such as:

HTTP

OpenAPI

AsyncAPI

REST

JSON

OAuth

OpenID Connect (OIDC).

Refer to Appendix E for more details.

1.2.4. Designing an API

When designing an API, it is important to perform business process analysis to ensure that API development is business driven rather than technology driven. Technology-driven projects rarely meet customers’ needs in the long run, so it is important to gain background in who could be using the API, and for what. As mentioned previously, co-design is fundamental to driving the right API development. To help identify potential partners to involve in the co-design, consider processes that:

currently depend on information the API could expose

require a capability an API could expose.

Some actors will be human (for example, application developers) while some actors will be the systems that will interact with, or depend on, the API. There may be different types of actors, some public sector, some commercial entities, some public.

When representatives for the potential actors are identified, start co-designing with these representatives. First and foremost consider the requirements for the API. Application developers often couch their requirements in terms of how the API should work, rather than what the API needs to do. Do not get bogged down in the variety of proposed solutions from each developer. Focus on extracting the true requirements by performing functional analysis (for example, use cases) and data flow analysis, and then identify resources and work out the granularity (see section 1.2.7. Granularity).

It is especially important that security and information privacy impacts are identified up front and addressed early on in the design process. Assess the information being passed and the types of access different customers and / or consuming applications should have to the API. This will help drive development of security policies alongside the design of the API.

One common pitfall in API design is to map all existing data tables onto resources and develop the associated CRUD (Create, Read, Update and Delete) capabilities into an API. Usually this results in a poor API design and tightly couples the API design to the underlying data structure.

Another common pitfall is to design APIs as an extension to, or way into, monolithic legacy systems. This should be avoided as it tightly couples the API to the legacy system. Both of these pitfalls will create issues for both provider and consumers in the long term.

At this point in the design process, agility is probably more important than completeness. Share early design thoughts and interface specifications with the developer community and quickly make changes in response to their feedback. Work through some sequence diagrams with them to help pin down API interactions and inform API design thinking.

The correct API design will likely not please every API developer, so do not try to be all things to all developers. A rule of thumb is that the API design is probably on the right track if most developers are a little unhappy, but all are able to achieve their aims with the proposed design.

It is important not to try to bypass evolution steps and try to build for all potential use cases right from the offset. Starting simple and focusing on a single channel or interaction initially is a more measured progression towards API delivery. By building onto these simple building blocks, API evolution over time naturally progresses towards omnichannel applications.

1.2.5. Design considerations

The following considerations emerge when looking to develop APIs in the public sector.

Understand the data, understand the consumers. Before starting work on APIs, gain a good understanding of what data is held, the complexity of that data, its relationships to other data, the downstream dependents on that data, and potential consumers of the data. It is also a good idea to understand the consumers’ drivers and downstream usage or customers.