04-Mar-2021| Best Practices |9 min read

When it comes to conversations around application architecture or working with integrations between applications, you’ve likely heard a couple terms pop up a few times: microservice and APIs.

You might also have run across the common misconception that microservices are just a way to implement APIs so they can communicate with each other. As you’ll see in this article, there are alternative ways to architect our microservice applications.

Let’s explore the concepts of microservices and APIs individually—what they are and how they’re used—and then I’ll show you how to combine both microservices and APIs into a more robust architecture.

What Are APIs?

APIs, or application programming interfaces, are what allow an application to communicate with other applications. Strictly speaking, an API is a group of protocols and standards that define how two applications share and modify each other’s data.

The definition for API has evolved and expanded over time. The term first originated to describe an interface meant only for end-user-facing programs, known as application programs. But API has come to mean something much broader. The term includes hardware interfaces and, of course, web APIs. In fact, web API is the most common application of the term nowadays.

Web APIs

If you’re using any web application today, you use APIs. They’re what enable the software integrations, allowing for many different systems to talk to each other (B2B communication). From banking and online shopping to social media and online streaming, APIs are powering most of our digital lives.

Now, APIs usually send and receive data through HTTP requests. There are several different types of protocols and API styles, like:

  • REST
  • SOAP
  • GraphQL
  • gRPC

The main difference between each resides in the architecture and, in cases like gRPC, in the communication protocol. Let’s take a closer look at one of the oldest and most common types of API: RESTful APIs.

RESTful APIs

The term REST, or Representation State Transfer, was defined by Roy Fielding in his 2000 Ph.D. dissertation “Architectural Styles and the Design of Network-based Software Architectures.” Fielding outlined six architectural constraints required to define a RESTful system:

  1. Client-Server Architecture
  2. Stateless
  3. Cacheable
  4. Uniform Interface
  5. Layered System
  6. Code on Demand

For an API to be RESTful, it must include these aspects:

  • A base URI, such as https://api.example.com
  • Use of semantic HTTP methods (GET, PUT, POST, and DELETE)
  • Media type definition for state transition of data elements

For a real-life example, think of shopping online. When you’re ready to check out, you see that the store gives you a couple of options to estimate shipping, commonly USPS, FedEx, or UPS.

Since each one of those shipping carriers is a separate company with different rates, the online store will make an API call with the contents of your shopping cart (weight, volumetric size) and retrieve the available rates for you to select during checkout. Once your order is placed and ready to be fulfilled, the store might make another API call to create the final shipment with the shipping vendor.

With APIs, applications can offer robust functionality without the need to implement everything from scratch. Other examples of this include using your social media credentials for account creation or login, buying online tickets, or even ordering a ride-share.

External and Internal APIs

APIs can be classified into two different categories: external and internal. The examples I’ve covered up to this point have been external, meaning APIs for third-party software developers and external use.

That said, APIs don’t have to be publicly available. Internal APIs are used for communication between internal applications, for example, internal microservices. With that in mind, let’s take a look at microservices next.

What Are Microservices?

Microservices are:

Microservice architecture—a variant of the service-oriented architecture (SOA) structural style—arranges an application as a collection of loosely coupled services. In a microservices architecture, services are fine-grained, and the protocols are lightweight.

Microservices are a style of software architecture used to divide different application functions into smaller “services.” These services are:

  • Highly maintainable and testable
  • Loosely coupled
  • Independently deployable
  • Organized around business logic

Microservice architecture is used to enable rapid, frequent, and reliable delivery of large and complex applications. The granularity of these services might vary greatly from a couple of services with large boundaries to hundreds of smaller services with particular functions, in the case of some larger companies.

To illustrate how a microservice architecture behaves in action, let’s take a step back and compare two different architectures for a flight booking app: monolith vs microservice.

Monolith

According to Wikipedia, a monolith is:

A monolithic application is self-contained and independent from other computing applications. The design philosophy is that the application is responsible not just for a particular task but can perform every step needed to complete a particular function.

In essence, a monolith is a single application that contains all the elements and components of an application or service, from the presentation layer and business logic all the way down to the database communication.

Sample monolith application

As you can see, our monolith is responsible for everything, including exposing an external API for third parties.

