In this article, we will upgrade the simple “Hello World” application into a real microservice. Let's assume that we want to create a microservice that will manage a list of tasks. Each task in the list should consist of a name and a description. Our microservice will allow us to create, read, update, and delete tasks. You can read the theoretical part, structure, and design of a microservice in the article: Building microservices with Node.js: microservices structure and development challenges
Application or microservice creation
First, let's create a new project called "task-service". Open a terminal and navigate to the folder where we will save our project. Then, in the terminal, type:
mkdir task-service cd task-service npm init -y
This will create a new folder named “task-service” and initialize a new project. The “package.json” file will be automatically created.
Then we install Express and other necessary packages. In the terminal, we enter:
npm install express body-parser mongoose --save
Express will be used to create our API, body-parser to process the input data, and mongoose to connect to the MongoDB database.
In the “task-service” folder, create a new folder “src” where we will store all the files related to our microservice. In this folder, create a file “index.js” and enter the following code:
const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose'); const app = express(); const port = 3000; app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); mongoose.connect('mongodb://localhost/taskDB', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', () => { console.log('Successfully connected to the database'); }); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Server is running on port: ${port}`); });
This code sets up our API, connects Express, body-parser, and mongoose, and connects to the MongoDB database. It also defines the base path “/” which will return the string “Hello World!”.
Microservices database model and schema
Next, we create a file called “task.js” in the “src/models” folder. This file will define the task schema that we will store in our database. The file contains the following code:
const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose'); const app = express(); const port = 3000; app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); mongoose.connect('mongodb://localhost/taskDB', { useNewUrlParser: true }); const db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', () => { console.log('Successfully connected to the database'); }); app.get('/', (req, res) => { res.send('Hello World!'); }); app.listen(port, () => { console.log(`Server is running on port: ${port}`); });
This code defines a schema “taskSchema” which contains two attributes: task name and task description.
This file represents a controller for managing tasks. It defines functions that are executed when certain URLs are called. For example, when a user sends a request to display a list of tasks, the function is triggered. getTasks
Similarly, when creating a new task, the function is used createTask
, and when editing a task updateTask
.
For each function, it is necessary to specify how it will process the received data and what response will be returned. In the case of the function getTasks
all tasks are read from the database and returned in response to the request. In the function createTask
The received data is validated, then the new task is saved in the database and a successful response is returned with data about the created task.
It is important that all communication with the database is done through an interface that is separate from the controller. This way the code is more transparent and easier to modify. Therefore, in the file tasks.js
method used TaskService
, which contains database management functions.
Controller and logic operations of microservices
In addition, the file tasks.js
also defined router
, which determines which URLs are used to call functions in the controller. For example, if a user sends a request to /api/tasks
, the function is triggered getTasks
.
File content tasks.js
could look something like this:
const express = require('express'); const TaskService = require('../services/taskService'); const router = express.Router(); const taskService = new TaskService(); router.get('/', async (req, res) => { try { const tasks = await taskService.getAllTasks(); res.json(tasks); } catch (err) { res.status(500).send(err.message); } }); router.post('/', async (req, res) => { try { const newTask = await taskService.createTask(req.body); res.json(newTask); } catch (err) { res.status(500).send(err.message); } }); router.put('/:id', async (req, res) => { try { const updatedTask = await taskService.updateTask(req.params.id, req.body); res.json(updatedTask); } catch (err) { res.status(500).send(err.message); } }); module.exports = router;
In this case, TaskService is used, which contains functions for working with the database. The file defines three URLs that use three different functions for managing tasks: getAll
, create
and update
.
Function getAll
returns a list of all tasks currently in the database. We do this by TaskService
we call the method getAll
, which uses the function find
from mongoose
to find all tasks in the database. The result is returned in the response to the request as JSON.
Function create
creates a new task in the database. In this function, we read the data sent in the request body and use it to create a new task in the database. We use the function create
from TaskService
, which creates a new task in the database using the method save
from mongoose
The result is returned in the response to the request as JSON.
Function update
update an existing task in the database. In this function, we read the data sent in the request body and use it to update an existing task in the database. We use the function update
from TaskService
, which updates an existing task in the database using the method findByIdAndUpdate
from mongoose
The result is returned in the response to the request as JSON.
These are the basic functions that we need to manage the tasks in this microservice. Using these functions, we can create a simple REST API that we can use to access our data. This microservice could be part of a larger application or we could use it as a standalone service, depending on our needs.
It is important to emphasize that this is just a basic example of using microservices using Node.js, Express, MongoDB, and RabbitMQ. There are many different ways we can use these technologies to create robust and scalable microservices. However, this example provides us with a good starting point to understand the basic concepts and tools we need to create microservices in Node.js.
How to move from the first microservice to a working application?
Once we have our microservice ready and tested, we can continue building the other microservices that will make up our online storeThese microservices may include:
- Microservice for order management.
- Inventory management microservice.
- A microservice for delivery management.
Each of these services will have its own database and interface for communicating with other services. For this, we can use RabbitMQ, which is an open source messaging software within applications.
Additionally, we can also use technologies like Angular, React, and VueJS to develop the front-end interface for our online store. These frameworks allow us to develop fast and interactive user interfaces that will allow our customers to access products and services more easily.
By using microservices, we can improve the scalability and maintainability of our system, as we have each service separate and independent from each other. This allows us to easily update and upgrade individual services without disrupting the entire system.
Conclusion
In conclusion, using microservices is one of the best practices when developing large applications like an online store. Node.js is a great tool for developing microservices because of its efficiency, flexibility, and performance. Using technologies like Express.js, MongoDB, RabbitMQ, we can build robust and scalable microservices that will meet the needs of our online store.