Before writing a single line of code, it pays to be clear about what we mean when we say "microservices". The term gets thrown around so loosely that it is often applied to systems that are not microservices at all (a monolith chopped into several processes, for instance) or confused with specific technologies such as Docker or Kubernetes. In this first lesson we will settle on a working definition, go through the characteristics that genuinely set a microservice apart, understand where this way of building software comes from, and agree on the vocabulary we will use throughout the course. We will close with a first, deliberately simple look at what TechCorp's online store would look like split into services.

This lesson is the conceptual foundation the rest of the course rests on: we will not discuss here whether microservices are good or bad (that comes in the next lesson), nor how they compare in detail with a monolith, nor when it makes sense to adopt them. Here we only answer the question "what exactly is a microservice?".

Contents

  1. What a microservice is (and what it is not)
  2. Defining characteristics
  3. A brief history: from SOA to microservices
  4. Basic vocabulary for the course
  5. First look: TechCorp's store split into services
  6. Common mistakes and tips
  7. Exercises
  8. Conclusion

  1. What a microservice is (and what it is not)

A working definition, precise enough to carry us through the whole course:

A microservice is an autonomous software component that implements one well-delimited business capability, is deployed independently, owns its own data, and communicates with the rest of the system only through well-defined interfaces (APIs or messages).

And a microservices architecture is a system made up of several such components collaborating to deliver a complete application.

Notice that the definition mentions no technology. It does not say "containers", or "Kubernetes", or "REST", or "Node.js". All of those tools will show up in the course because they make the work enormously easier, but they are not what defines a microservice. You can have microservices without containers, and you can have containers without microservices.

What a microservice is NOT

Knowing what a microservice is not matters just as much as knowing what it is. The following situations are frequently mistaken for microservices:

Situation Why it is not a microservice
A monolith running as several replicas behind a load balancer It is still a single deployment unit; every replica is the same code and shares the same database.
Several applications that read from and write to the same database There is no data autonomy: a schema change affects all of them at once. That is a "distributed monolith".
A module or package inside a project (for example, the orders/ folder of the monolith) A module is a good organizational practice, but it is deployed together with everything else.
An isolated serverless function that does a single technical thing (resizing an image) It may be part of a microservice, but on its own it does not model a complete business capability.
A "shared" service that everyone depends on in order to work (for example, a "common entities" service) It breaks autonomy: if it goes down, everything goes down; if it changes, everyone has to coordinate.

A practical rule of thumb: if you cannot deploy the component without coordinating with another team, or if you cannot change its data schema without warning anyone else, you probably do not have a microservice but a piece of something bigger.

The "micro" prefix

"Micro" is not about lines of code. There is no magic number ("under 500 lines"). It means the service has a small, well-defined functional scope: it does one business thing and does it completely. A payments service can run to thousands of lines and still be a perfectly reasonable microservice; what matters is that its responsibility is clear and that you can reason about it without having to understand the whole system.

  1. Defining characteristics

The following seven characteristics are what, taken together, set a microservice apart. When you evaluate a system, ask yourself how many of them it actually meets.

2.1 Autonomy

The service can work, change and evolve on its own. It has its own code, its own lifecycle and its own internal decisions. Autonomy is the root characteristic from which almost all the others derive.

2.2 Independent deployment

Each service is built, tested and put into production separately, with no need to deploy the rest of the system. If the Payments team fixes a bug, it ships a new version of payments-service and nobody else even notices. This requires the interfaces between services to be stable and versioned (we will cover this in module 3).

2.3 Modeled around business capabilities

Services are split along business lines, not technical layers. At TechCorp we talk about "catalog", "orders" or "payments", not about a "database service", a "logic service" and a "UI service". A service contains everything it needs to fulfill its capability: its API, its logic and its storage.

This is an important difference from layered architectures that separated "the data back end" from "the business back end": there, a new feature meant touching every layer and coordinating every team.

2.4 Decentralized data

Each service is the exclusive owner of its data. Nobody else reads from or writes to its database directly; if another service needs that information, it asks for it through the API or receives it through events. At TechCorp, the catalog will live in MongoDB and orders in their own PostgreSQL, and orders-service will never run a SELECT against the products collection.

This characteristic is the most expensive one to satisfy when you are coming from a monolith, and we will devote a full lesson to it in module 2.

