128 lines
5.9 KiB
Markdown
128 lines
5.9 KiB
Markdown
|
# Лабораторная работа №3 - REST API, Gateway и синхронный обмен между микросервисами
|
|||
|
|
|||
|
Цель: изучение шаблона проектирования gateway, построения синхронного обмена между микросервисами и архитектурного стиля RESTful API.
|
|||
|
|
|||
|
Задачи:
|
|||
|
|
|||
|
1. Создать 2 микросервиса, реализующих CRUD на связанных сущностях.
|
|||
|
2. Реализовать механизм синхронного обмена сообщениями между микросервисами.
|
|||
|
3. Реализовать шлюз на основе прозрачного прокси-сервера nginx.
|
|||
|
|
|||
|
## Создание микросервисов
|
|||
|
|
|||
|
Создать два микросервиса.
|
|||
|
|
|||
|
Каждый сервис реализует CRUD-операции: список записей, подробности конкретной записи, создание, удаление и изменение записи.
|
|||
|
|
|||
|
В качестве хранилища данных может выступать оперативная память приложения или база данных.
|
|||
|
|
|||
|
Сущности необходимо подобрать по следующим критериям:
|
|||
|
|
|||
|
1. Они должны быть связаны с предполагаемой темой диплома.
|
|||
|
2. Они должны быть связаны как `1-ко-многим``.
|
|||
|
|
|||
|
> Например, одна сущность - книга в библиотеке, вторая - абонемент.
|
|||
|
>
|
|||
|
> Поля абонемента: УИД (уникальный идентификатор) абонемента, Номер, ФИО читателя, Дата выдачи.
|
|||
|
> Поля книги: УИД книги, Автор, Название, Год издания, УИД абонемента, на котором сейчас находится книга.
|
|||
|
|
|||
|
Общение между сервисами должно происходить при помощи API, реализованного при помощи архитектурного стиля проектирования REST.
|
|||
|
То есть необходимо реализовать следующие endpoints:
|
|||
|
|
|||
|
1. "GET /" - Получение списка записей.
|
|||
|
Должен возвращать массив моделей.
|
|||
|
2. "GET /{uuid}" - Получение подробностей записи по УИД (uuid).
|
|||
|
Должен возвращать модель или ошибку 404.
|
|||
|
3. "POST /" - Создание новой записи.
|
|||
|
Принимает на вход данные. Должен возвращать модель из п.2.
|
|||
|
4. "PUT /{uuid}" - Обновление записи по УИД.
|
|||
|
Принимает на вход новые данные. Должен возвращать модель из п.2 или ошибку 404.
|
|||
|
5. "DELETE /{uuid}" - Удаление записи по УИД.
|
|||
|
Возвращает коды 200 при успехе и 404, если запись не найдена.
|
|||
|
|
|||
|
Пример модели абонемента для списка и подробностей:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
"uuid": "8f036445-a5bd-401c-926e-840f9de795cd",
|
|||
|
"number": 135,
|
|||
|
"fullName": "Иванов И.И.",
|
|||
|
"issued": "2023-10-18T05:41:00Z"
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Пример модели абонемента для создания или изменения:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
"number": 135,
|
|||
|
"fullName": "Иванов И.И.",
|
|||
|
"issued": "2023-10-18T05:41:00Z"
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
> Как видите, нет УИДа, т.к. он присваивается системой, и изменять мы его не можем.
|
|||
|
|
|||
|
Пример модели книги для списка:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
"uuid": "8740d660-b251-4272-8535-be7ec3748d4b",
|
|||
|
"author": "J.K.R.",
|
|||
|
"subject": "HP and PS",
|
|||
|
"year": 1997,
|
|||
|
"subscriptionUuid": "8f036445-a5bd-401c-926e-840f9de795cd"
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Пример модели книги для подробностей:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
"uuid": "8740d660-b251-4272-8535-be7ec3748d4b",
|
|||
|
"author": "J.K.R.",
|
|||
|
"subject": "HP and PS",
|
|||
|
"year": 1997,
|
|||
|
"subscriptionUuid": "8f036445-a5bd-401c-926e-840f9de795cd",
|
|||
|
"subscriptionInfo": {
|
|||
|
"number": 135,
|
|||
|
"fullName": "Иванов И.И.",
|
|||
|
"issued": "2023-10-18T05:41:00Z"
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
> Как видите, модель сильно богаче, чем при запросе списка.
|
|||
|
>
|
|||
|
> Как раз здесь и нужен синхронный обмен между сервисами.
|
|||
|
|
|||
|
Пример модели книги для создания или изменения:
|
|||
|
|
|||
|
```json
|
|||
|
{
|
|||
|
"author": "J.K.R.",
|
|||
|
"subject": "HP and PS",
|
|||
|
"year": 1997,
|
|||
|
"subscriptionUuid": "8f036445-a5bd-401c-926e-840f9de795cd"
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
Как понять, куда обращаться микросервису книг для получения данных об абонементах?
|
|||
|
Нам здесь поможет docker compose: код в "service" совпадает с хостом, куда следует обращаться.
|
|||
|
|
|||
|
## Реализация синхронного обмена
|
|||
|
|
|||
|
Как реализовать непосредственно работу с endpoints?
|
|||
|
Например, использовать ASP.NET Core Minimal APIs.
|
|||
|
[Небольшой пример, который это показывает](./example_1.cs).
|
|||
|
|
|||
|
Как вызвать синхронно данные с соседнего микросервиса?
|
|||
|
Через HTTP-клиент!
|
|||
|
[Небольшой пример, который это показывает](./example_2.cs).
|
|||
|
|
|||
|
## Реализация gateway при помощи nginx
|
|||
|
|
|||
|
Один сервер, несколько location, proxy_pass по хосту из docker-compose.yml, открытые порты наружу и... всё.
|
|||
|
|
|||
|
[Пример файла с настройкой nginx](./example_nginx.conf).
|