Node.js 9: Впровадження мікросервісів

Вступ

Мікросервіси — це підхід до архітектури, при якому велика програма розбивається на невеликі сервіси, які можуть працювати незалежно один від одного. Кожен сервіс розробляється для виконання однієї конкретної функції та може бути розгорнутий окремо.

Чому варто використовувати мікросервіси?

  1. Масштабованість: Кожен сервіс може масштабуватися незалежно.
  2. Гнучкість: Ви можете використовувати різні технології або мови програмування для кожного сервісу.
  3. Незалежність команд: Кожна команда може розробляти та керувати своїми сервісами.
  4. Ізоляція від збоїв: Збій одного сервісу не впливає на інші.

1. Основи мікросервісів

1.1 Моноліт проти мікросервісів

pic

1.2 Комунікація між сервісами

В архітектурі мікросервісів сервіси комунікують за допомогою:

  1. REST API: Використовують HTTP для комунікації між сервісами.
  2. Message Broker: Використовують посередників повідомлень, таких як RabbitMQ або Kafka, для асинхронної комунікації.

2. Створення додатку на основі мікросервісів з Node.js

2.1 Структура проєкту

Припустимо, ми створюємо додаток для електронної комерції з такими мікросервісами:

  1. Сервіс користувачів: Для аутентифікації та даних користувачів.
  2. Сервіс продуктів: Для управління даними продуктів.
  3. Сервіс замовлень: Для управління замовленнями.

Структура директорії:

ecommerce-microservices/  
├── user-service/  
│ ├── app.js  
│ ├── routes/  
│ │ ├── authRoutes.js  
│ ├── models/  
│ │ ├── userModel.js  
│ ├── package.json  
├── product-service/  
│ ├── app.js  
│ ├── routes/  
│ │ ├── productRoutes.js  
│ ├── models/  
│ │ ├── productModel.js  
│ ├── package.json  
├── order-service/  
│ ├── app.js  
│ ├── routes/  
│ │ ├── orderRoutes.js  
│ ├── models/  
│ │ ├── orderModel.js  
│ ├── package.json

2.2 Створення сервісу користувачів

  1. Ініціалізація проєкту:
mkdir user-service && cd user-service  
npm init -y  
npm install express mongoose bcryptjs jsonwebtoken

2. Налаштування app.js:

const express = require('express');  
const mongoose = require('mongoose');  
const authRoutes = require('./routes/authRoutes');  
const app = express();  

app.use(express.json());  

// Маршрут  
app.use('/auth', authRoutes);  

// Підключення до бази даних  
mongoose  
 .connect('mongodb://localhost:27017/user-service', {  
 useNewUrlParser: true,  
 useUnifiedTopology: true,  
 })  
 .then(() => console.log('Підключено до бази даних User-Service'))  
 .catch((err) => console.error('Не вдалося підключитися до бази даних', err));  

// Запуск сервера  
app.listen(3001, () => {  
 console.log('User-Service працює на http://localhost:3001');  
});

3. Створення моделі користувача: Додайте файл models/userModel.js:

const mongoose = require('mongoose');  
const bcrypt = require('bcryptjs');  

const userSchema = new mongoose.Schema({  
 name: { type: String, required: true },  
 email: { type: String, required: true, unique: true },  
 password: { type: String, required: true },  
});  

userSchema.pre('save', async function (next) {  
 if (!this.isModified('password')) return next();  
 this.password = await bcrypt.hash(this.password, 10);  
 next();  
});  

const User = mongoose.model('User', userSchema);  

module.exports = User;

4.

Створення маршруту для аутентифікації: Додайте файл routes/authRoutes.js:

const express = require('express');  
const User = require('../models/userModel');  
const jwt = require('jsonwebtoken');  
const router = express.Router();  

// Реєстрація користувача  
router.post('/register', async (req, res) => {  
 try {  
 const { name, email, password } = req.body;  
 const user = new User({ name, email, password });  
 await user.save();  
 res.status(201).json({ message: 'Користувача успішно зареєстровано' });  
 } catch (err) {  
 res.status(500).json({ error: err.message });  
 }  
});  

// Логін користувача  
router.post('/login', async (req, res) => {  
 try {  
 const { email, password } = req.body;  
 const user = await User.findOne({ email });  
 if (!user || !(await user.comparePassword(password))) {  
 return res.status(401).json({ message: 'Невірний email або пароль' });  
 }  
 const token = jwt.sign({ id: user._id }, 'secretKey123', { expiresIn: '1h' });  
 res.json({ token });  
 } catch (err) {  
 res.status(500).json({ error: err.message });  
 }  
});  

module.exports = router;

5. Запуск User-Service:

node app.js

2.3 Створення сервісу продуктів

  1. Ініціалізація проєкту:
mkdir product-service && cd product-service  
npm init -y  
npm install express mongoose

2. Налаштування app.js:

const express = require('express');  
const mongoose = require('mongoose');  
const productRoutes = require('./routes/productRoutes');  
const app = express();  

app.use(express.json());  

// Маршрут  
app.use('/products', productRoutes);  

// Підключення до бази даних  
mongoose  
 .connect('mongodb://localhost:27017/product-service', {  
 useNewUrlParser: true,  
 useUnifiedTopology: true,  
 })  
 .then(() => console.log('Підключено до бази даних Product-Service'))  
 .catch((err) => console.error('Не вдалося підключитися до бази даних', err));  

// Запуск сервера  
app.listen(3002, () => {  
 console.log('Product-Service працює на http://localhost:3002');  
});

3. Створення моделі продукту: Додайте файл models/productModel.js:

const mongoose = require('mongoose');  

const productSchema = new mongoose.Schema({  
 name: { type: String, required: true },  
 price: { type: Number, required: true },  
 stock: { type: Number, default: 0 },  
});  

const Product = mongoose.model('Product', productSchema);  

module.exports = Product;

4. Створення маршруту для продуктів: Додайте файл routes/productRoutes.js:

const express = require('express');  
const Product = require('../models/productModel');  
const router = express.Router();  

// Додавання продукту  
router.post('/', async (req, res) => {  
 try {  
 const product = new Product(req.body);  
 await product.save();  
 res.status(201).json(product);  
 } catch (err) {  
 res.status(500).json({ error: err.message });  
 }  
});  

// Отримання всіх продуктів  
router.get('/', async (req, res) => {  
 try {  
 const products = await Product.find();  
 res.json(products);  
 } catch (err) {  
 res.status(500).json({ error: err.message });  
 }  
});  

module.exports = router;

5. Запуск Product-Service:

node app.js

3. Комунікація між сервісами

3.1 Комунікація через REST API

Сервіс Order-Service буде отримувати дані користувачів та продуктів через REST API.

  1. Додайте залежність axios:
npm install axios
  1. Використовуйте axios для доступу до User-Service та Product-Service в Order-Service:
const axios = require('axios');  

async function getUser(userId) {  
 const response = await axios.get(`http://localhost:3001/users/${userId}`);  
 return response.data;  
}  

async function getProduct(productId) {  
 const response = await axios.get(`http://localhost:3002/products/${productId}`);  
 return response.data;  
}

4. Завдання та приклади

4.1 Завдання

  1. Створіть Order-Service для обробки замовлень, включаючи інтеграцію з User-Service та Product-Service.
    2.
    Додайте валідацію запасів продукції в Product-Service перед створенням замовлення.

4.2 Приклад

  • Створіть додаток для електронної комерції з такими функціями:
  • Аутентифікація користувачів (User-Service).
  • Управління продуктами (Product-Service).
  • Управління замовленнями (Order-Service).
  • Звіт про загальний дохід від замовлень.

5. Рефлексія та обговорення

1. Питання для рефлексії:

  • Які основні проблеми при управлінні великою кількістю мікросервісів?
  • Як ви справляєтеся з помилками в одному з сервісів?

2. Подальше обговорення:

  • Які переваги використання message broker (наприклад, RabbitMQ) порівняно з REST API для комунікації між сервісами?
  • Як ви забезпечуєте безпеку комунікації між сервісами?

Перекладено з: Node.js 9: Penerapan Mikroservis

Leave a Reply

Your email address will not be published. Required fields are marked *