Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 29, 2022 01:07 pm GMT

Microservices with express.js and rabbitmq

This article is to simplify and do a step by step tutorial to make a microservices app

In this tutorial, I'm going to use

  1. Node.js as runtime environment.
  2. Typescript instead of Javascript for better development experience.
  3. Express.js for the backend.
  4. Rabbitmq as a message broker.

To find the final code, you can find it on Github

Before typing code, why Microservices?

Let's say we have to services, In a Monolithic Architecture you would have only one repository and all your services interact through the same instance, if any service caused the instance to crash, the whole application will crash.

While in a Microservices Architecture each will work a whole unit and on interacting with other services, it uses message brokers like Rabbitmq to send a message to other services.

Now consider a warehouse service (consumer) that really depends on an order service (publisher), where whenever an order is submitted the warehouse is notified and starts the shipping process, in this architecture, if the order service caused a crash, the warehouse won't be affected and will keep working, even if the warehouse service was out when an order is submitted, the message broker will keep the message and on the startup of the warehouse service, it will assert that in knows about this message.

How to implement it?

First, the folder structure, consider making a directory called online-ordering-microservices, with two folders inside [order, warehouse]

Folder structure

The .gitingore file to ignore the node_modules inside each service

Second, setup rabbitmq as a message broker

Run docker container run --name rabbitmq --detach -p 5672:5672 rabbitmq

This will run a container from the image rabbitmq, on a detached mode and expose the port 5672 which is the default port for rabbitmq and give this container a name rabbitmq

Third, setup each service.

Run npm install express @types/express amqplib @types/amqplib to install the necessary dependencies.

order/index.ts

import amqplib, { Channel, Connection } from 'amqplib'import express, { Request, Response } from 'express'const app = express()// parse the request bodyapp.use(express.json())// port where the service will runconst PORT = 9005// rabbitmq to be global variableslet channel: Channel, connection: Connectionconnect()// connect to rabbitmqasync function connect() {  try {      // rabbitmq default port is 5672    const amqpServer = 'amqp://localhost:5672'    connection = await amqplib.connect(amqpServer)    channel = await connection.createChannel()    // make sure that the order channel is created, if not this statement will create it    await channel.assertQueue('order')  } catch (error) {    console.log(error)  }}app.post('/orders', (req: Request, res: Response) => {  const data = req.body  // send a message to all the services connected to 'order' queue, add the date to differentiate between them  channel.sendToQueue(    'order',    Buffer.from(      JSON.stringify({        ...data,        date: new Date(),      }),    ),  )  res.send('Order submitted')})app.get('*', (req: Request, res: Response) => {  res.status(404).send('Not found')})app.listen(PORT, () => {  console.log(`Server running on ${PORT}`)})

warehouse/index.ts

import amqplib, { Channel, Connection } from 'amqplib'import express, { Request, Response } from 'express'const app = express()// parse the request bodyapp.use(express.json())// port where the service will runconst PORT = 9005// rabbitmq to be global variableslet channel: Channel, connection: Connectionconnect()async function connect() {  try {    const amqpServer = 'amqp://localhost:5672'    connection = await amqplib.connect(amqpServer)    channel = await connection.createChannel()    // consume all the orders that are not acknowledged    await channel.consume('order', (data) => {      console.log(`Received ${Buffer.from(data!.content)}`)      channel.ack(data!);    })  } catch (error) {    console.log(error)  }}app.get('*', (req: Request, res: Response) => {  res.status(404).send('Not found')})app.listen(PORT, () => {  console.log(`Server running on ${PORT}`)})

Now, if you run both apps and made a post request to http://localhost:9005/orders, you will get a message in the warehouse service, more importantly, if you made a request while the warehouse service is not running and started the warehouse service, it will receive that message, and actually will keep receiving it untill it acknowledges it.

I hope you liked this tutorial, and see you in another ones.


Original Link: https://dev.to/omardiaa48/microservices-with-expressjs-and-rabbitmq-34dk

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To