Cách xây dựng một REST API với database Flask và Postgres

Học cách tạo một RESTful API bằng Flask và Postgres, giúp việc trao đổi dữ liệu liền mạch giữa ứng dụng và hệ thống bên ngoài.

Tạo REST API

Application Programming Interfaces (APIs) là một phần quan trọng trong việc xây dựng và kết nối các hệ thống khác nhau, cho phép các ứng dụng giao tiếp & trao đổi dữ liệu với dịch vụ khác.

Trong khi lập trình backend không chỉ liên quan tới viết API, nó còn bao gồm logic nghiệp vụ phía server, thiết kế cấu trúc hệ thống hiệu quả và các chức năng chính khác. Dưới đây là cách xây dựng một CRUD REST API đơn giản bằng Flash (một framework Python gọn nhẹ) và database Postgres.

Dùng Flask để xây dựng backend API

Flask là một framework Python gọn nhẹ, cung cấp một số tính năng đơn giản hóa việc ghi API backend cho client web được viết bằng các công nghệ khác nhau như React và Angular.

Hướng dẫn này sẽ cho bạn biết cách viết một REST API thực hiện 4 quá trình CRUD: tạo, đọc, update và xóa để quản lý dữ liệu người dùng được lưu trong database Postgres.

Thiết lập database Postgres

Ghé qua ElephanSQL, một giải pháp lưu trữ database dựa trên đám mây, cung cấp nền tảng tạo và quản lý database Postgres trên đám mây, đăng ký & đăng nhập trang tổng quan tài khoản của bạn.

Hướng dẫn tạo PostgreSQL

Click Create New Instance để tạo một phiên bản ứng dụng mới.

Cách tạo PostgreSQL

Cung cấp tên phiên bản và chọn gói miễn phí, cuối cùng, chọn vùng phiên bản được host để hoàn tất quá trình thiết lập.

Cung cấp tên cho ứng dụng

Khi phiên bản được tạo, điều hướng tới trang cài đặt và sao chép database URL, bạn sẽ dùng nó để thiết lập một kết nối với database.

Sao chép URL

Thiết lập một server Flask

Trên terminal của bạn, tạo một thư mục dự án và thay đổi danh mục hiện tại cho thư mục mới đó.

Trước khi cài đặt Flask, xác nhận rằng bạn đang chạy Python 3.6+ trên máy tính. Nếu không, bạn cần cài phiên bản Python mới nhất.

python --version

Sau đó, cài virtualenv, để tạo một môi trường lập trình ảo biệt lập.

pip install virtualenv

Tiếp theo, chạy lệnh bên dưới để tạo một môi trường ảo.

pip install virtualenv

Cuối cùng, kích hoạt môi trường ảo.

# On Windows:
.\venv\Scripts\activate
# On Unix or MacOS:
source venv/bin/activate

Cài đặt các gói cần thiết

Ở thư mục gốc của thư mục dự án, tạo file requirements.txt và thêm những gói này.

flask
python-dotenv
psycopg2-binary

Tiếp theo, cài đặt các gói.

pip install -r requirements.txt

psycopg2-binary là một thư viện Python hoạt động giống như middleware (đoạn mã trung gian), cho phép bạn thiết lập kết nối với database Postgres và triển khai nhiều hoạt động database khác nhau.

Cuối cùng, tạo file .env và dán URL database của bạn.

DATABASE_URL= your database URL

Tạo server Flask

Cuối cùng, tạo file app.py ở thư mục gốc, và thêm code bên dưới.

import os
import psycopg2
from dotenv import load_dotenv
from flask import Flask, request, jsonify

load_dotenv()

app = Flask(__name__)
url = os.getenv("DATABASE_URL")
connection = psycopg2.connect(url)


@app.get("/")
def home():
    return "hello world"

Code này thiết lập một phiên bản của ứng dụng Flask. Sau đó, nó tạo một kết nối tới database được chỉ định trong chuỗi URL và cuối cùng, thiết lập “home route” trả về một chuỗi dưới dạng phản hồi.

Tạo REST API kích hoạt các hoạt động CRUD

Giờ xây dựng REST API thực hiện 4 hoạt động CRUD.

Tạo bảng demo

Tạo một bảng người dùng trong database. Ở file app.py, thêm code bên dưới.

CREATE_USERS_TABLE = "CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT);"

with connection:
    with connection.cursor() as cursor:
        cursor.execute(CREATE_USERS_TABLE)
  • Code này tạo một bảng PostgreSQL mang tên users với hai cột.
  • Nó dùng phương thức kết nối psycopg2 để thiết lập kết nối với database và tạo một đối tượng con trỏ mới bằng connection.cursor, được dùng để triển khai những truy vấn SQL.

1. Xác định phương thức POST

