2.1 Ümumi arxitektura
Bu mərhələdə biz tapşırıqların idarə edilməsi üçün tətbiqetmə arxitekturasını layihələndirəcəyik. Biz frontend, backend və verilənlər bazasının necə qarşılıqlı əlaqədə olacağını, həmçinin onların hər birinə hansı komponentlərin daxil olacağını müəyyən edəcəyik.
Tətbiqetmə üç əsas komponentdən ibarət olacaq:
- Frontend (ReactJS): İstifadəçinin sistem ilə qarşılıqlı əlaqəsini təmin edən müştəri tərəfi.
- Backend (Flask): Frontend-dən gələn sorğuları emal edən və verilənlər bazası ilə qarşılıqlı əlaqədə olan server tərəfi.
- Database (PostgreSQL): İstifadəçilər və tapşırıqlarla bağlı verilənlərin saxlanılması üçün baza.
Arxitektura aşağıdakı kimi olacaq:
+-------------+ +-------------+ +--------------+
| | | | | |
| Frontend +------>+ Backend +------>+ Database |
| (ReactJS) | | (Flask) | | (PostgreSQL) |
| | | | | |
+-------------+ +-------------+ +--------------+
Komponentlər arasında qarşılıqlı əlaqə
- Frontend: CRUD əməliyyatlarını (yaratma, oxuma, yeniləmə, silmə) həyata keçirmək üçün backend-ə HTTP-sorğular göndərir.
- Backend: Frontend-dən gələn HTTP-sorğuları emal edir, biznes məntiqi yerinə yetirir və verilənlər bazası ilə qarşılıqlı əlaqədə olur.
- Database: Backend-dən gələn sorğulara əsasən verilənləri saxlayır və təqdim edir.
2.2 Hər bir komponentin təsviri
1. Frontend (ReactJS):
- İnterfeys komponentləri: İstifadəçilərin qeydiyyatı və avtorizasiyası, tapşırıqların yaradılması və redaktəsi, tapşırıqlar siyahısına baxış üçün komponentlər.
- API ilə qarşılıqlı əlaqə: Backend-ə HTTP sorğuları göndərmək üçün Axios kitabxanasından istifadə.
2. Backend (Flask):
- REST API: İstifadəçilərin və tapşırıqların idarəedilməsi üçün endpoint-lərin həyata keçirilməsi.
- Data modelləri: SQLAlchemy istifadə edərək istifadəçilər və tapşırıqlar üçün data modellərinin müəyyən edilməsi.
- Biznes-loqika: Data doğrulama və istifadəçi sessiyalarının idarəedilməsi də daxil olmaqla tətbiqin loqikasının işlənməsi.
3. Database (PostgreSQL):
- Cədvəllər: İstifadəçilər və tapşırıqlar haqqında məlumatların saxlanması üçün cədvəllər.
- Cədvəllər arasındakı əlaqələr: İstifadəçilər və tapşırıqlar arasında əlaqələrin müəyyən edilməsi (məsələn, bir istifadəçinin bir çox tapşırığı ola bilər).
4. Şəbəkə qarşılıqlı əlaqəsi
Bütün komponentlər arasındakı kommunikasiya HTTP protokolu vasitəsilə həyata keçiriləcək. Frontend REST API vasitəsilə Backend-lə, Backend isə SQL sorğuları vasitəsilə verilənlər bazası ilə qarşılıqlı əlaqədə olacaq.
- Frontend: İnkişaf və test üçün 3000 portu.
- Backend: Frontend ilə qarşılıqlı əlaqə üçün 5000 portu.
- Database: Backend ilə qarşılıqlı əlaqə üçün 5432 portu.
2.3 Hər bir komponentin detallı təsviri
1. Əsas məlumat strukturu
İstifadəçilər və tapşırıqlar haqqında məlumatları PostgreSQL məlumat bazasında saxlamaq üçün iki cədvəl yaradırıq: users və tasks.
Users cədvəli:
-
id (int, primary key): İstifadəçinin unikal identifikatoru. username (varchar, unique): İstifadəçi adı.password (varchar): İstifadəçinin parolunun hash-i.
Tasks cədvəli:
-
id (int, primary key): Tapşırığın unikal identifikatoru. title (varchar): Tapşırığın başlığı.description (text): Tapşırığın təsviri.-
owner_id (int, foreign key): Tapşırığın təyin edildiyi istifadəçinin identifikatoru. -
status (varchar): Tapşırığın statusu (yerinə yetirilib/yerinə yetirilməyib).
2. API dizaynı
Backend frontend ilə qarşılıqlı əlaqə üçün RESTful API təqdim edəcək. Təxmini endpoint siyahısı:
- İstifadəçilər:
- POST /users: Yeni istifadəçi yaratmaq.
- GET /users: Bütün istifadəçilərin siyahısını əldə etmək.
- GET /users/:id: Müəyyən bir istifadəçi haqqında məlumat əldə etmək.
- PUT /users/:id: İstifadəçi məlumatlarını yeniləmək.
- DELETE /users/:id: İstifadəçini silmək.
- Tapşırıqlar:
- POST /tasks: Yeni tapşırıq yaratmaq.
- GET /tasks: Bütün tapşırıqların siyahısını əldə etmək.
- GET /tasks/:id: Müəyyən bir tapşırıq haqqında məlumat əldə etmək.
- PUT /tasks/:id: Tapşırıq məlumatlarını yeniləmək.
- DELETE /tasks/:id: Tapşırığı silmək.
2.4 Məlumat Modelləri
Verilənlər bazası cədvəlləri ilə işləmək üçün Python-da kod belə görünəcək:
İstifadəçi Modeli:
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)
Tapşırıq Modeli:
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="tamamlanmamış")
2.5 Marşrutlar və kontrollerlər
Server tərəfində API-nin tətbiq nümunəsi:
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', "yerinə yetirilməyib")
)
db.session.add(new_task)
db.session.commit()
return jsonify(new_task.to_dict()), 201
@app.route('/tasks/
', methods=['GET']) def get_task(id): task = Task.query.get_or_404(id) return jsonify(task.to_dict()) @app.route('/tasks/
', 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/
', methods=['DELETE']) def delete_task(id): task = Task.query.get_or_404(id) db.session.delete(task) db.session.commit() return '', 204
2.6 Frontend tərəfindən serverə müraciət nümunəsi
Task siyahısının göstərilməsi üçün React komponent nümunəsi:
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('Tapşırıqlar gətirilərkən bir xəta baş verdi!', error);
});
}, []);
return (
<div>
<h1>Task Siyahısı</h1>
<ul>
{tasks.map(task => (
<li key={task.id}>{task.title} - {task.status}</li>
))}
</ul>
</div>
);
};
export default TaskList;
GO TO FULL VERSION