Việc kết hợp Flask-RESTful và SQLAlchemy mang lại một kiến trúc mạnh mẽ để phát triển các dịch vụ Web API. Flask-RESTful giúp chuẩn hóa việc định nghĩa tài nguyên (Resources), trong khi SQLAlchemy đóng vai trò là một ORM (Object-Relational Mapping) mạnh mẽ để quản lý cơ sở dữ liệu. Dưới đây là hướng dẫn chi tiết các bước để thiết lập một hệ thống API hoàn chỉnh.
1. Thiết lập môi trường và cài đặt thư viện
Trước tiên, bạn cần cài đặt các gói thư viện cần thiết thông qua pip. Đảm bảo bạn đang sử dụng một môi trường ảo (virtual environment) để tránh xung đột phiên bản.
pip install Flask Flask-RESTful Flask-SQLAlchemy
2. Cấu trúc thư mục dự án
Một cấu trúc thư mục phân lớp rõ ràng sẽ giúp dự án dễ bảo trì và mở rộng hơn:
my_api_project/
├── core/
│ ├── __init__.py
│ ├── database.py # Cấu hình SQLAlchemy
│ └── resources.py # Định nghĩa các API endpoints
├── app.py # Điểm khởi chạy ứng dụng
└── storage.db # Cơ sở dữ liệu SQLite (tự động tạo)
3. Định nghĩa Model với SQLAlchemy
Trong tệp core/database.py, chúng ta sẽ khởi tạo SQLAlchemy và định nghĩa cấu trúc bảng dữ liệu. Ví dụ dưới đây quản lý thông tin khách hàng (Customer):
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Customer(db.Model):
__tablename__ = 'customers'
id = db.Column(db.Integer, primary_key=True)
full_name = db.Column(db.String(100), nullable=False)
contact_email = db.Column(db.String(120), unique=True, nullable=False)
def to_json(self):
return {
"id": self.id,
"name": self.full_name,
"email": self.contact_email
}
4. Xây dựng tài nguyên API với Flask-RESTful
Tại core/resources.py, chúng ta sử dụng class Resource để xử lý các phương thức HTTP. Đồng thời, reqparse sẽ được dùng để kiểm tra dữ liệu đầu vào.
from flask_restful import Resource, reqparse, abort
from .database import db, Customer
class CustomerResource(Resource):
def get(self, customer_id):
entity = Customer.query.get(customer_id)
if not entity:
abort(404, message="Khách hàng không tồn tại")
return entity.to_json(), 200
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('full_name', type=str, required=True, help='Họ tên là bắt buộc')
parser.add_argument('contact_email', type=str, required=True, help='Email là bắt buộc')
args = parser.parse_args()
new_customer = Customer(full_name=args['full_name'], contact_email=args['contact_email'])
try:
db.session.add(new_customer)
db.session.commit()
return new_customer.to_json(), 201
except Exception:
abort(400, message="Lỗi khi tạo mới khách hàng (có thể trùng email)")
5. Khởi tạo ứng dụng và đăng ký Route
Cuối cùng, trong tệp app.py, chúng ta kết nối tất cả các thành phần lại với nhau, cấu hình cơ sở dữ liệu và đăng ký các endpoint.
from flask import Flask
from flask_restful import Api
from core.database import db
from core.resources import CustomerResource
def create_app():
app = Flask(__name__)
# Cấu hình database SQLite
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///storage.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
api = Api(app)
# Đăng ký các Resource
api.add_resource(CustomerResource, '/customers', '/customers/<int:customer_id>')
# Tạo bảng dữ liệu nếu chưa có
with app.app_context():
db.create_all()
return app
if __name__ == '__main__':
main_app = create_app()
main_app.run(debug=True)
Các tính năng mở rộng cần lưu ý
- Xác thực (Authentication): Bạn có thể tích hợp thêm Flask-JWT-Extended để bảo mật các tài nguyên API.
- Phân trang (Pagination): Sử dụng phương thức
paginate()của SQLAlchemy để xử lý tập dữ liệu lớn khi gọi GET. - Xử lý lỗi: Flask-RESTful cho phép tùy chỉnh định dạng thông báo lỗi JSON để nhất quán với client-side.