An introduction to API design
Web applications would not have existed without APIs... or, at least, they would have been much more difficult to use. In our new tutorial, we'll get you a proper introduction to API design and take a look at the most popular approaches towards this matter.
Table of contents
- What is API?
- API. Broad perspective
- API in modular design
- Web API
- Why CRUD fails
- RESTful service pros
- API design patterns: summary
What is API?
API means application programming interface.
The term most often refers to connections/information exchange protocols between computers or computer programs.
An API is a software interface, offering services to other pieces of software.
The most frequent API related terms are:
- API implementation/exposition,
- using/consuming API.
When somebody implements an API, it means they possess an API server to be used by clients.
Information regarding what an API shares with clients and how it works is featured in API specifications. The API specification is most often a document or a separate program.
API. Broad perspective
Programming language API.
There are numerous possibilities of calling a piece of code an API, even within one application.
API in modular design
API creates layers and boundaries between particular elements of a system or an API module. The facade module is among the most popular ones. Its main function is to combine several modules into one, transparent interface.
Another function of an API in modular design is to hide the implementation from the interface. Example?
In a web API, we don’t need a client to know the exact data models, functions, or queries in the database. When the client is interested in getting a list of users, they get a list of users, and nothing else.
In modular design, API is frequently use-case-oriented. We’ll get to explain this approach in the later paragraphs of this article.
A monolith is the most basic way of writing applications. I call it “a classic monolith”.
In monolith applications, a system is divided into layers such as model, view and controller.
In our case, there are additional layers:
- template, which is bound to view, and provides us with HTML tools to build views,
- and database connected to the model.
There is also a server routing for accepting requests and adjusting them to the actions of the controller.
In Elixir, requests are transferred to server routing through endpoints.
Monolith with frontend client
In this example, the layers of a monolithic application are accompanied by a client app.
A client app can be hosted by a backend language or a node.
Client applications are separate parts of a system that communicate with server via HTTP requests.
Different than in classic monolithic applications, templates are no longer responsible for creating client views. They use data exchange formats such as JSON, XML, etc.
The client layer (application) is used to serve the data to the client in a nice way.
This is a very popular approach to web API programming.
The client layer consists of:
- additional abstractions to make the application’s maintenance easier,
- an API client for communication with a server.
In this instance, a server needs a way to display data to the client, often using JSON/XML API for communication with a client.
Even though the client layer can run on the same virtual machine as other layers, it is a separate application.
What is CRUD?
CRUD stands for Create Read Update Delete. It is a standard for building web applications.
Create, read, update, and delete are the names of 4 operations on assets.
Each of these operations has a counterpart in an HTTP query, e.g.
operation: create - HTTP method: post
read - get
update - put/patch
“Put” supplies a modified resource.
“Patch” supplies a set of instructions to achieve a goal desired by the client.
Why CRUD fails
- applications are built with the goal of streamlining processes rather than creating resources,
- Entities don’t follow business rules (e.g. post without published_at cannot be seen),
- Business logic is complex,
- Operations are the core of an application (e.g. customers do not set “paid” status, they pay for a product).
In short, this is what I meant by talking that APIs are use-case-oriented in most cases.
REST is a way of building web applications based on 6 core principles:
- Uniform interface. All endpoints behave in a similar fashion, even though they operate on different entities.
- Stateless. An application’s state is only registered in the database.
- Cacheable. We can use HTTP tools to speed up our application.
- Layered system,
- Code on demand (optional solution), which means that part of the logic can be transferred into the client application.
RESTful service pros
- Your API behaves in a predictable way,
- Simple (but not always easy) API usage,
- Is a mature, battle-proven, and mature standard,
- Easy scalability with HTTP tools (e.g. caching),
- Lack of state.
RESTful API cons
- Lack of state (which is a good thing as long as we don’t need it).
- Doesn’t necessarily translate to the real world,
- Easy to grow exponentially when more functionalities are being implemented,
- Low cohesion,
- We DON’T STORE stuff, we DO stuff
REST is heavily bound to the way HTTP was implemented. Hence the question: should we treat HTTP as something more than just a “transport” protocol? We need neither its semantics, nor architecture designed on top of it.
Composite API is a design approach to batching API requests sequentially into a single API call.
E.g. when you want to communicate with an external RESTful API, you create a composite defining the list of operations to be made on the server-side, and returning the results.
Business Domain Centric API
It is more an approach than a pattern, based on 4 principles.
- Controllers accept and check parameters’ high-level validity (e.g. type, the existence of an argument),
- Controllers run code that DOES stuff (e.g. publish_post, process_payment),
- Can have regular CRUD endpoints,
- Gives us room for flexibility.
A specification-turned-platform for building APIs with 1 endpoint (“/graphql”) responsible for handling queries.
2 requests are possible in GraphQL:
- GET - which is a “query”,
- POST - which is a JSON request that specifies what you want to change (“query”, “operationName” and “variables”).
GraphQL is a good alternative to REST.
In real-life scenarios, it requires using more abstractions than queries and mutations.
This is why its learning threshold is pretty high at first. This is, however, compensated by the insane speed of delivery for apps that change a lot, and require multiple sources of data.
GraphQL also guarantees rapid prototyping, and easy testing, albeit doesn’t avoid performance issues.
API design patterns: summary
There are plenty of web API design variants, though there is no ideal one-size-fits-all solution. Each one has its pros and cons. As time goes by, the solutions which had previously been called “next big things” end up useless or abused. Like everywhere, common sense seems to be the most effective way to choose the proper one.