CodeGym /Cursos /Docker SELF /Design da arquitetura da aplicação

Design da arquitetura da aplicação

Docker SELF
Nível 23 , Lição 1
Disponível

2.1 Arquitetura Geral

Nesta etapa, vamos planejar a arquitetura do aplicativo para gerenciamento de tarefas. Vamos definir como o frontend, backend e o banco de dados irão interagir, além de quais componentes estarão incluídos em cada um deles.

O aplicativo será composto por três componentes principais:

  • Frontend (ReactJS): Parte do cliente que garante a interação do usuário com o sistema.
  • Backend (Flask): Parte do servidor que processa as solicitações do frontend e interage com o banco de dados.
  • Database (PostgreSQL): Armazenamento de dados para usuários e tarefas.

A arquitetura terá o seguinte formato:

Terminal

+-------------+       +-------------+       +--------------+
|             |       |             |       |              |
|  Frontend   +------->+   Backend   +------->+   Database   |
|  (ReactJS)  |       |   (Flask)   |       | (PostgreSQL) |
|             |       |             |       |              |
+-------------+       +-------------+       +--------------+

Interação entre os componentes

  • Frontend: envia requisições HTTP para o backend realizar operações CRUD (criar, ler, atualizar, excluir tarefas).
  • Backend: processa as requisições HTTP do frontend, executa a lógica de negócios e interage com o banco de dados.
  • Database: armazena e fornece dados mediante solicitações do backend.

2.2 Descrição de cada componente

1. Frontend (ReactJS):

  • Componentes de interface: componentes para registro e login de usuários, criação e edição de tarefas, visualização da lista de tarefas.
  • Interação com API: uso da biblioteca Axios para enviar requisições HTTP para o backend.

2. Backend (Flask):

  • REST API: implementação de endpoints para gerenciamento de usuários e tarefas.
  • Modelos de dados: definição de modelos de dados para usuários e tarefas usando SQLAlchemy.
  • Lógica de negócio: processamento da lógica do aplicativo, incluindo validação de dados e gerenciamento de sessões de usuários.

3. Banco de Dados (PostgreSQL):

  • Tabelas: tabelas para armazenar informações sobre usuários e tarefas.
  • Relações entre tabelas: definição de relações entre tabelas de usuários e tarefas (por exemplo, um usuário pode ter várias tarefas).

4. Interação em rede

Toda a comunicação entre os componentes será feita através do protocolo HTTP. O frontend irá interagir com o backend através da REST API, e o backend — com o banco de dados através de consultas SQL.

  • Frontend: porta 3000 para desenvolvimento e testes.
  • Backend: porta 5000 para interação com o frontend.
  • Database: porta 5432 para interação com o backend.

2.3 Descrição Detalhada de Cada Componente

1. Estrutura Básica de Dados

Para armazenar dados sobre usuários e tarefas no banco de dados PostgreSQL, vamos criar duas tabelas: users e tasks.

Tabela users:

  • id (int, primary key): identificador único do usuário.
  • username (varchar, unique): nome do usuário.
  • password (varchar): hash da senha do usuário.

Tabela tasks:

  • id (int, primary key): identificador único da tarefa.
  • title (varchar): título da tarefa.
  • description (text): descrição da tarefa.
  • owner_id (int, foreign key): identificador do usuário ao qual a tarefa foi atribuída.
  • status (varchar): status da tarefa (por exemplo, concluída/não concluída).

2. Design da API

O backend vai fornecer uma RESTful API para interação com o frontend. Lista aproximada de endpoints:

  • Usuários:
    • POST /users: criar um novo usuário.
    • GET /users: obter a lista de todos os usuários.
    • GET /users/:id: obter informações sobre um usuário específico.
    • PUT /users/:id: atualizar informações de um usuário.
    • DELETE /users/:id: deletar um usuário.
  • Tarefas:
    • POST /tasks: criar uma nova tarefa.
    • GET /tasks: obter a lista de todas as tarefas.
    • GET /tasks/:id: obter informações sobre uma tarefa específica.
    • PUT /tasks/:id: atualizar informações de uma tarefa.
    • DELETE /tasks/:id: deletar uma tarefa.

2.4 Modelos de Dados

É assim que o código em Python para trabalhar com tabelas no banco de dados vai ficar:

Modelo User:

Python

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    tasks = db.relationship('Task', backref='owner', lazy=True)
    def to_dict(self):
        return {
            "id": self.id,
            "username": self.username
        }

Modelo Task:

Python

from app import db

class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    description = db.Column(db.Text, nullable=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    status = db.Column(db.String(20), nullable=False, default="não feita")
    def to_dict(self):
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "owner_id": self.owner_id,
            "status": self.status
        }

2.5 Rotas e controladores

Exemplo de implementação de API no lado do servidor:

Python

from app import app, db
from app.models import Task, User
from flask import request, jsonify

@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks = Task.query.all()
    return jsonify([task.to_dict() for task in tasks])

@app.route('/tasks', methods=['POST'])
def create_task():
    data = request.get_json()
    new_task = Task(
        title=data['title'],
        description=data.get('description'),
        owner_id=data['owner_id'],
        status=data.get('status', "não concluída")
    )
    db.session.add(new_task)
    db.session.commit()
    return jsonify(new_task.to_dict()), 201

@app.route('/tasks/<int:id>', methods=['GET'])
def get_task(id):
    task = Task.query.get_or_404(id)
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['PUT'])
def update_task(id):
    data = request.get_json()
    task = Task.query.get_or_404(id)
    task.title = data['title']
    task.description = data.get('description')
    task.status = data.get('status', task.status)
    task.owner_id = data['owner_id']
    db.session.commit()
    return jsonify(task.to_dict())

@app.route('/tasks/<int:id>', methods=['DELETE'])
def delete_task(id):
    task = Task.query.get_or_404(id)
    db.session.delete(task)
    db.session.commit()
    return '', 204

2.6 Exemplo de chamada ao servidor a partir do frontend

Exemplo de componente React para exibir uma lista de tarefas:

Javascript

import React, { useEffect, useState } from 'react';
import axios from 'axios';

const TaskList = () => {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    axios.get('http://localhost:5000/tasks')
      .then(response => {
        setTasks(response.data);
      })
      .catch(error => {
        console.error('Ocorreu um erro ao buscar as tarefas!', error);
      });
  }, []);

  return (
    <div>
      <h1>Lista de Tarefas</h1>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title} - {task.status}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION