Aspects for API Designing (2/3)

David E Lares S
The Startup
Published in
4 min readFeb 22, 2021

This second part is oriented on the architectural constraints of API development. These are a bunch of concepts that are extremely related to code work, in different aspects.

Code on demand

Some products establish Code-on-demand constraints, where the server can extend client functionality by sending code, regardless of data. You as a developer can send some kind of executable components to extend functionality or just for patching bugs. An example of this constraint is the Java Applet, Flash components, or JavaScript code

Client -> Load balancer -> App Server -> DB Layer

Then, the server can respond from the server side, you can receive the script that will run to whatever logic is written for. You can summarize this in two steps. The first one is that the server can send code along with data to a client, and then, the client can execute the received code to carry out some action.

Statelessness

Another constraint is Statelessness, and it’s found when a client connects to the backend. This constraint creates a client session that manages the application data for accessing the client state, so all the subsequent calls from the same client lead to the backend in a form or other to access the client state.

In a few words, the client state is handled by the HTTP sessions. However, this is not possible for REST APIs, because is a stateless architecture, here, each request is independent and the server only receives all the information of the request.

Between a client doing a request and the mid-tier or backend layer, there’s no state management. The state is handled in the client if needed, but not in the mid-tier or a web server.

Layered System architecture

The third constraint is the Layered System architecture, which consists of multiple layers in a client-server architecture, where no layer can see the past or the next layer in the stack, and the load-balancers are the ones responsible for load distribution.

It can be found like this: Client -> Gateway -> App Server -> DB Layer

The most important condition set by this constraint is that the client must never connect directly to the server, this is done by the load balancer only.

By using layers, you can hide the complexity of the whole, and adapt to whatever needs are required without losing the implementation. This is ideal for simplification and evolution because each layer can change independently and the client connection is not done directly to a server.

This one precedes the Client-Server constraint as you know it.

Client-Server

This is the foundation for the REST architecture, it uses a uniform interface as an interactive component for HTTP clients.

We already discuss this in the first part of this post series, but to summarize this. In API development, the owner entity needs to figure out a way to solve performance, scaling, authentication, security, and design concerns, while the consumers are more focused on product concerns such as UI, UX, or authorization mechanisms.

The client and the server do not reside in the same process, and there’s no direct calling functionality. The server is decoupled from the client and both can change without impacting each other.

Union interface

The union interface states that the client and the server share a common technical interface, a simple contract for client-server communication that has no business context attached, just a technical one.

This is just a fancy way of describing APIs because this principle is compounded by the identity of the resource, commonly done by URI/URL executions, that can expose the resources and perform resource manipulation based on the HTTP verbs that accompany them

Another cool thing that I forgot about API designing in the first section is the fact that the server not only sends data but also can send actions with HateOAS, this is just including links for better results when interacting with the API.

Caching

Caching is just another architectural constraint based directly on the HTTP cache headers. Many details are found in the first part of this series as well, but to complement what has been told there it can be found locally and in a shared mode.

Statelessness cases can hurt performance in terms of chattiness and higher data traffic. Caching is good to counterbalance the negative impact of statelessness and can be present on the server, the mid-tier, or the client.

Details can be found in the first part of the series.

REST architecture

REST is only an architectural POV, if your API uses JSON is not a guarantee that is a RESTful API.

To be cataloged as a RESTful App, it needs to follow some rules.

  1. Must be a client-server
  2. Use a uniform interface for a well-designed communications contract between a Client and a Server
  3. Caching for controlling the responses, at least the static ones.
  4. Layered systems, multiple layers managed independently
  5. Managing code-on-demand patterns as an optional aspect

Let’s summarize this:

An architecture constraint is a design rule that can be conformed to your API, each one presented here is unique in the form of working or complementing a base API approach.

You can go deep into details, and work with the one that suits your needs.

Join me in the last section, I will be reviewing the security aspects of the API design.

--

--