As users of technology, we use REST APIs every day in some or the other form. Some of us also build REST APIs in day-to-day developers’ life. What are APIs and what makes them RESTful? In this article, I will talk about how to design scalable, reliable, and consistent RESTful APIs while avoiding common mistakes.
What is REST?
REST is an architectural style that defines a set of architectural principles by which you can design web services that focus on a system’s “resources”, including how the resource “states” are addressed and transferred over HTTP upon invocation by a wide range of “clients” written in different programming languages.
What is an API?
An API which is an acronym for Application Programming Interface, is a software intermediary that allows two applications to talk to each other. API is the software program that allows to programmatically interact one software application/component/resource with another. In simple words, APIs are the default means of communication between various software applications and systems. If you use a smart phone, look at any popular app such as google maps, Instagram, TikTok, Snapchat — they are all examples of how APIs can be efficiently used for communication. Thinking of a commercial website, look at Amazon and you will see how the website harnesses the power of APIs to deliver products, shopping experience and much more.
The Bezos API Mandate: Amazon’s Manifesto for Externalization
In 2002, according to tech legend, a mandate was issued by Amazon founder Jeff Bezos. This mandate would serve to form the backbone of Amazon in the modern web space, informing both the API development paradigm in the corporate mindset and a general improved approach to externalizing API functions.
The Mandate became somewhat legendary in the API/microservices space, as it formed the basis for much of the modern API design paradigm within the corporate view.
By legend, the mandate is as follows:
1. All teams will henceforth expose their data and functionality through service interfaces.
2. Teams must communicate with each other through these interfaces.
3. There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team’s data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network.
4. It doesn’t matter what technology they use. HTTP, Corba, Pubsub, custom protocols — doesn’t matter.
5. All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.
6. Anyone who doesn’t do this will be fired.
7. Thank you; have a nice day!
This mandate indeed became the core of Amazon’ technology development, and further Amazon built API based scalable systems that became part of SaaS offerings from such as Amazon Web Services.
RESTful APIs and Microservices
The terms RESTful API and Microservices go hand-in-hand. When talking about APIs, we must also talk about microservices and most importantly how they differ from each other. They refer to very different things and the easiest way to understand the difference between RESTful APIs and microservices is from the function perspective:
- Microservices present the independent software services or functions — or the basic building blocks — that form a larger application which is based on many small microservices.
- APIs present the protocols, rules, controls, and governance that combines one or more microservices together and deliver a result which is one single response to the end user. APIs work as a glue between various systems, microservices and users of the system.
What is Microservices Architecture?
Microservice architecture, as described by Martin Fowler is below:
In short, the microservice architectural style  is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
Microservice architecture applies principles of componentization of services. Using this architecture, software system is decomposed into various sub-components that can be defined as microservices. These microservices remain isolated in functioning and are assigned a single responsibility. Microservices, by definition, are atomic. Any change in any of the microservices does not affect the functioning of other microservices.
While microservices architecture comprise of completely isolated, fully functional and fine-grained services, these microservices are also capable of scaling independently. A typical microservices architecture consist of typical component as follows:
A typical Microservice Architecture consist of the following components:
- Identity Provider
- API Gateway
- Messaging Formats
- Service Management
- Service Discovery
- Service cataloguing
Salient Features of a Microservices Architecture
Here are some salient features of a microservices architecture that makes it different from a legacy monolith architecture.
- Modular: By splitting an application into smaller components, it becomes easier to understand, develop, and test the application.
- Domain Driven Design: Microservices are built around business capabilities and the right approach using domain driven design leads to the right microservices implementation using capabilities-based componentization.
- Scalable: Since microservices are implemented and deployed independently, they can be monitored and scaled independently.
- Robustness: When a memory leak exists in a microservice, only that microservice is affected. The other microservices keep running. Consider the example of Netflix, if one of the movie categories (say drama) in the feed fails, other categories (such as action, family, kids etc.) are not affected.
- Security: Because microservices are isolated, the entire system is not affected by attacks to one microservice.
- Product based design: Microservices based implementation focusses on thinking products and not projects. Version the products for various major and minor feature changes.
- Improved processes: Decentralized governance and decentralized data management help improving overall processes.
- Elastic: Well-designed microservices are designed for failure, loosely coupled and are elastic in nature. While endpoints are designed smart, pipes remain dumb and do not store any service states.
Here are some key areas to focus on when considering a microservices architecture:
- API contracts for services for public usage
- Containers as build artifacts
- Dependency management among multiple services
- Monitoring various stages of deployment lifecycle
- Detect failure fast, fail gracefully and recover fast!
- Infrastructure automation
- Component/Module reuse across organizational boundaries
- Centralized architecture team vs decentralized architecture team
Potential drawbacks of a Microservices based Architecture
Despite all the benefits, microservices architecture comes with its own challenges, from implementation to migration and maintenance. Some of the prominent challenges adopting a microservices architecture poses include:
- Operationally expensive: Too many services, operational overhead compared to monolith applications.
- Potential failures: Higher number of services lead to potential failures in communication between various services.
- Complex testing: Each microservice needs a separate testing cycle over a distributed environment, thus making it more expensive from cost and effort perspective.
- Complex development: Componentized implementation requires much more time and skills than developing standard monolith applications.
REST meets Microservices
REST is a great tool for building a scalable microservice since they are stateless and modular. The REST architecture pattern allows the client and the server to be implemented independently without the knowledge of the other entity. This means that code at either side can be modified without affecting each other.
Here are the key drivers where RESTful APIs are coupled with microservices based architecture to deliver business value by implementing best practices in design and delivery of an enterprise system:
I plan to detail Service Mesh concepts and implementation in a separate article. Here are some of the basics around Service Mesh and its utility.
What is a Service Mesh?
A service mesh is a low latency dedicated infrastructure layer designed to handle and facilitate service-to-service communications between microservices (and other services) using APIs. Service mesh also abstracts the networking aspect of microservices from their business logic.
A typical implementation of a service mesh, for example Istio, involved implementing a set of proxies alongside the application code. These proxies handle the communication between the microservices. Service mesh provide security, observability, and reliability by using these proxies which are often referred as sidecars. The application code does not need to build these features and they also do not need to be aware of existence of the service mesh.
Service Mesh or API Gateway?
This is one of the most common question technologists have about a service mesh. If we have API gateway, do we still need a service mesh?
The answer is not very complex. There are overlaps between functions of an API gateway and a service mesh, but they serve different purpose. Both API gateway and Service mesh can handle security, traffic management, and monitoring and service discovery, however, these implementations happen in different contexts. An API Gateway primarily manages traffic from edge level client-to-service while a service mesh is used for managing internal service-to-service communication.
Service Meshes are completely decentralized and self-organizing networks between microservice instances that handle service discovery, traffic management, load balancing, monitoring, and tracing. API Gateways in general focus on ingress traffic to your application environment, i.e. from external clients to API endpoints-microservices (commonly referred to as north/south traffic). Service meshes on the other hand manage the traffic between services in your cloud environment (referred to as east/west traffic).
The decentralized nature of Service meshes makes it easier to work on microservices within fairly isolated teams, however, Service meshes can be quite complex for large implementations and involve a lot of moving parts.