CodeGym /课程 /Docker SELF /应用程序架构设计

应用程序架构设计

Docker SELF
第 23 级 , 课程 1
可用

2.1 总体架构

在这个阶段,我们将设计一个用于管理任务的应用程序架构。我们会明确前端、后端和数据库之间的交互关系,以及它们各自包含的组件。

应用程序将由三个主要部分组成:

  • Frontend (ReactJS): 提供用户与系统交互的客户端部分。
  • Backend (Flask): 处理来自前端的请求并与数据库交互的服务器部分。
  • Database (PostgreSQL): 用于存储用户和任务数据的存储部分。

架构图如下:

Terminal

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

组件之间的交互

  • Frontend: 发送HTTP请求到后端以执行CRUD操作(创建、读取、更新、删除任务)。
  • Backend: 处理来自前端的HTTP请求,执行业务逻辑并与数据库交互。
  • Database: 根据后端的请求保存和提供数据。

2.2 每个组件的描述

1. Frontend (ReactJS):

  • 界面组件: 用于用户注册和登录、创建和编辑任务、查看任务列表的组件。
  • 与API的交互: 使用Axios库发送HTTP请求到后台。

2. Backend (Flask):

  • REST API: 实现用户和任务管理的端点。
  • 数据模型: 使用SQLAlchemy定义用户和任务的数据模型。
  • 业务逻辑: 处理应用程序逻辑,包括数据验证和用户会话管理。

3. Database (PostgreSQL):

  • : 用于存储关于用户和任务信息的表。
  • 表关系: 定义用户和任务表之间的关系(例如,一个用户可以有很多任务)。

4. 网络交互

所有组件之间的通信将通过HTTP协议进行。Frontend将通过REST API与Backend交互,而Backend将通过SQL查询与数据库交互。

  • Frontend: 开发和测试使用端口3000。
  • Backend: 用于与Frontend交互的端口5000。
  • Database: 用于与Backend交互的端口5432。

2.3 每个组件的详细描述

1. 数据的基本结构

我们将在PostgreSQL数据库中创建两个表来存储用户和任务的数据:userstasks

users:

  • id (int, primary key): 用户的唯一标识符。
  • username (varchar, unique): 用户名。
  • password (varchar): 用户密码的哈希值。

tasks:

  • id (int, primary key): 任务的唯一标识符。
  • title (varchar): 任务标题。
  • description (text): 任务描述。
  • owner_id (int, foreign key): 分配任务的用户ID。
  • status (varchar): 任务状态(例如,已完成/未完成)。

2. API设计

后端将提供RESTful API与前端交互。可能的端点列表如下:

  • 用户:
    • POST /users: 创建新用户。
    • GET /users: 获取所有用户的列表。
    • GET /users/:id: 获取特定用户的信息。
    • PUT /users/:id: 更新用户信息。
    • DELETE /users/:id: 删除用户。
  • 任务:
    • POST /tasks: 创建新任务。
    • GET /tasks: 获取所有任务的列表。
    • GET /tasks/:id: 获取特定任务的信息。
    • PUT /tasks/:id: 更新任务信息。
    • DELETE /tasks/:id: 删除任务。

2.4 数据模型

以下是使用 Python 操作数据库表的代码示例:

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
        }

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="未完成")
    def to_dict(self):
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "owner_id": self.owner_id,
            "status": self.status
        }

2.5 路由和控制器

在服务器端实现API的示例:

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', "未完成")
    )
    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 前端请求服务器的例子

用于显示任务列表的 React 组件示例:

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('获取任务时出错了!', error);
      });
  }, []);

  return (
    <div>
      <h1>任务列表</h1>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>{task.title} - {task.status}</li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;
3
任务
Docker SELF, 第 23 级, 课程 1
已锁定
创建数据模型
创建数据模型
3
任务
Docker SELF, 第 23 级, 课程 1
已锁定
实现任务的CRUD API
实现任务的CRUD API
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION