APIs are one of the magical black boxes software developers have come up with. You feed in a bunch of inputs and get an expected output and you don't have to worry about anything (assuming it is a nicely written masterpiece of code!). The performance of the API depends on a lot of factors. Still, for this article, I am more concerned about the maintenance of an API or an API service, in general, consisting of many APIs. I am also concerned with the industry-wide best practices on how to write an API in a layer and structured manner. I am still a learner but let me take this opportunity to talk about whatever I know about this topic having written an API service as well as quite a few APIs.
A general practice of computer science is to divide and conquer. The same applies to writing an API. Instead of writing an API which makes a database call and does a bunch of computations before returning a set of results as a single piece of code in one file or maybe two files, we usually structure the API code into three layers. The three layers are called by different names at different places at times but for me, I prefer to call them:
- Application Layer
- Service Layer
- Manager Layer
- DAO (Data access object) Layer
The primary reason for splitting the API into these layers is to ensure a better separation of concerns, ease of extension of API, and ease of maintenance and debugging. This image explains the usual flow of data in the layered structure of the API :
Figure 1: API Layering structure
The key tasks of the application layer are to serve as the entry point of the input and basic validations, authentication and authorization (if not done elsewhere in the service) and the first point of logging input received with other critical information. The second layer is the service layer which runs the main flow of code containing the business logic. Whenever needed, the service layer calls utility methods of specific nature (unlike general utility methods like sorting or splitting strings etc) from the next layer which is the manager layer. The service layer also does a deeper validation of the input (for example the divide by zero issues etc which come at a later stage) and finally returns the formatted output which the application layer returns to the client as the API response. The DAO layer acts as a single point from where the API makes any network calls to access 3P service or other things like databases, file storage etc.
This layering structure has many variations depending on the type of API, the exact requirements of the API and the code base where it is being written (and obviously the developer's creativity!). But this is what most of them look like at a high level. The benefits that this layering structure provides are :
- Each part is modular and easy to replace. Say tomorrow we want to update the database from MySQL to DynamoDB, we would only need to update the DAO layer leaving other layers untouched (or minimally touched). Or maybe we want some utility logic to be changed, then we would only need to update the manager layer and so on.
- Debugging becomes really easy as the logs now can be traced easily to which layer is the failing part.
- Uniformity in the service is achieved and developers' adventurism is reduced. Developers know what pieces of code to be kept where exactly and what pieces of code to find where.
- Documenting the API service becomes easier as the documentation is also layered and has a clear separation of concerns making it more readable and concise.
All in all, this structure gives our API a bit of flexibility to changes and changes are easier to make with the least lines of code changed in at least a number of places. At the same time, it gives the API a certain rigidity making it tough for developers to write pieces of code where they should not be written. This also helps the code reviewer review the code faster and better visualize the flow. Most API services adhere to this or similar layering flow and this provides a bit of standardization in the directory and code structuring as well and new developers can easily adapt to a new API code base. Other structures and comments on this structure are welcome!
Amrit Raj
Comments