Merge pull request 'vasina_ekaterina_lab_3' (#294) from vasina_ekaterina_lab_3 into main
Reviewed-on: #294
This commit is contained in:
commit
14de0603a8
53
vasina_ekaterina_lab_3/README.md
Normal file
53
vasina_ekaterina_lab_3/README.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
# Лабораторная работа №3 - REST API, шлюз и синхронный обмен данными между микросервисами
|
||||||
|
|
||||||
|
## Задание
|
||||||
|
|
||||||
|
### Цель
|
||||||
|
Изучение принципов проектирования с использованием паттерна шлюза, организации синхронной передачи данных между микросервисами и применения архитектурного стиля RESTful API.
|
||||||
|
|
||||||
|
### Задачи
|
||||||
|
1. Создание двух микросервисов, которые реализуют операции CRUD для связанных сущностей.
|
||||||
|
2. Реализация механизма синхронного обмена данными между микросервисами.
|
||||||
|
3. Настройка шлюза на базе Nginx в качестве прозрачного прокси-сервера.
|
||||||
|
|
||||||
|
### Микросервисы
|
||||||
|
1. **user_service** — сервис, который управляет информацией о пользователях.
|
||||||
|
2. **order_service** — сервис, который обрабатывает данные о заказах пользователей.
|
||||||
|
|
||||||
|
### Связь между микросервисами
|
||||||
|
- Один документ (user) может иметь множество связанных предметов (orders) (соотношение 1 ко многим).
|
||||||
|
|
||||||
|
### Структура проекта
|
||||||
|
|
||||||
|
```
|
||||||
|
lab_3/
|
||||||
|
|-- nginx/
|
||||||
|
| |-- nginx.conf
|
||||||
|
|-- order_service/
|
||||||
|
| |-- Dockerfile
|
||||||
|
| |-- main.py
|
||||||
|
| |-- requirements.txt
|
||||||
|
|-- user_service/
|
||||||
|
| |-- Dockerfile
|
||||||
|
| |-- main.py
|
||||||
|
| |-- requirements.txt
|
||||||
|
|-- docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Описание работы:
|
||||||
|
|
||||||
|
Для разработки микросервисов был выбран язык программирования Python.
|
||||||
|
|
||||||
|
### Синхронный обмен данными
|
||||||
|
Сервис `user_service` отправляет HTTP-запросы к `order_service` при выполнении определенных операций CRUD. Это позволяет получать актуальную информацию о предметах, связанных с конкретными героями.
|
||||||
|
|
||||||
|
### Docker Compose
|
||||||
|
Конфигурационный файл `docker-compose.yml` представляет собой многоконтейнерное приложение, которое включает в себя три сервиса: `user_service`, `order_service` и `nginx`. Функция маршрутизации возложена на сервер Nginx, который обрабатывает запросы и перенаправляет их на соответствующие микросервисы.
|
||||||
|
|
||||||
|
### Nginx
|
||||||
|
Конфигурационный файл Nginx определяет настройки веб-сервера и обратного прокси, который управляет входящими запросами и направляет их на соответствующие сервисы.
|
||||||
|
|
||||||
|
### Видеозапись работы программы
|
||||||
|
|
||||||
|
https://vkvideo.ru/video174596752_456239396
|
24
vasina_ekaterina_lab_3/docker-compose.yml
Normal file
24
vasina_ekaterina_lab_3/docker-compose.yml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
services:
|
||||||
|
user_service:
|
||||||
|
build:
|
||||||
|
context: ./user_service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
|
||||||
|
order_service:
|
||||||
|
build:
|
||||||
|
context: ./order_service
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
ports:
|
||||||
|
- "5001:5001"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx:latest
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
depends_on:
|
||||||
|
- user_service
|
||||||
|
- order_service
|
11
vasina_ekaterina_lab_3/nginx/nginx.conf
Normal file
11
vasina_ekaterina_lab_3/nginx/nginx.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
location /users {
|
||||||
|
proxy_pass http://user_service:5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /orders {
|
||||||
|
proxy_pass http://order_service:5001;
|
||||||
|
}
|
||||||
|
}
|
10
vasina_ekaterina_lab_3/order_service/Dockerfile
Normal file
10
vasina_ekaterina_lab_3/order_service/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3.11
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
CMD ["python", "main.py"]
|
56
vasina_ekaterina_lab_3/order_service/main.py
Normal file
56
vasina_ekaterina_lab_3/order_service/main.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
from flask import Flask, jsonify, request
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
orders = {}
|
||||||
|
|
||||||
|
# вывод всех заказов
|
||||||
|
@app.route('/orders', methods=['GET'])
|
||||||
|
def get_orders():
|
||||||
|
return jsonify(list(orders.values()))
|
||||||
|
|
||||||
|
# получение заказа по uuid
|
||||||
|
@app.route('/orders/<uuid:order_uuid>', methods=['GET'])
|
||||||
|
def get_order(order_uuid):
|
||||||
|
order = orders.get(str(order_uuid))
|
||||||
|
if order:
|
||||||
|
return jsonify(order)
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
|
||||||
|
# добавление нового заказа
|
||||||
|
@app.route('/orders', methods=['POST'])
|
||||||
|
def create_order():
|
||||||
|
data = request.json
|
||||||
|
order_uuid = str(uuid.uuid4())
|
||||||
|
order = {
|
||||||
|
'uuid': order_uuid,
|
||||||
|
'number': data['number'],
|
||||||
|
'product': data['product'],
|
||||||
|
'user_uuid': data['user_uuid']
|
||||||
|
}
|
||||||
|
orders[order_uuid] = order
|
||||||
|
return jsonify(order), 201
|
||||||
|
|
||||||
|
# изменение заказа по uuid
|
||||||
|
@app.route('/orders/<uuid:order_uuid>', methods=['PUT'])
|
||||||
|
def update_order(order_uuid):
|
||||||
|
order = orders.get(str(order_uuid))
|
||||||
|
if not order:
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
data = request.json
|
||||||
|
order['number'] = data['number']
|
||||||
|
order['product'] = data['product']
|
||||||
|
order['user_uuid'] = data['user_uuid']
|
||||||
|
return jsonify(order)
|
||||||
|
|
||||||
|
# удаление заказа по uuid
|
||||||
|
@app.route('/orders/<uuid:order_uuid>', methods=['DELETE'])
|
||||||
|
def delete_order(order_uuid):
|
||||||
|
if str(order_uuid) in orders:
|
||||||
|
del orders[str(order_uuid)]
|
||||||
|
return '', 204
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5001)
|
1
vasina_ekaterina_lab_3/order_service/requirements.txt
Normal file
1
vasina_ekaterina_lab_3/order_service/requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Flask
|
10
vasina_ekaterina_lab_3/user_service/Dockerfile
Normal file
10
vasina_ekaterina_lab_3/user_service/Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM python:3.11
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
CMD ["python", "main.py"]
|
54
vasina_ekaterina_lab_3/user_service/main.py
Normal file
54
vasina_ekaterina_lab_3/user_service/main.py
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
from flask import Flask, jsonify, request
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
users = {}
|
||||||
|
|
||||||
|
# вывод всех пользователей
|
||||||
|
@app.route('/users', methods=['GET'])
|
||||||
|
def get_users():
|
||||||
|
return jsonify(list(users.values()))
|
||||||
|
|
||||||
|
# получение пользователя по uuid
|
||||||
|
@app.route('/users/<uuid:user_uuid>', methods=['GET'])
|
||||||
|
def get_user(user_uuid):
|
||||||
|
user = users.get(str(user_uuid))
|
||||||
|
if user:
|
||||||
|
return jsonify(user)
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
|
||||||
|
# добавление нового пользователя
|
||||||
|
@app.route('/users', methods=['POST'])
|
||||||
|
def create_user():
|
||||||
|
data = request.get_json()
|
||||||
|
user_uuid = str(uuid.uuid4())
|
||||||
|
user = {
|
||||||
|
'uuid': user_uuid,
|
||||||
|
'name': data['name'],
|
||||||
|
'age': data['age']
|
||||||
|
}
|
||||||
|
users[user_uuid] = user
|
||||||
|
return jsonify(user), 201
|
||||||
|
|
||||||
|
# изменение пользователя по uuid
|
||||||
|
@app.route('/users/<uuid:user_uuid>', methods=['PUT'])
|
||||||
|
def update_user(user_uuid):
|
||||||
|
user = users.get(str(user_uuid))
|
||||||
|
if not user:
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
data = request.get_json()
|
||||||
|
user['name'] = data['name']
|
||||||
|
user['age'] = data['age']
|
||||||
|
return jsonify(user)
|
||||||
|
|
||||||
|
# удаление пользователя по uuid
|
||||||
|
@app.route('/users/<uuid:user_uuid>', methods=['DELETE'])
|
||||||
|
def delete_user(user_uuid):
|
||||||
|
if str(user_uuid) in users:
|
||||||
|
del users[str(user_uuid)]
|
||||||
|
return '', 204
|
||||||
|
return jsonify({'error': 'Not found'}), 404
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5000)
|
1
vasina_ekaterina_lab_3/user_service/requirements.txt
Normal file
1
vasina_ekaterina_lab_3/user_service/requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Flask
|
Loading…
Reference in New Issue
Block a user