APIs are central to modern software development, but there’s not a single approach to how they’re built. In fact, early APIs were likely tacked on to existing software. This monolithic approach has been replaced in recent years by microservice architecture. If you’re a seasoned developer, you’ve likely heard about microservices and maybe even built them. After all, most tech giants have embraced microservices including Amazon, Apple, Microsoft, and Netflix. Not all developers are familiar with microservices. This guide will cover the characteristics of microservices, best practices of this architectural style, as well as additional details to help developers and others make sense of the common patterns.
If you ask a group of developers what microservices are, you’ll likely get many different answers. There's no industry-wide universal definition of microservices. But you’ll find one of the most concise descriptions is in Sam Newman’s book, "Building Microservices."
Some companies define microservices as an architectural pattern used to build and structure applications as a collection of loosely coupled, small services. Each service is treated separately and can be reused within the company or externally by third-party developers.
A microservices architecture can consist of dozens, hundreds, even thousands of individual services. And because each service is autonomous, you can add new features and fix problems without the risk of breaking the entire application.
Even if you have experience with microservices, it’s easy to misunderstand some of the characteristics.
Microservices are not:
- Small: Microservices aren’t always “small,” as the adjective micro implies. A microservice focuses on one task, and its size depends on the application.
- Defined by size: Microservices are not defined by size, such as the number of endpoints or lines of code.
- An API: A microservice and an API are not the same thing. APIs enable developers to consume a service, but not all microservices are consumed by developers.
- SOA: Microservices is not another name for service-oriented architecture (SOA). They are different things that share a few of the same characteristics.
In the next section, we’ll cover some of these misconceptions by explaining the common microservice properties.
Microservices enable developers to build distributed applications that are reliable, scalable, and agile. To achieve this, there are some key characteristics of microservices:
- Organized by business capabilities
- Loosely coupled
- Language agnostic
In the following sections, we’ll go into detail of each of these characteristics, as well as explain how microservices differ from other approaches.
In a microservices architecture, services are organized by business capabilities, with each independent service focusing on a specific business function. For example, if you’re building a customer-facing application for a bank, you would add a microservice for each banking function, such as:
- Get a checking account.
- Get a savings account.
- Get account balances.
- Get account transactions.
If the bank is in Europe, it might provide Open Banking APIs that you could incorporate into an approved third-party financial services app.
If you’re building a hotel booking app, you might organize individual services something like this:
- Search for accommodations.
- Get hotel room prices.
- Create an account.
- Book a hotel.
- Pay for the booking.
For the hotel microservices example, you would likely need to create multiple services for each capability. For example, “pay for the booking” might include individual services for account authorization, identity validation, and payment processing.
Each microservice represents a different business capability and each service is autonomous.
The basic idea of microservices is that services are independent and autonomous — if there is a problem with one service, it shouldn’t impact other services and break your application. If you build an app with microservices, you should minimize dependencies, and any dependencies you use should be as small as possible.
Before the advent of microservices, applications were built as monoliths. When an application is a monolith, every service is tightly coupled together, and the entire app is treated as a single unit.
If you built the above hotel booking app as a monolith, a bug in one part of the system could take the entire app offline for hours, possibly days. Prolonged downtime for your app is not good for business. Customers would flock to a competing hotel booking app that works reliably.
Netflix is well known for its use of microservices. But when the Netflix website was a monolithic application back in 2008, the entire site went down because of one missing semicolon. One minor mistake anywhere in your tightly coupled monolithic application could break it.
Microservices don’t require a specific programming language. You can build each service with the best language, library, or framework for the job. You can experiment with cutting-edge technologies without the worry that you’ll break the application.
Language agnostic is a useful characteristic when you have multiple teams with different language specialties. But you must ensure that language agnostic is not taken to the extreme. You need to be able to maintain all the code of your application, which is challenging if every service uses a different technology.
Language agnostic also means you aren’t limited to one method of communication among services.
Every service in a microservices architecture must communicate with each other, and each service has its own communication protocol. Microservices usually rely on APIs for communication because APIs are language independent and often lightweight. A microservice might use HTTP, REST, or WebSockets to communicate with other services within an app.
When it comes to data management, each microservice handles its own database. Although, in some cases, a few services may share the same database. Each service may use the same database technology but with different instances, or they may use an approach called polyglot persistence, where each service uses a different database. With microservices, you don’t want all the services to share the same database or one persistent store.
There were other architectural trends before microservices. Before APIs became the common language, many organizations used service-oriented architecture (SOA). Like microservices, if you ask different companies what SOA is, you’ll get different answers. SOA shares some similarities with microservices. For example, they both enable the reuse of individual components, and applications are organized based on business functions.
The key differences between SOA and microservices are scope and communication. SOA is an enterprise-wide approach to building applications where developers can reuse functions from one app to another across the enterprise. Microservices enable an application to be broken into individual business functions that can be scaled, reused, and administered independently.
When it comes to communication, every microservice has its own protocol. However, each service of an SOA application shares an ESB (enterprise service bus) for communication. If the ESB fails, then the services can’t communicate with each other, and the application breaks.
The main difference between microservices and APIs involves consumption. APIs focus on consumption; they enable applications to consume services. Developers use APIs to add functionality to and interact with applications. Whereas, microservices allow developers to build an application with an architectural style that divides functionality into small autonomous services. APIs are used in microservices architectures not only for service communication but also to expose the functionality of individual services.
Understanding the basic principles of microservices is a great first step. But before you start using them to build applications, you need to make some decisions regarding application architecture.
If you plan on using microservices to build an application, you don't doesn’t necessarily have to use them right out of the gate. If your team isn’t experienced with building microservices architectures, then starting with a monolith might be your best option. However, the components of a monolith will eventually become tightly coupled together. So, if you decide to break up a monolith into services later, it will be challenging.
If you’re looking to add cutting-edge features to your application, then starting with a microservices architecture may be the best choice. Microservices are language agnostic, so you can use the best language, framework, and library for each feature you want to add to your app. You can also add cutting-edge features to a monolithic application, but monoliths tend to use only a few languages.
When it comes to application architectures, monolith and microservices are not the only options. Other types of architectures include event-driven and N-tier (multi-tier). However, this is not the only decision you need to make.
In general, most of the services in a microservices architecture are private and not made available for public consumption. However, you may want to expose some of the services as public or partner APIs. While each microservice focuses on one specific task, you may decide to provide a public API that exposes multiple capabilities. You could choose to take numerous microservices and expose them as one mega public API. You’ll need to decide on an API strategy, one that provides developers a good experience when consuming your APIs. You also need to secure every part of your application, especially your APIs and microservices.
Another choice you need to make is whether to include API gateways in your microservices architecture. An API gateway allows you to hide a group of microservices behind one entry point. One of the key benefits of an API gateway is security; it provides advanced security features such as API user authentication, authorization, and data encryption. If you only want to add basic security for a small set of APIs, you could choose to use API Proxies instead of gateways. But if you expose many of your microservices as public or partner APIs, an API gateway would be a better choice. Clients making API calls would not connect directly to your microservices and would instead connect with the API gateway.
Once you’ve figured out your strategy for the application architecture, you can start designing your microservices and building your apps. Here are four microservices best practices you should follow:
Building a microservices architecture means that you need to design and deploy dozens, hundreds, perhaps even thousands of APIs. You should follow design-first principles to ensure the success of all the APIs in your architecture. Design-first means that you start with a design stage where you write an API specification that all stakeholders review and offer feedback on.
If you use OpenAPI to create your API specification, you can iron out all the details of your APIs before writing a single line of code. And with Stoplight, you can do nifty things with your OpenAPI files like generate mock servers to test API responses, create style guides, and generate documentation. If you follow design-first principles, you also ensure consistency across your APIs.
Microservices and the APIs associated with them are independent, but you should encourage consistency across your organization. To do that, you need a consistent design style, one that every development team follows.
Creating a style guide is one of the best ways to ensure that microservices and APIs remain consistent across your entire application. You can use OpenAPI to create a style guide to suggest how endpoints, requests, responses, and fields should be implemented. And you can design contracts for your APIs that explain how the APIs will behave. You could also use a linting tool like Spectral to enforce the style guide by linting your OpenAPI documents.
With OpenAPI, you can not only enforce design-first principles and maintain consistency across your application but also create a design process where developers reuse common components.
You can save yourself a lot of time by reusing components across APIs, and to some extent, microservices. Microservices
are autonomous and loosely coupled, but they sometimes share the same objects. With OpenAPI, you can define reusable
components in one place and reuse object definitions across your APIs. For example, you could describe a
object as a single parameter, one that developers can reference and reuse for each API they design.
Today, you can find many tools that allow you to automate much of the API design process. For example, you can use Stoplight to automatically generate documentation and mock servers from your OpenAPI files. You can also use Stoplight to create style guides and then automatically run API style checks against Spectral rules. Automating design processes not only saves you time but also improves the accuracy and quality of your API and microservices designs.
You have a lot to consider if you’re thinking about building an application with microservices. And the best practices we’ve highlighted are only the beginning. Additional microservices best practices you should consider following include:
- Maintaining a central repository for your APIs and microservices.
- Practicing continuous integration and delivery (CI/CD).
- Monitoring and visualizing your architecture.
- Implementing automated service discovery.
Ready to get started with microservices? Then sign up for a free account to see how Stoplight can help you follow microservices best practices and build consistent, high-quality APIs.