Not so long ago, the technology used to build a website was quite simple.
But now, things are getting a bit more complex. You have all these new techniques and technology you need to keep track of. While they might be confusing at first, learning about them can help make us more productive developers.
One of these concepts we hear a lot about nowadays is the microservice architecture. It caused quite a stir, especially recently, because it's not usually explained well...
Even experienced developers have no idea what microservices are, and that's alright. Usually, when asked about what they think microservices are, most web developers are going to say something like:
Doesn't that have something to do with APIs?
The answer is kind of.
In the Jamstack world, we often talk about them as the same thing, but really they're complementary concepts. Learning about each idea's details can help us, especially when we only need one between APIs vs. microservices.
Let's explore these two concepts. We'll start with the dictionary definitions, but don't worry. I'll move past the janky jargon and get to the meat of it in a bit.
What are APIs vs. microservices?
API stands for Application Programming Interface. According to Wikipedia, an API "defines interactions between multiple software applications. It defines the kinds of calls or requests that can be made, how to make them, the data formats that should be used, the conventions to follow, etc." In the web development world, we most often use APIs that can be accessed through the Internet.
Microservices are, according to microservices.io, pieces of "an architectural style that structures an application as a collection of services that are highly maintainable and testable, loosely coupled, independently deployable, organized around business capabilities, [and] owned by a small team."
These definitions might seem a bit obtuse, so here's how I would define them:
API stands for Application Programming Interface. APIs define how two pieces of software can connect and talk to each other. If your application were a big company, your API's job would be to keep in touch with external parties (customers or company partners, for example). Most APIs are organized around some standard, like REST or GraphQL, so that everybody knows how to use them.
Microservices are pieces of software (often just isolated functions) that do a single, tiny, independent part of a bigger application. If your application were a big company, each employee would be a microservice, each playing their own specific and small role, working alongside but independently from their coworkers. This lets you make changes to individual microservices without affecting the rest of the application. In a big company replacing or retasking one employee in a large team would probably not affect the rest of the company all that much.
It's the evolution of the monolith architecture. Instead of having one block composing the whole application, every component is divided into smaller building blocks.
Put like that, does it make a bit more sense how they're different and how they can work together?
What APIs and microservices actually means IRL
Let's dive into a more practical use case to help you understand furthermore.
Say I've got this completely original payment processor service that I'm calling Tripe (you know, because it's a silly idea, not because I got inspired by any existing company in particular 😉).
There's a ton of little bits of functionality that this application is going to need. Here are some off the top of my head:
Reading from the database
Inserting into or updating the database
Creating invoice PDFs
Contacting the banks
Scheduling a recurring task for subscriptions
Running an actual transaction
All these little pieces of functionality are given their own functions and are all maintained separately. Boom—that's the microservice architecture in a nutshell. All of those individual tasks are microservices. That makes debugging way easier, too, since you can narrow down the problem to a single function almost immediately. And that's awesome if you're like me and hate debugging:
Let's go further with this. Tripe will probably let their users trigger some of these functions, right? Creating invoices, customers profile, subscriptions, charges, and returns are five actions the user can start, and all of them would use some of the microservices mentioned above. So the solution here would be to create five new microservices, one for each of the new actions we're exposing to the outside world.
For example, the new invoicing microservice would call the microservice reading the database, then the one that makes the PDFs, and then the one sending emails. You could think of it in terms of that analogy I gave earlier about the big company; you could have some employees whose whole job is to collect work done by their coworkers to present to people outside the company. Essentially we're creating a set of microservices that collect work done by other microservices and deliver it to users across the Internet. They only exist to interface between your application and the outside world via programmed HTTP requests.
Sound familiar? Well, it's because that's an API!
Quick sidenote: An API is technically how any two programs (including microservices themselves) communicate, but in web development, we usually mean an HTTP-facing API. An API follows a protocol like REST or GraphQL to expose data and functionality to the wider Internet. When I talk about an API in this article, that's what I'm referring to, though it's useful to know that the definition is pretty wide.
Those five microservices let users directly access Tripe's API. Not every microservice has to be part of an API, just like how not every employee needs to be part of the team communicating with customers. Many employees just do internal tasks and help out the customer-facing workers, just like how many microservices only do internal tasks or help out the API functions. There are also many ways to make an API without using microservices, so these technologies are more complementary than competing.
Let's make this more visual with the helping hand of a diagram!
Tripe's architecture would look something like this:
This looks a little complex on the surface, but it's a payment processor, after all. I wouldn't really be comfortable giving my credit card information to anything simpler than this...
Let's go through the columns one by one. On the far left, we have Tripe's users. They only have access to the microservices in the External API column. Combined, the endpoints in the second column (External API) make up the API. They're the only microservices with a defined way to talk to the users (through specific JSON objects set by the API docs, for example). They individually accomplish tasks independently and use some other microservices (in the Business Logic column) to do tasks users aren't allowed to trigger directly. Most business logic functions also call each other, demonstrating that the whole Tripe application is broken down into its tiniest, reusable, isolated, independent pieces.
Building your application with microservices reduces complexity and makes maintenance a lot easier because you can edit these little pieces individually. It's like building a site out of Legos: if you don't like one of them, you can just replace it and leave the rest of the site intact. That means your technical debt goes down to almost nothing, and if you keep with this approach, you'll never run into one of those lose-lose architecture dilemmas that we all hate.
Microservices and APIs real-world applications
Our Tripe graph might look pretty complex because of all the lines, but it was relatively simple when matched up against the same graph for bigger companies like Amazon or Netflix:
The structure starts to get a bit unwieldy to look at, but it's far easier to work with. The article where the image is taking from jokes that the Amazon microservice node graph "looks almost like a Death Star, but is way more powerful."
When you think about it, this architecture makes perfect sense for big companies like Amazon and Netflix. Their developers don't have to edit the entire codebase or redeploy the entire site when they want to make an update. Netflix's engineers, for example, are improving their product 24/7. Imagine if they had to take down the site for just a moment whenever they wanted an internal feature added. Netflix would be down constantly; bye-bye binge-watching! 😧
Instead, they only have to work with one manageable chunk of code at a time, just one of the dots on that graph.
In contrast, think about how few of the nodes on Netflix’s graph of microservices are actually meant to communicate with the outside world. Netflix has been revising their API lately so I couldn’t figure out exactly how many of the nodes are facing outward. However, it’s still quite a small amount compared to the number of microservices they actually use internally. Take this image, for example:
Here's the accompanying explanation:
Suppose a user clicks the "play" button for Stranger Things Episode 1 on their mobile phone. For playback to begin, the mobile phone sends a "play" request to the API. The API, in turn, calls several microservices under the hood. Some of these calls can be made in parallel because they don’t depend on each other. Others have to be sequenced in a specific order. The API contains all the logic to sequence and parallelize the calls as necessary. The device, in turn, doesn’t need to know anything about the orchestration that goes on under the hood when the customer clicks "play".
Interesting, right? I want to highlight one phrase in particular: "The API contains all the logic to sequence and parallelize the calls as necessary." This means that the client (person watching Netflix) called the API endpoint when they pressed the "play" button, which is, in itself, a microservice.
Side note: as I understand it, the API Netflix refers to here isn't available to the public. Remember, an API is just a defined way for "two pieces of software to connect and talk to each other". Those "two pieces of software" are, in this case, Netflix's backend and Netflix's frontend. It's still an API even if you and I can't use it over the Internet because that interaction between the frontend and the backend is given a structure and rules to follow. This is an important note to remember because it means that you've probably created more APIs than you realize in your career. Anytime we internally connect two services and give them a way to talk to one another, we're making one. We should be cognizant of that because it gives us a chance to think through our architecture before it gets out of hand.
TLDR; They're complimentary.
What's the conclusion? APIs can be made up, wholly or partially, out of microservices. Microservices can be used for a lot more, though. The original definition (the really wordy, nerdy one) called microservices pieces of "an architectural style". The whole application, business logic and all, can be broken down into tiny, reusable, single-purpose chunks of code, and that's the microservice architecture.
Here's a Venn diagram if you'd like another way to visualize it. As you can see, microservices can be an API (the overlapping of the circles), but APIs aren't necessarily a microservice.
APIs and microservices are now massive parts of the modern web development process. We can't move forward without them. So if you're making your way past the traditional monolithic web architecture and/or want to learn more about how these newer technologies work together, here are some more links for additional education:
If you've got any other questions, feel free to reach out to me on Twitter or in the comments below. I'd love to hear from you!
Liked this article? Hit the share buttons below. 👇