API-first Development

Romeo Agbor Peter - Sep 4 '21 - - Dev Community

Web applications and systems over the internet communicate via APIs. The data exchanged can be in any form, one of those forms is a standard architecture called REST. In this article, you'll learn what a REST API is and how it's used to build decoupled web applications can scale.

API

Application Programming Interface (API) is an approach for data exchange between two independent software application. It is a software-to-software communication.

RESTful APIs

REpresentational State Transfer (REST) is standard for building APIs. It consists of patterns and structures that stands as a guidelines for building APIs. APIs that are built following such structures and patterns are known as RESTful web services. The REST architecture is generally preferred over the obsolete SOAP API architecture because of the benefit of less bandwidth over the web.

Why API?

Say you're building a web application that'll showcase all the schools in your city and their geographical details, like the distance, nearest landmark, road routes, etc. Instead of building a mapping system of your own, you can employ Google Maps to get showcase the geolocation of the schools. Building a mapping system is quite complex in its nature. That's why outsourcing such task to a system that is built specifically to handle mapping and geolocation is a wise choice. And that's why APIs were exist — to consume resource from an independent system over the internet.

A consuming software can also provide an API for other systems to consume. The system consuming the resources does not have to have a link to the systems it consumes from. In fact, they are usually not related.

With the advent of the "API-first" approach as a standard for building modern software, especially on the web, the use of APIs has provided a "future-proof" and multifaceted way of building web applications.

"API-first"

This approach consists mainly of two parts in web application — the frontend and the backend — that are separated from each other. The backend deals only with the server and database(s) and provides an API through endpoints for the frontend or client to consume. The front-end then manages the presentation (the part users see) of that data.

The approach of separating, or dividing services into different parts is broadly known as Service-oriented architecture.

