REST API Tutorial: How to Design a Sustainable Web API
This guide is a step-by-step approach to designing a RESTful API using best practices. It will explain in detail data formats, architectural decisions, and how to implement real-time communication into your API. REST is an architecture style for designing networked applications, and an API that adheres to the principles of REST does not require the client to know anything about the structure of the API.
A Well Designed API Approach
The design of an API has different design phases and decision making that will determine how well your API is designed and the usability of your API. Without having a good strategic plan in place from the beginning can make it difficult to sustain the API over time. This post is to help you in this decision making process from the start to end of the design of the API, which leaves it up to you on how you implement your API and offer it for consumption by others that want to take advantage of the data that is offered from the API that you have created and designed.
One of the first decisions when designing your API is the data format that will represent the API. How the data is represented with be the decision maker on how your API is structured overall and how it will handle the requests and responses. These days the most popular data formats are JSON, but the use of XML is also an option. JSON has become so popular because of the ease of use with the data that is past back and forth to and from the API. What can drive this decision is one that you should consider in the eyes of the audience because it is the data format that will dictate how the information is understood and what is the easiest way for that data to be handled by those who are making use of the API.
The process of step 1 – dealing with data formats – is to make sure that the data has been put into a language that one computer can send to another that will understand that data. This is a reason why JSON has become so popular because the use of key value pairs makes it easy for both computers to understand that data stored in the key value pairs. Lets talk about the data that is represented by JSON.
The key value pairs that JSON holds are keys, and it is these keys are attributes that represent the object being described. The attributes tell what the object contains and what information can be taken from that object. When the attributes are needed from your API, it is the way that the data is stored that makes it easy to consume because of the ability to look at the values in a sentence like format.
If you have worked with JSON already, you know that it has a good way of putting data in a hierarchy that can make sense. For example, in a dictionary you can put an object inside of another object. Then you have key values that you have available not only from the parent object, but any object(s) that are nested inside of that object.
When passing data back and forth from computer to computer, there is important information that one computer needs to know about the data being sent from another computer. This information can be found in the headers of that envelope being sent so to speak. When the receiving computer receives the envelope, it will look at the headers for the information about the request or the response. One of the headers is the
Content-Type that one server sends with a certain data type to the other computer. When that content type is sent, the receiving computer will determine if it can accept the data type that is found in the body of the message inside of the envelope. One of the upsides is that if there is an error inside of the message, there is a fallback using the header
Architectural Design Decisions
When looking at the design of an API from this perspective, it is from a standpoint of how the API is used for hitting endpoints.
API’s have various decisions during the architectural design process, and these decisions determine the semantics of the API. Some of these decisions we will look at include: REST, requests and responses, resources, URL’s, endpoints, HTTP verb, GET, POST, PUT, DELETE.
This first thought process has to be how easy can the API be so that other computers can work with the data delivers from the API. This brings up the decisions that were touched on in the previous paragraph. One of the most used approaches is Representational State Transfer – REST – because it is an open approach for lots of conventions that are used for consumers of your API. How this transfer is made is determined by the resources made available by your API. Resources are the nouns of the API. Examples could be such things as Patient, Doctor, etc. Take note to the work things that I used to describe the resources. The resources represent things, which are nouns, that make it easy to understand the main focus of what your API makes available. These things can be found everywhere around us in the real world. Knowing this can help to plan the processes of typical interactions that happen in the real world that will help you to determine the resources that are needed. The API data should act like a script from a movie where you have to determine the actors, plots, and story lines that go into the movie.
To continue with the real world example of a movie, we need to look at the script and what roles these actors play. It is the roles of these actors that determine how well the movie is accepted by those who are watching – the receiving computers. This is what we can semantics so to speak in the determination of how to represent the resources of the API. The URL’s have to be understandable from a semantic point of view just like it is clear what role the actor is playing in the movie.
Let us take a step back into the API lingo to get an understanding of how important it is to realize the structure of a REST API. There are patterns that have been accepted by API authors that have shown the semantically correct way to make your resources available. The URL is plural for the resource name, in our case we could have something like
/doctors. Once we have that we then add on a unique identifier for the resource name. Lets say we have a doctor who has the ID of 4321 in the system and we want to make his information available. We would have a resource plus identifier so it is understood that this is the doctor we are wanting information for. So this will now look like so:
doctors/4321. So what it is that we have here? We have an endpoint. This endpoint is important because we then start to perform actions on the endpoint. How do we set up the actions for this?
There are a couple well thought out semantics for handling actions to perform and those are determined by the endpoints. Those that are plural are for listing and creating. Those that end with a plural plus unique identifier are for retrieving, updating, and cancelling. One the semantics of your API are in place, you can then determine the data that goes with each of the endpoints. One thing to take note of when working with REST is that it has an open ended approach, which allows the design of the API up to the person that is design it. At times, this can have a negative approach. There is a good amount of details that goes into the design of an API, and if it is thought out well, one will have good resources and endpoints that clearly define the semantics of the API.
- Resources are for clarifying the nouns of the API
- Endpoints are used to determine the HTTP verbs
How to Communicate in Real-Time
The design of the API has no real significance if there is no way to communicate from the user to the client and then to the server. The integration should be straightforward that will allow for sharing to link together the systems involved in the communication process. What is needed for this communication to happen?
There is a continuous real time communication process that goes on when your API is being used. What happens for the most part is that when something happens on one computer, the other will automatically update. One example of this is when a person interacts with the client and wants to update the server. One thing I want to mention before moving on that I may have overlooked is how to look at the role of the API on the computer. Just like any computer that you interact with, you have programs that you use. The API is considered to be a program, and it sits on the computer, which we call the server, and it is a stand-alone program that waits for the server to talk to it and asks for information that was sent to it by the client. What we mentioned above before this, when we were talking about the person interacting with the client wanting information from the server, this is considered client-driven. There is also server-driven. Server-driven differs in that a user does something and needs the client to be aware of the change. With the design of a good API, the client should be the only initiator of communication. When this design has been correctly implemented, the client will know exactly when data has changed, which allows it to call the API right away letting the server know about the data change. This happens in real time with no delay.
Of the two options, client-driven and server-driven, it is harder on the integration of server-driven because of the possibility of numerous requests that could be coming in at the same time and the server needing to know how to handle all of these requests. How can this be handled? Polling.
The options of polling can make the real time communication process look and feel smoother to the user. There are two familiar types of polling: regular short interval polling and long polling. When it comes to regular polling, the client asks for requests from the server on the status of the request and always looking for the response, even if it has not changed. When it comes to polling, the more that is done by the client, the smoother the real time communication feels. Unfortunately, there are drawbacks to this, simply because there could be no updates from the request. This at times can make the client inefficient in the real time communication process. So how can this be handled for a better real time communication process?
Long polling comes in handy much more than short polling because the server does not send back a request until there is one. So the client can ask for the requests, but there will be no responses from the server until the response has changed. You still looking for other ways for that real time communication process. Have you noticed a trend going on lately with web apps that have API’s available? There are offering webhooks. Why is this? It is because it is a process where the client makes both the requests and at the same time listens for them, which allows the server to push updates. What makes this different? It is because the client becomes both what is it and also acts as the server. This makes it where the server is stateless and has less of a strain on the request and response procedure. You probably have seen this with the likes of Twitter and Instagram, where they use webhooks. This can be seen because you have a provided callback URL that can receive events, and the server for a place that the person can enter the callback URL.
The polling, long polling, webhooks dynamics of the API is increasingly getting faster and faster for the real time communication process. One type of process that is making its ways into the limelight is Subscription Webhooks, which is a process where the client tells the server what events it is interested in and the callback URL that it should send the updates to. For more information, you can read about REST Hooks and PubSubHubbub.
The take away from this section is how communication can be real time between the server and the user with the client acting as the middle man doing all of the requesting.
There are various decisions that go into the design of the API, and you can find some great examples online showing API documentation, such as Facebook and Twitter. In regards to the programming languages that are used for the way that the API is communicated with, this is all dependent on the knowledge that your team has and what is the best fit for the integration of your API. This is not as important as the design of the API itself. As long as your have a well structured, semantically correct design for your API, all of the rest is sugar on top of the superstar of your web application.
There is also the importance of authentication, which would be just as long as this post, which made me feel better if I left it out for another post to explain the different types of authentication, such as OAuth and OAuth2. This topic is important as to how access is granted for communication with your API. That will be in another post. Please take note that these are notes that are from a series that Zepier put on in regards to the design of an API, and you can go to their site to find out for yourself how they view a well thought out API design.
Codementor Rob Simpson is a Sr. Web Developer at Agilex Technologies with over 15 years experience in web development, and his last few years have been focused on BackboneJS and AngularJS projects.