Microservices in JavaScript: Architecture and Practice from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction to Microservice Architecture in JavaScript

Microservice architecture is a software development approach where an application is built as a set of small, independently deployable services. Each service implements a single business function and communicates with others through lightweight protocols (usually HTTP/REST or message queues). JavaScript, specifically the Node.js runtime, is ideal for creating microservices thanks to its asynchronous I/O model, vast package ecosystem (npm), and high development speed.

In this article, we will cover the key aspects of building microservices in JavaScript: from architecture design to container deployment. You will learn how to organize data exchange, ensure fault tolerance, and test a distributed system.



1. Designing Microservice Architecture

The first step is decomposing a monolithic application into services. Each microservice should own its own database (database per service) and be fully autonomous. Consider an example of an online store:

  • Service Users — registration, authentication, profiles.
  • Service Products — product catalog, prices, stock.
  • Service Orders — order creation and processing.
  • Service Payments — integration with payment gateways.
  • Service Notifications — sending email/SMS.

For inter-service communication, we use two approaches: synchronous (REST/gRPC) for requests requiring an immediate response, and asynchronous (message queues) for events that do not require blocking.



2. Creating a Microservice on Node.js with Express

Let's start with a simple microservice for user management. Install Express and a library for working with UUID:

npm init -ynpm install express uuid

Create a file users-service.js:

const express = require('express');const { v4: uuidv4 } = require('uuid');const app = express();app.use(express.json());

const users = [];

// Create userapp.post('/users', (req, res) => { const { name, email } = req.body; const user = { id: uuidv4(), name, email }; users.push(user); res.status(201).json(user);});

// Get list of usersapp.get('/users', (req, res) => { res.json(users);});

// Get user by IDapp.get('/users/:id', (req, res) => { const user = users.find(u => u.id === req.params.id); if (!user) return res.status(404).json({ error: 'User not found' }); res.json(user);});

app.listen(3001, () => console.log('Users service running on port 3001'));

Run the service: node users-service.js. Now you have a working microservice with a REST API. Services for products and orders are created similarly (on ports 3002 and 3003 respectively).



3. Asynchronous Communication via RabbitMQ

For events such as "order created" or "user registered", we use message queues. Install the RabbitMQ client:

npm install amqplib

Create a utility for publishing messages (event-bus.js):

const amqp = require('amqplib');let channel;

async function connect() { const connection = await amqp.connect('amqp://localhost'); channel = await connection.createChannel(); await channel.assertExchange('order_events', 'topic', { durable: true });}

async function publishEvent(routingKey, data) { if (!channel) await connect(); channel.publish('order_events', routingKey, Buffer.from(JSON.stringify(data))); console.log(`Event published: ${routingKey}`);}

module.exports = { publishEvent };

Now in the orders service (orders-service.js), when an order is created, publish

Blogs

Book Recommendations