2.5 Communication through lightweight APIs

Services talk to each other over the network using simple, well-known protocols: usually HTTP/REST for synchronous requests and messaging (RabbitMQ in our case) for asynchronous events. The intelligence lives in the services, not in the communication infrastructure. This is usually summed up as smart endpoints, dumb pipes.

2.6 Team ownership

A service belongs to one team that designs, builds, deploys and operates it ("you build it, you run it"). That team is responsible for keeping it working in production. At TechCorp, Luis's team will own orders-service end to end.

2.7 Automation

With many small services, deploying by hand is simply not viable. Microservices presuppose continuous integration and continuous deployment, infrastructure as code, automated tests and monitoring. Without automation, the architecture does not scale operationally.

Visual summary

mindmap
  root((Microservice))
    Autonomy
      Own code
      Own lifecycle
    Independent deployment
      No coordination with others
    Business capability
      Catalog, Orders, Payments...
    Decentralized data
      One DB per service
    Lightweight APIs
      REST
      Events
    Team ownership
      You build it, you run it
    Automation
      CI/CD
      Observability

  1. A brief history: from SOA to microservices

Microservices did not appear out of nowhere. They are the evolution of earlier ideas, corrected by experience.

The age of the monolith and SOA

In the 2000s, enterprise applications were mostly built as monoliths: one large application deployed on an application server. As they grew, they became hard to maintain and hard to scale.

SOA (Service-Oriented Architecture) emerged in response. The idea was sound: split the system into reusable services. But the usual implementation had problems:

  • Services communicated through an ESB (Enterprise Service Bus), a central component that routed, transformed and orchestrated messages. The ESB ended up being a technical and organizational bottleneck: all the intelligence lived there.
  • The protocols (SOAP, WS-*) were heavy and verbose.
  • Services tended to share databases and to be deployed in a coordinated fashion.
  • Governance was highly centralized: committees decided which services existed and what they looked like.

The birth of microservices

Around 2011-2014, companies such as Netflix, Amazon and SoundCloud began to describe publicly how they had split their systems into very small, autonomous services, each with its own team and communicating over HTTP. In 2014, James Lewis and Martin Fowler published the article that popularized the term and pinned down the characteristics we saw in the previous section.

Several factors made this approach feasible at that moment:

Factor What it contributed
Public cloud (AWS and the like) Create and destroy servers in minutes, paying per use.
Containers (Docker, 2013) Package each service with its dependencies in a reproducible way.
Orchestrators (Kubernetes, 2014) Manage hundreds of containers automatically.
DevOps culture and continuous delivery Automate build, test and deployment.
REST/JSON APIs Lightweight, universal communication versus SOAP/XML.
Domain-Driven Design Tools for dividing the business into well-delimited contexts.

In a sense, microservices are "SOA done right": they keep the idea of services but drop the centralized ESB, the heavy protocols, the shared database and the rigid governance.

timeline
    title Evolution toward microservices
    2000-2005 : Monoliths on application servers
    2005-2010 : SOA with ESB, SOAP and centralized governance
    2011-2013 : Netflix, Amazon and others publish their experiences
              : Docker (2013)
    2014      : Lewis and Fowler's article
              : Kubernetes (2014)
    2015-today : Widespread adoption, service mesh, observability

  1. Basic vocabulary for the course

We will use these terms constantly throughout the course. Here we give only brief definitions; each one is developed in its corresponding lesson.

Term Brief definition Example at TechCorp
Service Autonomous component that implements a business capability and is deployed separately. orders-service
Instance A running process of a service. A service may have several identical instances to spread load. Three replicas of catalog-service on Black Friday
API Set of operations a service exposes to others (usually over HTTP). POST /orders, GET /orders/{id}
Contract Formal, stable description of an API or a message: routes, fields, types, errors. It is what lets different services evolve without breaking each other. The OpenAPI specification of orders-service
Event Message announcing that something has happened in a service, published so that others can react without coupling to it. order.created, payment.confirmed
Message broker Infrastructure that receives events from producers and delivers them to consumers. RabbitMQ
Gateway (API Gateway) Single entry point for external clients, which routes each request to the right service and centralizes cross-cutting concerns (authentication, rate limits). The gateway on port 8080
Orchestrator Platform that deploys, scales, restarts and connects service instances across a cluster of machines. Kubernetes
Container Executable package that includes the service and all its dependencies, isolated from the rest of the machine. Docker image of payments-service
Observability The ability to understand what is happening inside the system from its outputs: metrics, logs and traces. Prometheus, Grafana, Loki, Jaeger
Distributed trace Record of the full path of a request across several services. Seeing that "create order" took 800 ms and 600 ms of that was in payments

There is no need to memorize the table: we will keep using and extending it. What matters is that, when one of these terms shows up, you know which family it belongs to.

  1. First look: TechCorp's store split into services

TechCorp is the fictional company that will accompany us throughout the course. It runs an online store that today is a single Node.js monolith built with Express and a single PostgreSQL database. We will introduce it in detail in lesson 01-05; for now, let's look only at what the destination would look like: the store decomposed into services.

flowchart LR
    Customer[Browser / Mobile app]
    GW[API Gateway<br/>:8080]

    subgraph TechCorp services
        CUS[customers-service<br/>:3004]
        CAT[catalog-service<br/>:3001]
        INV[inventory-service<br/>:3006]
        ORD[orders-service<br/>:3002]
        PAY[payments-service<br/>:3003]
        NOT[notifications-service<br/>:3005]
    end

    MQ[(RabbitMQ<br/>events)]

    Customer --> GW
    GW --> CUS
    GW --> CAT
    GW --> ORD
    ORD -. publishes order.created .-> MQ
    MQ -. consumes .-> INV
    MQ -. consumes .-> PAY
    MQ -. consumes .-> NOT

Notice several things in the diagram:

  • The customer does not talk to the services directly, but to the gateway. The internal services do not even need to be reachable from the Internet.
  • Each service maps to a business capability: customers, catalog, inventory, orders, payments, notifications. There is no "database service" or "logic service".
  • There are two communication styles: solid arrows (synchronous requests, HTTP) and dashed arrows (asynchronous events through RabbitMQ). When an order is created, orders-service does not call inventory, payments and notifications one by one: it publishes an event and each interested party reacts.
  • Each service has its own port because it is an independent process. In module 4 we will actually bring them up.

What a service exposes: two example endpoints

To make the idea of an "API" concrete, this is what a minimal slice of what orders-service offers to the rest of the world would look like (in pseudo-HTTP, not implemented).

Creating an order:

POST /orders
Content-Type: application/json

{
  "customerId": "c-1024",
  "lines": [
    { "productId": "p-501", "quantity": 2 },
    { "productId": "p-777", "quantity": 1 }
  ]
}

--- Response ---
201 Created
Location: /orders/ord-88213

{
  "orderId": "ord-88213",
  "status": "PENDING",
  "total": 149.90
}

Fetching an order:

GET /orders/ord-88213

--- Response ---
200 OK

{
  "orderId": "ord-88213",
  "customerId": "c-1024",
  "status": "CONFIRMED",
  "lines": [
    { "productId": "p-501", "quantity": 2, "unitPrice": 49.95 },
    { "productId": "p-777", "quantity": 1, "unitPrice": 50.00 }
  ],
  "total": 149.90
}

Notice what does not appear in these examples: there is nothing about how the order is stored, which database the service uses, or how the total is computed. Whoever consumes the API only knows the contract: the route, the input format and the output format. That opacity is precisely what lets Luis's team change the guts of orders-service whenever it wants without breaking anyone.

It is also worth noting that the order is created with status PENDING and later shows up as CONFIRMED. In between, things have happened in other services (reserving stock, charging the customer) that the consumer does not learn about directly. That flow, "a customer places an order", is the running example for the whole course, and we will pick it apart in lesson 01-05.

Common Mistakes and Tips

  • Confusing the tool with the architecture. Using Docker and Kubernetes does not turn a system into microservices. Ask about the seven characteristics, not about the stack.
  • Thinking that "micro" means tiny. Excessively small services (sometimes called nanoservices) multiply communication and operational cost without providing real autonomy. The right size is dictated by the business capability, not by a line limit.
  • Splitting by technical layers. A "data access service" and a "logic service" are not microservices; they are a monolith cut in half that forces you to deploy both at once.
  • Sharing the database "just at the beginning". This is the most common way to end up with a distributed monolith. If two services share tables, in practice they are one.
  • Ignoring the organizational side. Team ownership and automation are not optional details; without them the architecture does not hold up. We will look at this in more detail in lesson 01-04.
  • Tip: whenever you read about a "microservices" system, try to identify what its deployment unit is and who owns each piece of data. Those two questions dismantle most false claims.

