CodeGym /コース /Docker SELF /アプリケーションアーキテクチャの設計

アプリケーションアーキテクチャの設計

Docker SELF
レベル 23 , レッスン 1
使用可能

2.1 全体的なアーキテクチャ

この段階では、タスク管理アプリケーションのアーキテクチャを設計するよ。Frontend、Backend、Databaseがどのように相互作用するか、それぞれにどんなコンポーネントが含まれるかを決めるんだ。

アプリケーションは以下の3つの主要なコンポーネントから構成されるよ:

  • Frontend (ReactJS): ユーザーとシステムがやり取りするためのクライアントサイド。
  • Backend (Flask): Frontendからのリクエストを処理し、Databaseとやり取りするサーバーサイド。
  • Database (PostgreSQL): ユーザーとタスクのデータを保存するデータストア。

アーキテクチャは以下のようになるんだ:

ターミナル

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

コンポーネント間の相互作用

  • Frontend: タスクのCRUD操作(作成、読み取り、更新、削除)を実行するために、BackendにHTTPリクエストを送信するんだ。
  • Backend: FrontendからのHTTPリクエストを処理して、ビジネスロジックを実行し、Databaseとやり取りを行うよ。
  • Database: Backendからのリクエストに応じてデータを保存したり、提供したりするんだ。

2.2 各コンポーネントの説明

1. Frontend (ReactJS):

  • インターフェースコンポーネント: ユーザー登録・認証、タスクの作成と編集、タスクリストの閲覧用コンポーネント。
  • APIとのやり取り: HTTPリクエストをバックエンドに送信するためにAxiosライブラリを使用する。

2. Backend (Flask):

  • REST API: ユーザーとタスクの管理用のエンドポイントを実装。
  • データモデル: SQLAlchemyを使用してユーザーとタスクのデータモデルを定義。
  • ビジネスロジック: データのバリデーションとユーザーセッション管理を含むアプリケーションロジックの処理。

3. Database (PostgreSQL):

  • テーブル: ユーザー情報およびタスク情報を保存するためのテーブル。
  • テーブル間の関係: ユーザーとタスクのテーブル間の関係を定義(例えば、1人のユーザーが複数のタスクを持つことができる)。

4. ネットワークインタラクション

全てのコンポーネント間の通信はHTTPプロトコルを通じて行われる。フロントエンドはREST APIを通じてバックエンドと連携し、バックエンドはSQLクエリを通じてデータベースと連携する。

  • Frontend: 開発およびテスト用のポート3000。
  • Backend: フロントエンドと連携するためのポート5000。
  • Database: バックエンドと連携するためのポート5432。

2.3 各コンポーネントの詳細説明

1. 基本的なデータ構造

ユーザーとタスクのデータをPostgreSQLデータベースに保存するために、userstasksの2つのテーブルを作成するよ。

usersテーブル:

  • id (int, primary key): ユーザーのユニークな識別子。
  • username (varchar, unique): ユーザー名。
  • password (varchar): ユーザーのパスワードハッシュ。

tasksテーブル:

  • id (int, primary key): タスクのユニークな識別子。
  • title (varchar): タスクのタイトル。
  • description (text): タスクの説明。
  • owner_id (int, foreign key): タスクが割り当てられたユーザーの識別子。
  • 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 Model:

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 Model:

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;
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION