Câu chuyện thực tế: Khi Script Python bỗng dưng ‘im hơi lặng tiếng’
2 giờ sáng, điện thoại mình rung liên hồi. Bot Telegram báo lỗi 502 Bad Gateway dồn dập từ hệ thống nhận Webhook của đối tác. Với lưu lượng khoảng 500 request mỗi phút, script xử lý cũ của công ty đã đổ sụp. Sau 15 phút kiểm tra log, mình nhận ra vấn đề: Đoạn code cũ chỉ chạy theo kiểu ‘đọc file rồi nghỉ’, nó hoàn toàn không có khả năng lắng nghe (listen) các request HTTP gửi tới liên tục.
Lúc đó, mình cần một giải pháp cực nhanh để dựng ‘cổng’ tiếp nhận dữ liệu JSON. Viết lại bằng Django thì quá cồng kềnh cho một tác vụ nhỏ. Dùng raw socket thì lại tốn cả ngày để xử lý đống header HTTP phức tạp. Flask xuất hiện như một cứu cánh đúng lúc.
Tại sao script bình thường không thể làm Server?
Lúc mới bắt đầu, chúng ta thường viết script chạy một lèo từ trên xuống rồi kết thúc. Nhưng để giao tiếp với App Mobile hay Frontend, code của bạn phải đóng vai trò là một Server.
Nó phải luôn ở trạng thái ‘treo’ để chờ kết nối. Nếu chỉ dùng code Python cơ bản, bạn sẽ dính lỗi ConnectionRefusedError ngay. Đơn giản vì không có port nào được mở để đón nhận dữ liệu. Một Framework chuẩn cần giúp bạn:
- Mở cổng kết nối (như port 5000 hoặc 8080).
- Bóc tách (parse) các request HTTP phức tạp thành dữ liệu dễ đọc.
- Trả về định dạng JSON chuẩn để các hệ thống khác hiểu được.
Ba lựa chọn phổ biến cho dân Backend Python
Đêm đó, mình đã cân nhắc nhanh 3 phương án:
- Module
http.servercó sẵn: Rất nhanh, không cần cài đặt. Tuy nhiên, nó cực kỳ thô sơ. Việc bóc tách dữ liệu từ POST request bằng module này là một cực hình. - FastAPI: Hiện đại, hỗ trợ async cực mạnh. Nhưng ngặt nỗi server cũ của công ty vẫn chạy Python 3.6, trong khi FastAPI yêu cầu bản cao hơn để tối ưu.
- Flask: Đây là ‘chân ái’ lúc đó. Flask là một micro-framework nhẹ và linh hoạt. Tài liệu trên Stack Overflow cực kỳ đồ sộ, giúp mình fix lỗi ngay cả trong trạng thái ngái ngủ.
Triển khai REST API với Flask trong 10 phút
Dưới đây là cách mình dựng lại Gateway tiếp nhận dữ liệu. Bạn có thể áp dụng ngay cho dự án của mình.
1. Thiết lập môi trường ‘sạch’
Đừng bao giờ cài thư viện trực tiếp vào Python hệ thống. Mình luôn dùng môi trường ảo (virtualenv) để tránh xung đột phiên bản, một lỗi rất dễ gây sập hệ thống khi deploy.
# Tạo và kích hoạt môi trường ảo
python -m venv venv
source venv/bin/activate # Trên Linux/macOS
# venv\Scripts\activate # Trên Windows
# Cài đặt Flask
pip install flask
2. API đầu tiên: Lắng nghe kết nối
Tạo file app.py với cấu trúc tối giản sau:
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/', methods=['GET'])
def home():
return jsonify({"status": "online", "message": "Server đã sẵn sàng!"})
if __name__ == '__main__':
app.run(debug=True, port=5000)
Chạy lệnh python app.py và truy cập http://localhost:5000. Bạn sẽ thấy dòng JSON trả về ngay lập tức.
3. Xử lý dữ liệu thực tế (POST Request)
Dữ liệu từ đối tác thường đẩy qua phương thức POST. Đây là cách mình xử lý để nhận và lưu trữ tạm thời:
from flask import Flask, request, jsonify
app = Flask(__name__)
data_store = []
@app.route('/api/webhook', methods=['POST'])
def handle_webhook():
# Lấy dữ liệu JSON từ request gửi đến
incoming_data = request.get_json()
if not incoming_data:
return jsonify({"error": "Dữ liệu trống!"}), 400
# Log dữ liệu để kiểm tra
print(f"Nhận được: {incoming_data}")
data_store.append(incoming_data)
return jsonify({"status": "success", "items_count": len(data_store)}), 201
if __name__ == '__main__':
# Dùng host='0.0.0.0' để máy khác có thể truy cập vào
app.run(host='0.0.0.0', port=5000)
Lời khuyên: Khi file code bắt đầu ‘phình’ to
Dự án của mình lúc đầu chỉ có 200 dòng code trong một file app.py. Sau vài tháng, yêu cầu thêm phân quyền và log khiến nó vọt lên 2000 dòng.
Lúc này, việc tìm kiếm bug trong một file duy nhất là thảm họa. Bạn nên chia nhỏ các Route bằng Blueprint ngay khi thấy dự án có dấu hiệu lớn dần. Đừng đợi đến lúc code rối như tơ vò mới lo refactor.
4. Test API nhanh bằng Terminal
Thay vì mở Postman nặng nề, mình thường dùng curl để test nhanh ngay trên terminal:
curl -X POST http://localhost:5000/api/webhook \
-H "Content-Type: application/json" \
-d '{"id": 101, "event": "payment_success"}'
Những ‘tử huyệt’ cần tránh khi đưa API lên Production
Để API chạy bền bỉ và không bị sếp gọi lúc nửa đêm, hãy nhớ 3 quy tắc thép:
- Tuyệt đối không dùng
app.run()để chạy thật: Server mặc định của Flask chỉ phục vụ việc code (dev). Nó không chịu tải được. Hãy dùng Gunicorn hoặc uWSGI để chạy ứng dụng thực tế. - Đừng tin dữ liệu người dùng: Luôn dùng thư viện như
pydanticđể kiểm tra định dạng JSON. Một field bị thiếu có thể làm sập toàn bộ logic xử lý phía sau. - Bắt lỗi chặt chẽ: Luôn bọc code trong
try...except. Đừng bao giờ để API trả về một trang lỗi trắng xóa kèm mã nguồn Python (traceback). Đó là miếng mồi ngon cho hacker.
Xây dựng REST API với Flask không khó, nhưng để nó ‘sống sót’ qua những đợt cao điểm lại cần sự tỉ mỉ. Từ một đoạn script cứu nguy lúc 2 giờ sáng, mình đã biến nó thành một hệ thống ổn định nhờ việc cấu trúc hóa đúng cách ngay từ đầu.