Exercises

Exercise 1: Microservice or not?

For each situation, state whether it describes a microservice and justify your answer with at least one of the seven characteristics.

  1. TechCorp deploys its current monolith on four identical servers behind a load balancer.
  2. The Marketing team builds a small independent Python application that manages coupons, with its own database, its own REST API and its own deployment pipeline.
  3. The Orders team extracts the order logic into a separate Node.js process, but that process still reads from and writes to the products and customers tables in the monolith's database directly.

Exercise 2: Vocabulary in context

Match each sentence with the vocabulary term it describes:

  • a) "When a payment is confirmed, a message is published so that whoever needs it can react."
  • b) "On Black Friday we spin up eight copies of the catalog service."
  • c) "All requests from the mobile app come in through the same place, which decides which service to send them to."
  • d) "We document the routes, fields and error codes of the orders API and commit to not breaking them."
  • e) "We can see that the request went through three services and which one the time was lost in."

Exercise 3: Designing a minimal contract

Following the style of the pseudo-HTTP examples in the lesson, write two endpoints that catalog-service could expose: one to fetch a product by its identifier and another to list products filtered by category. Give the method, the route, an example response and the status code. Do not implement anything; the point is only to think about the contract.

Solutions

Exercise 1

  1. No. It is the same monolith replicated. The deployment unit is still one (independent deployment fails) and all replicas share code and database (decentralized data fails).
  2. Yes. It meets autonomy, independent deployment, its own business capability (coupons), its own data and a lightweight API. It also illustrates technological heterogeneity: it can be in Python even though the rest is Node.js.
  3. No (not yet). Although it is a separate process, it accesses data belonging to other areas directly. It is a miniature distributed monolith: any change to products or customers can break this process, and vice versa. To be a microservice it should obtain that information through the catalog and customers APIs or events.

Exercise 2

  • a) Event (and, by extension, message broker).
  • b) Instance (several instances of the same service).
  • c) Gateway (API Gateway).
  • d) Contract.
  • e) Distributed trace (observability).

Exercise 3 (one possible solution)

GET /products/p-501

--- Response ---
200 OK

{
  "productId": "p-501",
  "name": "TC-Pro Wireless Headphones",
  "category": "audio",
  "price": 49.95,
  "active": true
}
GET /products?category=audio&page=1&size=20

--- Response ---
200 OK

{
  "page": 1,
  "total": 87,
  "products": [
    { "productId": "p-501", "name": "TC-Pro Wireless Headphones", "price": 49.95 },
    { "productId": "p-777", "name": "TC-Mini Portable Speaker", "price": 50.00 }
  ]
}

Points to look for: noun-based routes (/products), use of GET for reads, filters in the query string, a paginated response, and a 404 Not Found (not shown) when the product does not exist. Everything about good REST design is developed in lesson 03-01.

Conclusion

In this lesson we established the working definition of a microservice: an autonomous component, focused on one business capability, deployable on its own, owner of its data, and communicating through lightweight interfaces. We saw that the seven characteristics (autonomy, independent deployment, modeling by business capability, decentralized data, lightweight APIs, team ownership and automation) are what set a microservice apart, and that no particular technology defines it. We placed the idea in its historical context, as a correction of the mistakes of classic SOA, and we fixed the vocabulary we will use from here on. Finally, we took a first look at TechCorp's service map and at what it means for a service to "expose an API".

With these foundations in place, the next lesson tackles the question everyone asks next: what do you gain and what do you pay when you adopt this architecture? We will look at the advantages and disadvantages of microservices, illustrated with concrete situations at TechCorp.

Microservices Course

Module 1: Introduction to Microservices

Module 2: Microservice Design

Module 3: Communication between Microservices

Module 4: Implementing Microservices

Module 5: Deployment and Orchestration

Module 6: Monitoring and Maintenance

Module 7: Security in Microservices

Module 8: Case Studies and Practical Examples

© Copyright 2026. All rights reserved