In today's fast-paced software development landscape, building scalable and maintainable applications has become increasingly challenging. One of the most effective ways to tackle these challenges is by adopting a microservices architecture. This architectural pattern involves breaking down a monolithic application into smaller, independent services that communicate with each other over well-defined APIs.
Microservices architecture is based on the principle of decomposing an application into distinct services, each responsible for a specific business capability. These services are loosely coupled and can be developed, deployed, and scaled independently. This approach offers several advantages:
Let's explore a practical example of how microservices architecture can be implemented using Docker and Kubernetes.
Suppose we have an e-commerce application with two main services: orders and products.
The orders service is responsible for handling order-related operations such as creating, updating, and retrieving orders.
// src/orders/index.js
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
let orders = [];
app.post('/orders', (req, res) => {
const order = req.body;
orders.push(order);
res.status(201).send(order);
});
app.get('/orders', (req, res) => {
res.send(orders);
});
app.listen(port, () => {
console.log(`Orders service running on port ${port}`);
});
The products service manages product information.
// src/products/index.js
const express = require('express');
const app = express();
const port = 4000;
app.use(express.json());
let products = [
{ id: 1, name: 'Laptop', price: 999 },
{ id: 2, name: 'Smartphone', price: 499 }
];
app.get('/products', (req, res) => {
res.send(products);
});
app.listen(port, () => {
console.log(`Products service running on port ${port}`);
});
Create a Dockerfile for each service.
# src/orders/Dockerfile
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
# src/products/Dockerfile
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 4000
CMD ["node", "index.js"]
Use Docker Compose to define and run multi-container Docker applications.
# docker-compose.yml
version: '3'
services:
orders:
build: ./src/orders
ports:
- "3000:3000"
products:
build: ./src/products
ports:
- "4000:4000"
Start the services using Docker Compose.
$ docker-compose up --build
You should see output indicating that both services are running:
Creating network "microservices_default" with the default driver
Building orders
Step 1/8 : FROM node:14
...
Successfully built abcdef
Successfully tagged microservices_orders:latest
Building products
Step 1/8 : FROM node:14
...
Successfully built ghijkl
Successfully tagged microservices_products:latest
Creating microservices_orders_1 ... done
Creating microservices_products_1 ... done
You can test the services using curl or any API testing tool.
$ curl -X POST http://localhost:3000/orders -H "Content-Type: application/json" -d '{"id": 1, "product_id": 1, "quantity": 2}'
Response:
{"id":1,"product_id":1,"quantity":2}
#### Testing Products Service
```Terminal
$ curl http://localhost:4000/products
Response:
[{"id":1,"name":"Laptop","price":999},{"id":2,"name":"Smartphone","price":499}]