The only downside (I don't considered a downside at all considering the many benefits) to the API-first approach is that it require extra configuration.

Although it is "easier" to build a web application using the traditional method where both the frontend and backend are interwoven and the whole application sits on a remote server that processes data and sends it back as response to the client. It is not ideal to build modern applications this way as you'll see why:

  • Web applications built using the traditional method do not support multiple clients or frontends. It shouldn't matter the client, whether desktop or mobile; or which framework is being used, whether React, Angular, or Vue. With the API-first approach, the backend should be a "hub" for holding and transmitting API data via HTTP when requested for. If you're a developer then supporting multiple clients should get you excited.

  • In the traditional approach, backend data can't be used both internally and externally. There is no easy way to power in-house applications with data from the backend. With API-first, data can be used to power internal and external applications. All the developer need do is request and present the data gotten from the backend API.

  • Applications built using API-first approach are fast. Because the frontend is separated from the backend, response from the server are usually quite fast. This is because after the frontend initially loads on the client (in this case the browser), the client downloads the web pages and from the server and caches it. Hence, further responses coming from the server are quite fast as it is just for getting back data. Incoming data will not slow down or stop the web pages from loading on the client. This is unlike the traditional approach where the server must process all there is on every request before sending back data.

  • API-first web application development is streamlined. The frontend developer only have to be concerned about making changes to the frontend. Traditionally, a frontend developer is suppose to possess an understanding of the backend systems. Similarly, the backend developer is only concerned about the server logic and how it delivers the required data. The backend developer need not worry about how the data would be presented as UI in the frontend.

Web API (server side)

A server-side web API is a programmatic interface consisting of one or more publicly exposed endpoint to a defined request-respond message system typically expressed in JSON or XML, which is exposed via the web -- most commonly by means of HTTP-based web server.

-- Wikipedia

A web API suite of endpoints that exposes a certain part of a database. URLs are pointed to available endpoints to get the available underlying data through HTTP actions.

How the Web Works

Before we go on from here, I want to do a recap of how the technologies behind the web work. This will ultimately give you a better understanding of web APIs and the API-first approach. Besides, a web API sits on top of the underlying architecture and protocols of the web.

Computers connected via internet fall the categories of clients and servers.

A client is any internet-connected device or web-accessing software. A server as the name implies is a computer that store and serve website, web apps and its related data.

A client can make a request to the server asking for copy of website, web app or data and the server answers the request by sending a corresponding response.

Below are protocols that make the web work:

World Wide Web (WWW)

The World Wide Web as we know it today was made possible in 1989. The web runs on Hypertext Transfer Protocol (HTTP) that allows for the movement of a text containing links over the internet. With this idea, documents could be shared over the internet. This brought the notion of web pages. This invention has become the ideal way of computer communication over the internet.

URL

The Uniform Resource Locator (URL) refer to the address of resource(website) on the internet.

https://www.romeopeter.com is an instance of a URL.

When a client (any internet-connected device) enters the address, a request is sent to the server hosting this website and the server sends back a response containing a copy of the website. The request and response process is done through HTTP.

TCP/IP

Transmission Control Protocol and Internet Protocol (TCP/IP) are communication protocols that state how data should be transferred over the internet.

DNS

Domain Name Servers (DNS) translate domain name like "romeopeter.com" into IP address, the address is then used to send an HTTP message to a server to get a copy of the webpage, and the server sends it as a response. An IP address is a sequence of numerical character separated by a dot (.) that every internet-connected device has. It uniquely identifies the device. The reason behind DNS is because a website name like "romepeter.com" is easier to remember for humans than an address like 198.23.159.66

HTTP actions

HTTP actions, or verbs are a list of keyword that allows a client to retrieve and manipulate data on a server. These are known as request methods. When a client sends an HTTP request to a server to get data, such a request is a GET request.

The client can CREATE, READ, UPDATE, and DELETE data stored on the server. This is known as the CRUD (Create-Read-Update-Delete) functionalities.

For instance, every tweet or IG post you make or delete, you set off one of the CRUD functions.

The four most common HTTP request methods are GET, POST, PUT, and DELETE.

Diagram

HTTP Actions                            CRUD Functions
----------                              ----------

GET ------------------------------->    Read
POST ------------------------------>    Create
PUT ------------------------------->    Update
DELETE ------------------------------>  Delete
Enter fullscreen mode Exit fullscreen mode

content are read using the using GET action, created using POST, updated using PUT and deletes using DELETE.

Status Code

When a client sends a request to a server, the server executes the requests and sends back a response with a status code. HTTP status codes are issued by the server in response to a client's request.

The general category of status codes are:

  • 2xx Success - Request by client was understood and resolved
  • 3xx Redirection - Request moved or redirected
  • 4xx Client Error - Error in client request, usually bad URL or bad login request
  • 5xx Server Error - Server failed to process or resolve a request

For every HTTP request, there are only four potential outcomes: it worked (2xx), redirected to different URL (3xx), Error from the client (4xx), Error from the server (5xx).

The common ones are 200 (OK), 201 (created), 301 (moved permanently), 404 (Not Found), 500 (Server Error).

Statelessness

The HTTP request-response cycle happens independently or in complete isolation. This means no memory of previous request or response is stored and no request or response is affected by the previous one from the same client. This is known as statelessness.

When a client makes a request, it includes the necessary data needed for the server to fulfil or resolve that request. The server will not fulfil a new request using data from the previous one.

Although HTTP protocol is stateless (no memory), state (memory) is necessary for every traditional web application. When you login in a web application, a state is created on the server to identify you and every further request you make. For example, a state is created to manage your online shopping cart when you shop online.

You'll learn more about states when we dive into API authentication.

REST

We talked earlier about REST (REpresentational State Transfer) being an architecture type for building an API but didn't touch on the features

REST is a standard for building APIs for the web. The standard is consistent for building and consuming APIs via the the HTTP protocol.

Three main features of REST:

  • It is stateless
  • Supports HTTP actions (GET, POST, PUT, and DELETE)
  • Return data in JSON (the preferred format) or XML.
  • Light weight data transmission.

API Authentication

API authentication is an API-first approach for user verification and identification.

In an API driven software, when a user makes a request (in the case where a user tries to log in) to the server, the server first identifies the user so that further request from that user will be resolved (accepted). If the credentials match what the server has already stored then the user is verified (authenticated), else a message with the appropriate HTTP status code is sent as response to the client indicating the user is not verified (unauthenticated).

API authentication is unlike the simpler traditional web authentication where a session (state) is created for the verified user on the server. This way of authentication is quite straight forward because the session remembers who the authenticated entity until the state is terminated.

API authentication uses HTTP which is a stateless protocol. the protocol has no memory of the request-response cycle. That means there is no way to tell if a user is authenticated or not because each request happens independently. To resolve the issue of authentication, a unique identifier is passed along with each HTTP request to the server.

There are many ways you can take to when implementing an API-first authentication:

Basic Authentication

This is the common approach in implementing an API authentication. The user's username and password separated by a colon (username:password) is passed as a value into a special HTTP header keyword called Authorization.

Here is an example:

Diagram

{
    Authorization: Basic bGT06bJHG3yZQ7Niub9uy6bi5i
}
Enter fullscreen mode Exit fullscreen mode

The username:password value is encoded in base64, which is an encoding scheme to convert data to 64 bit characters, thus preventing modification when transporting data.

This method does not require cookies or session ID because it uses the request header.

Once the request gets to the server, the server checks the Authorization header and compares the username:password value with credential it has stored. If the credentials match then the user is verified and the server fulfills the client request and a response is sent with a status code (200 OK). If the user is not verified a message and status code (401 Unauthorized) is sent back to the client, informing the client that the authentication failed and therefore can not grant request.

Below is visual of what happens

Diagram

Client                                                                      Server
--------                                                                    --------

GET / HTTP/1.1
------------------------->
                                                            HTTP/1.1 401 Unauthorized
                                                                 WWW-Authenticate: Basic
                                                            <------------------------ 
GET / HTTP/1.1
Authorization: Basic bGT06bJHG3yZQ7Niub9uy6bi5i
------------------------------------------------->

                                                            HTTP/1.1 200 OK
                                                            <------------------------
Enter fullscreen mode Exit fullscreen mode

The down side is that credentials must be sent to the server on every request. Basic authentication is most suitable for testing and should only be used over HTTPS, which is the secured version of HTTP.

Session Authentication

API session-based authentication is a combination of Basic Authentication and Session Authentication.

To understand how this works, you have to understand how session-based cookie authentication works in traditional web application.

In traditional web apps, the user sends a login request from a client to a server that utilizes session and cookie authentication scheme, the server resolves the request if the credential (mostly username and password) match and a session ID (unique identifier) is returned as a response. The response is then stored as a cookie in the browser.

Session IDs are unique to each client (in this case the browser). The validity of the ID is only within the client. The ID can not be used across multiple domains.

The server creates a session object (state) containing information about a user, including the credentials.

Further requests from the client have to include the session ID as an HTTP request header. The server uses the session ID from the request header to identify the user by matching it with the session object that holds all the user data in the server. If there's a match then the user is identified and the request is resolved.

Session ID is terminated by both server and client when user logs out. If the user logs in again, a new session ID is generated and stored as cookie in the browser.

The session and cookie approach are stateful because data is stored on the client and the server.

Now, back to API Session Authentication. In this instance, it's a combination of Basic Authentication and Session Authentication (as stated above). The Basic authentication scheme is used only to send the session ID via HTTP request header for each request. The difference with this combination of authentication schemes is that authentication happens only once, unlike the single Basic Authentication (credentials are sent for each request). This makes it more secure and efficient as the server does not have to verify the user on each request, rather it only matches session ID with the session object on the server as a faster way of looking up the user.

Diagram

Client                                                                      Server
------                                                                      ------

POST / HTTP/1.1
credential(username&password)
------------------------->
                                                            HTTP/1.1 200 OK
                                                       Set-cookie: sessionID = ksd6kB...
                                                            <------------------------ 
GET / HTTP/1.1
Authorization: Basic ksd6kBSDKkjhds7KK2kjUGb9uyi
------------------------------------------------->

                                                            HTTP/1.1 200 OK
                                                            <------------------------
Enter fullscreen mode Exit fullscreen mode

Noting the diagram above, a user logs in and a session ID is sent as a response to be stored as a cookie in the browser. Basic Authentication is then used to send the session ID via HTTP request header to the server. The server matches session ID with its session object and a confirmation (200 OK) is sent back to the client.

The downside of session authentication is lack of scaling. The use of session ID makes it limited to only one domain. Multiple frontends or clients aren't supported outside that domain, such as desktop and mobile clients. Also, this approach is difficult to maintain across servers as sessions object have to be maintained and kept up-to-date. And lastly, the cookie is sent for every request, whether needed or not, which is inefficient.

Session-based authentication scheme should not be used for API that have to respond to multiple clients.

Bearer Authentication

Bearer authentication (or token authentication) is an authentication scheme that uses the exchange of token (cryptographic characters) to grant access to a user.

It's a stateless authentication scheme where access is given to the bearer of the token. The token is generated by the server and sent to the client to be stored as either a cookie or in local storage. The token is passed to the head of all future request going to the server. The server uses the token to verify that the user is authenticated. The server does not create a state (session) to validate the user. No record of the user is kept on the server, all it does is check if the token is valid.

see in the diagram below for the flow of Bearer Authentication.

Diagram

Client                                                                      Server
------                                                                      ------

POST / HTTP/1.1
------------------------->
                                                            HTTP/1.1 404 Unauthorized
                                                            <------------------------ 
GET / HTTP/1.1
Authorization: Bearer 401f7ac837da42b97f613d789819ff93537bee6a
------------------------------------------------->

                                                            HTTP/1.1 200 OK
                                                            <------------------------
Enter fullscreen mode Exit fullscreen mode

This approach of authentication is considered appropriate for client-server setup. It comes with two major advantages:

  • No session object is created on the server as token is stored only in the client.
  • Scalability: Token can be shared across domains. Multiple clients can be supported: building for web, mobile and even desktop clients.

Token authentication should always be used over HTTPS.

Conclusion

We've covered some core concept of an API-driven software. From what an API is, to a RESTful API, the API-first approach, underlying technology of web APIs and the many different methods of API authentication.

There are other methods of authentications we didn't touch here, such as JWT (JSON Web Token), API keys and OAuth 2.0.

I leave the rest (see what I did there?) to you to find out on your own.

. . . . . . . . . . . . . . . . . . .