kosheev_maksim_lab_4 is ready2
This commit is contained in:
parent
41d7a3d8fd
commit
0add49368f
@ -1,9 +0,0 @@
|
|||||||
FROM python:3.9
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN pip install flask requests
|
|
||||||
|
|
||||||
CMD ["python", "subscriptions_service.py"] # Замените на нужный файл при сборке.
|
|
@ -1,46 +0,0 @@
|
|||||||
# Лабораторная работа №3 - REST API, шлюз и синхронный обмен данными между микросервисами
|
|
||||||
|
|
||||||
## Задание
|
|
||||||
|
|
||||||
### Цель:
|
|
||||||
Изучение принципов проектирования с использованием паттерна шлюза, организации синхронной передачи данных между микросервисами и применения архитектурного стиля RESTful API.
|
|
||||||
|
|
||||||
### Задачи:
|
|
||||||
1. Создание двух микросервисов, которые реализуют операции CRUD для связанных сущностей.
|
|
||||||
2. Реализация механизма синхронного обмена данными между микросервисами.
|
|
||||||
3. Настройка шлюза на базе Nginx в качестве прозрачного прокси-сервера.
|
|
||||||
|
|
||||||
### Микросервисы:
|
|
||||||
1. **books_service** — сервис, который управляет информацией о книгах.
|
|
||||||
2. **subscriptions_service** — сервис, который обрабатывает данные об абонементах.
|
|
||||||
|
|
||||||
### Связь между микросервисами:
|
|
||||||
- Один абонемент может быть связан с несколькими книгами. Взаимодействие между сервисами осуществляется через синхронные HTTP-запросы.
|
|
||||||
|
|
||||||
## Как запустить проект:
|
|
||||||
|
|
||||||
Для запуска приложения необходимо выполнить команду:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose up --build
|
|
||||||
```
|
|
||||||
После этого проект будет доступен на следующих адресах:
|
|
||||||
|
|
||||||
Books Service: http://localhost:5000/books/
|
|
||||||
Subscriptions Service: http://localhost:5001/subscriptions/
|
|
||||||
## Описание работы:
|
|
||||||
Для разработки микросервисов был выбран язык программирования Python, с использованием фреймворка Flask для реализации API.
|
|
||||||
|
|
||||||
## Синхронный обмен данными
|
|
||||||
Сервис books_service обращается к subscriptions_service для получения информации о подписках, связанных с каждой книгой.
|
|
||||||
Все запросы между сервисами выполняются синхронно с использованием HTTP-запросов, что позволяет обеспечить актуальность данных при выполнении операций CRUD.
|
|
||||||
Docker Compose
|
|
||||||
Конфигурационный файл docker-compose.yml представляет собой многоконтейнерное приложение, которое включает в себя три сервиса: books_service, subscriptions_service и nginx. С помощью Docker Compose можно удобно запустить все сервисы одновременно.
|
|
||||||
|
|
||||||
## Nginx
|
|
||||||
Конфигурация Nginx настроена так, чтобы обрабатывать входящие HTTP-запросы и перенаправлять их на соответствующие сервисы. Это позволяет использовать один общий адрес для доступа к разным API-сервисам.
|
|
||||||
|
|
||||||
Nginx будет действовать как шлюз, который будет маршрутизировать запросы от пользователей в соответствующие микросервисы.
|
|
||||||
|
|
||||||
### Видео
|
|
||||||
https://disk.yandex.ru/i/b12BECyaGmbqUQ
|
|
@ -1,8 +0,0 @@
|
|||||||
FROM python:3.9-slim
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
COPY requirements.txt requirements.txt
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
CMD ["python", "app.py"]
|
|
@ -1,82 +0,0 @@
|
|||||||
from flask import Flask, jsonify, request
|
|
||||||
import requests
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
# Данные о книгах (в памяти)
|
|
||||||
books = [
|
|
||||||
{
|
|
||||||
"uuid": str(uuid.uuid4()),
|
|
||||||
"author": "J.K.R.",
|
|
||||||
"subject": "HP and PS",
|
|
||||||
"year": 1997,
|
|
||||||
"subscriptionUuid": "8f036445-a5bd-401c-926e-840f9de795cd"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
SUBSCRIPTIONS_URL = "http://subscriptions_service:5000/subscriptions/"
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/books/', methods=['GET'])
|
|
||||||
def get_books():
|
|
||||||
return jsonify(books), 200
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/books/<uuid:book_id>', methods=['GET'])
|
|
||||||
def get_book(book_id):
|
|
||||||
book = next((b for b in books if b['uuid'] == str(book_id)), None)
|
|
||||||
if not book:
|
|
||||||
return jsonify({"error": "Book not found"}), 404
|
|
||||||
|
|
||||||
# Получение данных об абонементе
|
|
||||||
response = requests.get(f"{SUBSCRIPTIONS_URL}{book['subscriptionUuid']}")
|
|
||||||
if response.status_code == 200:
|
|
||||||
book["subscriptionInfo"] = response.json()
|
|
||||||
return jsonify(book), 200
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/books/', methods=['POST'])
|
|
||||||
def create_book():
|
|
||||||
data = request.json
|
|
||||||
new_book = {
|
|
||||||
"uuid": str(uuid.uuid4()),
|
|
||||||
"author": data["author"],
|
|
||||||
"subject": data["subject"],
|
|
||||||
"year": data["year"],
|
|
||||||
"subscriptionUuid": data["subscriptionUuid"]
|
|
||||||
}
|
|
||||||
books.append(new_book)
|
|
||||||
return jsonify(new_book), 201
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/books/<uuid:book_id>', methods=['PUT'])
|
|
||||||
def update_book(book_id):
|
|
||||||
data = request.json
|
|
||||||
book = next((b for b in books if b['uuid'] == str(book_id)), None)
|
|
||||||
if not book:
|
|
||||||
return jsonify({"error": "Book not found"}), 404
|
|
||||||
|
|
||||||
# Обновляем данные книги
|
|
||||||
book["author"] = data.get("author", book["author"])
|
|
||||||
book["subject"] = data.get("subject", book["subject"])
|
|
||||||
book["year"] = data.get("year", book["year"])
|
|
||||||
book["subscriptionUuid"] = data.get("subscriptionUuid", book["subscriptionUuid"])
|
|
||||||
|
|
||||||
return jsonify(book), 200
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/books/<uuid:book_id>', methods=['DELETE'])
|
|
||||||
def delete_book(book_id):
|
|
||||||
global books
|
|
||||||
book = next((b for b in books if b['uuid'] == str(book_id)), None)
|
|
||||||
if not book:
|
|
||||||
return jsonify({"error": "Book not found"}), 404
|
|
||||||
|
|
||||||
# Удаляем книгу
|
|
||||||
books = [b for b in books if b['uuid'] != str(book_id)]
|
|
||||||
return jsonify({"message": "Book deleted successfully"}), 200
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run(host="0.0.0.0", port=5000)
|
|
@ -1,3 +0,0 @@
|
|||||||
flask
|
|
||||||
flask-restful
|
|
||||||
requests
|
|
@ -1,28 +0,0 @@
|
|||||||
version: "3.8"
|
|
||||||
|
|
||||||
services:
|
|
||||||
books_service:
|
|
||||||
build:
|
|
||||||
context: ./books_service
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
ports:
|
|
||||||
- "5000:5000"
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions_service:
|
|
||||||
build:
|
|
||||||
context: ./subscriptions_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:
|
|
||||||
- books_service
|
|
||||||
- subscriptions_service
|
|
@ -1,11 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
|
|
||||||
location /books/ {
|
|
||||||
proxy_pass http://books_service:5000/;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /subscriptions/ {
|
|
||||||
proxy_pass http://subscriptions_service:5001/;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
FROM python:3.9-slim
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
COPY requirements.txt requirements.txt
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
CMD ["python", "app.py"]
|
|
@ -1,65 +0,0 @@
|
|||||||
from flask import Flask, jsonify, request
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
# Данные об абонементах (в памяти)
|
|
||||||
subscriptions = [
|
|
||||||
{
|
|
||||||
"uuid": str(uuid.uuid4()),
|
|
||||||
"number": 135,
|
|
||||||
"fullName": "Иванов И.И.",
|
|
||||||
"issued": "2023-10-18T05:41:00Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.route('/subscriptions/', methods=['GET'])
|
|
||||||
def get_subscriptions():
|
|
||||||
return jsonify(subscriptions), 200
|
|
||||||
|
|
||||||
@app.route('/subscriptions/<uuid:subscription_id>', methods=['GET'])
|
|
||||||
def get_subscription(subscription_id):
|
|
||||||
subscription = next((s for s in subscriptions if s['uuid'] == str(subscription_id)), None)
|
|
||||||
if subscription:
|
|
||||||
return jsonify(subscription), 200
|
|
||||||
return jsonify({"error": "Subscription not found"}), 404
|
|
||||||
|
|
||||||
@app.route('/subscriptions/', methods=['POST'])
|
|
||||||
def create_subscription():
|
|
||||||
data = request.json
|
|
||||||
new_subscription = {
|
|
||||||
"uuid": str(uuid.uuid4()),
|
|
||||||
"number": data["number"],
|
|
||||||
"fullName": data["fullName"],
|
|
||||||
"issued": data["issued"]
|
|
||||||
}
|
|
||||||
subscriptions.append(new_subscription)
|
|
||||||
return jsonify(new_subscription), 201
|
|
||||||
|
|
||||||
@app.route('/subscriptions/<uuid:subscription_id>', methods=['PUT'])
|
|
||||||
def update_subscription(subscription_id):
|
|
||||||
data = request.json
|
|
||||||
subscription = next((s for s in subscriptions if s['uuid'] == str(subscription_id)), None)
|
|
||||||
if not subscription:
|
|
||||||
return jsonify({"error": "Subscription not found"}), 404
|
|
||||||
|
|
||||||
# Обновляем поля, если они переданы
|
|
||||||
subscription["number"] = data.get("number", subscription["number"])
|
|
||||||
subscription["fullName"] = data.get("fullName", subscription["fullName"])
|
|
||||||
subscription["issued"] = data.get("issued", subscription["issued"])
|
|
||||||
|
|
||||||
return jsonify(subscription), 200
|
|
||||||
|
|
||||||
@app.route('/subscriptions/<uuid:subscription_id>', methods=['DELETE'])
|
|
||||||
def delete_subscription(subscription_id):
|
|
||||||
global subscriptions
|
|
||||||
subscription = next((s for s in subscriptions if s['uuid'] == str(subscription_id)), None)
|
|
||||||
if not subscription:
|
|
||||||
return jsonify({"error": "Subscription not found"}), 404
|
|
||||||
|
|
||||||
# Удаляем запись
|
|
||||||
subscriptions = [s for s in subscriptions if s['uuid'] != str(subscription_id)]
|
|
||||||
return jsonify({"message": "Subscription deleted successfully"}), 200
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run(host="0.0.0.0", port=5001)
|
|
@ -1,3 +0,0 @@
|
|||||||
flask
|
|
||||||
flask-restful
|
|
||||||
requests
|
|
Loading…
Reference in New Issue
Block a user