Monoliths are not necessarily bad or obsolete, and in specific scenarios, like a proof of concept or a simple web service, it might make sense to use a monolith. But as soon as our application starts to grow in responsibilities and scope, it makes sense to move to a microservice architecture.

Let’s take a look at the same application but this time using a microservice-based architecture:

Sample microservice application

There are a few key differences from our monolith approach:

  • We have broken down the business logic into different and separate services.
  • The flight-booking service doesn’t have any dependencies with the database nor the frontend.
  • Each service has its own API, and the other services use that API to communicate with each other.

Microservices vs. APIs

Before moving forward, let’s do a quick recap of what we’ve learned so far:

  • An API is the part of an application that allows other applications to request and send data.
  • There are many different styles of APIs and protocols.
  • Microservices is a software architecture style that separates an application into smaller boundaries.
  • Microservices can communicate to each other through APIs.

That last point is often where confusion or misunderstanding can set in. Note that the APIs implemented by each service don’t have to be RESTful, or even use HTTP for that matter; there are more efficient and faster alternatives.

One of these alternatives is gRPC, a universal RPC framework developed by Google. gRPC is a high-performance, open-source, universal RPC framework that can run in any environment.

Microservices could also communicate using the Event/Message system, which is entirely asynchronous and doesn’t need to wait for a response, thus avoiding coupling between our services.

For each one of these communication methods, there are a few pros and cons to consider.

REST

Pros:

  • Easy to understand and implement without previous experience
  • Requests and responses are usually human-readable (JSON)
  • Widely adopted standard with native support from many frameworks and libraries

Cons:

  • No standardized way to do things like versioning, search, and logical breakdown of endpoints
  • Poor support and applicability for streaming
  • No standard schema for endpoints

gRPC

Pros:

  • Great speed due to the binary format
  • Great support for streaming data bidirectionally
  • Supported by many languages (Java, Python, Scala) and allows for cross-language communication

Cons:

  • Higher learning curve, and additional knowledge required (eg, Protobuf)
  • Payloads are not human-readable and require additional tools for debugging

Event/Message Driven

Pros:

  • Fully asynchronous communication between services
  • Supports many different message formats: JSON, protobuf, AVRO
  • Can facilitate service decoupling

Cons:

  • Application design using messages may be more complicated
  • Additional message queue like Kafka, RabbitMQ or Pulsar is needed
  • The asynchronous nature might make it harder to debug

Making It All Work

Those are a lot of options, but here’s the best part: they are not mutually exclusive. They can all work together in your application’s service architecture.

Let’s take a final pass on our application diagram and apply what we’ve learned so far:

Microservices application with more efficient communication

There are a few changes from our previous microservice diagram:

  • We moved our REST API implementation to a fourth service.
  • REST is now only used for communicating with our frontend app and any external developer or services.
  • All the services are internally communicating using gRPC for better performance and handling large volumes of traffic.
  • Additionally, the booking service and billing service are communicating using an Event/Message system for operations that can be asynchronous.

As you can see, it’s possible to combine each communication style to leverage their benefits and strengths.

Conclusions

So now that we’ve gone over the definitions of microservices and APIs, hopefully you’re more familiar with the connection between them.

APIs allow our applications to send and receive data with other applications or even external developers; there are many different communication protocols and styles of APIs. Microservices are an architectural pattern that allows us to organize our application into smaller services. By segmenting our application into smaller services each with a single responsibility, we can quickly scale, maintain, and develop complex systems.

Typically, microservices and APIs are applied together. For example, each microservice could contain an API. Through the API, the microservices will communicate with each other. However, this isn’t strictly necessary—services could use different communication strategies, like a message queue. Similarly, APIs don’t need to be implemented through microservices; for example, they could be part of a monolith application.

Knowing the difference and understanding the synergy between both concepts should allow you to leverage both efficiently when architecting and building applications. Companies like Netflix, Spotify, and Shopify have adopted this approach already.

Allan MacGregor is a software engineer and entrepreneur based in Toronto, Canada. He has fifteen years of professional experience building innovative solutions both inside and out of the e-commerce space.

All the Lightrun News That’s Fit to Print(f)!

Get the latest posts, news,
feature releases, updates, and articles directly to your inbox