Tạo tuyến bài đăng để thêm dữ liệu

INSERT_USER_RETURN_ID = "INSERT INTO users (name) VALUES (%s) RETURNING id;"
@app.route("/api/user", methods=["POST"])
def create_user():
    data = request.get_json()
    name = data["name"]
    with connection:
        with connection.cursor() as cursor:
            cursor.execute(INSERT_USER_RETURN_ID, (name,))
            user_id = cursor.fetchone()[0]
    return {"id": user_id, "name": name, "message": f"User {name} created."}, 201
  • Chuỗi truy vấn SQL xác định lệnh SQL sẽ được triển khai bằng cursor.execute để chèn hàng mới với tên người dùng vào bảng users’ trong database. Nó trả về ID người dùng đã tạo mới.
  • Hàm create_user lấy tên là tham số lưu trữ ở database, còn cursor.fetchone được gọi để trích xuất ID người dùng đã tạo mới. Cuối cùng, một từ điển chứa ID và tên của người dùng mới được tạo, cùng với thông báo cho biết rằng người dùng đã được tạo thành công sẽ được trả về.

Tạo người dùng mới

2. Định nghĩa phương thức GET

Xác định hai đường đi: một để truy xuất tất cả dữ liệu trong cơ sở dữ liệu và hai là để truy xuất dữ liệu cụ thể từ cơ sở dữ liệu dựa trên ID.

SELECT_ALL_USERS = "SELECT * FROM users;"


@app.route("/api/user", methods=["GET"])
def get_all_users():
    with connection:
        with connection.cursor() as cursor:
            cursor.execute(SELECT_ALL_USERS)
            users = cursor.fetchall()
            if users:
                result = []
                for user in users:
                    result.append({"id": user[0], "name": user[1]})
                return jsonify(result)
            else:
                return jsonify({"error": f"Users not found."}), 404

@app.route("/api/user/<int:user_id>", methods=["GET"])
def get_user(user_id):
    with connection:
        with connection.cursor() as cursor:
            cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
            user = cursor.fetchone()
            if user:
                return jsonify({"id": user[0], "name": user[1]})
            else:
                return jsonify({"error": f"User with ID {user_id} not found."}), 404
  • API đầu tiên xử lý các truy vấn HTTP GET để trích xuất toàn bộ người dùng từ database và trả về kết quả ở định dạng JSON trong phản hồi.

API đầu tiên

API thứ hai xử lý các truy vấn HTTP GET để lấy dữ liệu cho một người dùng cụ thể từ database. Nó lấy user ID là tham số, trích xuất dữ liệu người dùng từ database và trả về kết quả ở định dạng JSON trong phản hồi.

API thứ hai

3. Xác định phương thức PUT

Tạo tuyến đường nhập để update dữ liệu được lưu trữ trong database.

@app.route("/api/user/<int:user_id>", methods=["PUT"])
def update_user(user_id):
    data = request.get_json()
    name = data["name"]
    with connection:
        with connection.cursor() as cursor:
            cursor.execute(UPDATE_USER_BY_ID, (name, user_id))
            if cursor.rowcount == 0:
                return jsonify({"error": f"User with ID {user_id} not found."}), 404
    return jsonify({"id": user_id, "name": name, "message": f"User with ID {user_id} updated."})
  • Hàm update_user lấy tham số ID người dùng làm trường nhập và dùng nó để update tên của người dùng được chỉ định trong database.
  • Nếu hoạt động update thành công, nó trả về một đối tượng JSON cùng với ID người dùng được cập nhật, tên và thông báo thành công trong phản hồi.

Định nghĩa người dùng

4. Xác định phương thức DELETE

Triển khai lộ trình xóa để loại bỏ dữ liệu được lưu trữ của một người dùng cụ thể ở database.

@app.route("/api/user/<int:user_id>", methods=["DELETE"])
def delete_user(user_id):
    with connection:
        with connection.cursor() as cursor:
            cursor.execute(DELETE_USER_BY_ID, (user_id,))
            if cursor.rowcount == 0:
                return jsonify({"error": f"User with ID {user_id} not found."}), 404
    return jsonify({"message": f"User with ID {user_id} deleted."})
  • Route API xử lý chức năng xóa của một người dùng cụ thể từ database dựa trên ID của họ. Nếu không thấy người dùng đó, nó trả về mã trạng thái 404 kèm thông báo lỗi. Tuy nhiên, nếu hoạt động xóa thành công, nó trả về đối tượng JSON cùng thông báo thành công.

Xóa người dùng theo ID

Trên đây là cách dùng Flask và Postgres để xây dựng CRUD REST API đơn giản. Hi vọng bài viết hữu ích với các bạn.

Thứ Ba, 28/03/2023 10:25
52 👨 901
0 Bình luận
Sắp xếp theo