Xây dựng dựng dụng REST API đơn giản với FLASK

Introduction

RestFull API, chắc hẳn các bạn đã nghe đến cái tên này khá nhiều trong cuộc đời người làm lập trình. Việc xây dựng một ứng dụng REST API cũng ko hề khó. Bài viết này, tôi sẽ hướng dẫn các bạn xây dựng một ứng dụng REST API đơn giản sử dụng Flask (một framwork đơn giản, nhẹ nhàng, và cũng rất dễ dàng để học của python).

Trước khi bắt đầu, các bạn có thể tham khảo bài viết này để hiểu rõ hơn về REST API.

Let Get Started!!!

Trước tiên, hãy tạo workspace để chứa source code của bạn chứ nhỉ

$ mkdir flask_example & cd flask_example/

Tiếp theo là tạo môi trường ảo để chạy Python 2.7

flask_example$ virtualenv venv
flask_example$ source venv/bin/activate

Add các files dưới đây vào ứng dụng của bạn.

(venv) flask_example$ touch app.py .gitignore README.md requirements.txt

Bạn có thể thấy, ứng dựng flask đơn giản của bạn sẽ có cấu trúc cơ bản như bên dưới.

├── .gitignore

├── app.py

├── README.md

└── requirements.txt

Với một ứng dụng Flask, dĩ nhiên bạn không thể không cài đặt flask cho ứng dụng của mh

(venv) flask_example$ pip install flask flask-api

Thêm các thư viện đã cài đặt vào file requirements.txt. Bước này rất quan trọng khi bạn thực thiện build lại ứng dụng của mh trên một môi trường khác. Bạn chỉ cần cài đặt lại các thư viện cần thiện thông qua file requirements.txt này là được.

pip freeze > requirements.txt

Mọi thứ khởi đầu có vẻ như đã hoàn thành, giờ chúng ta cùng bắt tay vào code những dòng đầu tiên với Flask.

Hello World!

"Hello World" là đoạn message vô cùng quen thuộc, bây giờ chúng ta cùng viết đoạn script ngắn để trả về message này nhé.

Đầu tiên hãy mở file app.py và làm như sau:

from flask_api import FlaskAPI

app = FlaskAPI(__name__)

@app.route('/')
def helloworld():
    return {
        "message": "Hello World!"
    }

if __name__ == '__main__':
    app.run()

chạy ứng dụng của bạn và chờ đợi điều kì diệu .............

(venv) flask_example$ python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Đoạn code nho nhỏ trên sẽ trả về cho bạn một đoạn json với nội dung như thế này:

HTTP 200 OK
Content-Type: application/json

{
    "message": "Hello World!"
}

Hoặc bạn có thể vào link http://127.0.0.1:5000/ để xem kết quả 😉

Với một ứng dụng API, đơn giản hơn hết bạn chỉ cần định nghĩa format trả về dữ liệu của nó là dạng json vậy là bạn đã có một ứng dụng vô cùng đơn giản. Tuy nhiên trong quá trình làm việc, mọi thứ đâu hề đơn giản đến như vậy. Bạn cần phải làm việc thường xuyên với database, phải insert, truy vấn dữ liệu ..... Dĩ nhiên việc có một database để lưu trữ dữ liệu là không không thể thiếu. Ỏe bước tiếp theo, tôi sẽ hưỡng dẫn các bạn làm việc với database, cụ thể ở bài viết này, tôi sử dụng postgeSQL.

Working with database

Các thư viện mà tôi sẽ sử dụng ở bước này bao gồm:

  • PostgreSQL
  • Psycopg2
  • Flask-SQLAlchemy
  • Flask-Migate

Lưu ý, môi trường làm việc của bạn cần phải được cài đặt sẵn PostgreSQL mới có thể làm việc được nhé. Bây giờ, hãy tạo một database để lưu dữ liệu

$ sudo -u postgres psql
psql (9.5.12)
Type "help" for help.
# create database flask_example_dev
# \q

Cài đặt các thư viện sẽ dùng để kết nối database mà tôi để kể trên

(venv) flask_example$ pip install psycopg2 Flask-SQLAlchemy Flask-Migrate
(venv) flask_example$ pip freeze > requirements.txt

Config settings

File config, ko thể thiếu trong một ứng dụng web service, nó sẽ cũng cập các cài đặt môi trường, thiết lập database.... Bạn cần phải đưa ra các định nghĩa môi trường để ứng dụng của bạn có thể hoạt động được cở các môi trường khác nhau.

(venv) flask_example$ touch config.py

Và thêm các dòng config sau vào file vừa tạo

import os
basedir = os.path.abspath(os.path.dirname(__file__))


class Config(object):
    DEBUG = False
    TESTING = False
    CSRF_ENABLED = True
    SECRET_KEY = 'add-your-key'
    SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']

class ProductionConfig(Config):
    DEBUG = False


class StagingConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class DevelopmentConfig(Config):
    DEVELOPMENT = True
    DEBUG = True


class TestingConfig(Config):
    TESTING = True

Trên terminal bạn thêm DATABASE_URL variable như sau:

$ export DATABASE_URL="postgresql://localhost/flask_example_dev"

và add dòng trên vào file .env

Tiếp nữa trong file app.py bạn cần import SQLAlchemy để connect tới database

from flask_api import FlaskAPI
from flask_sqlalchemy import SQLAlchemy
import os

app = FlaskAPI(__name__)
app.secret_key = os.urandom(24)
app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

from models import *

@app.route('/')
def helloworld():
    return {
        "message": "Hello World!"
    }

if __name__ == '__main__':
    app.run()

Data Model

Bạn có thể setup 1 models đơn giản bằng cách thêm vào models.py nội dung sau:

from app import db
from sqlalchemy.dialects.postgresql import JSON


class Article(db.Model):
    __tablename__ = 'articles'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String())
    contents = db.Column(db.String())
    image = db.Column(db.String())

    def __init__(self, title, contents, image):
        self.title = title
        self.contents = contents
        self.image = image

    def __repr__(self):
        return '<id {}>'.format(self.id)

Với nội dung models như trên, tôi đang định nghĩa một class có tên Article tương ứng với bảng articles trong database. Bảng này sẽ bao gồm các trường:

  • id: Định danh của 1 bản ghi dữ liệu
  • title: tiêu đề của bài viết
  • contents: nội dung bài viết
  • image: hình ảnh tượng trưng cho bài viết

Function init() sẽ chạy khi bạn tạo dữ liệu lần đầu tiên. với định nghĩa function như trên, 3 trường title, contents, image là bắt buộc, nếu thiếu bất kì trường nào trong cá trường trên dữ liệu sẽ không được lưu vào trong database. Và method repr() biểu diễn objects trả về khi bạn query đến nó.

Local Migrate

Để quản lý database migation và update database's chema, chúng ta sẽ sử dụng Flask-Migrate. Đầu tiên bạn cần phải tạo 1 file: manage.py với nội dung sau:

import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand

from app import app, db

app.config.from_object(os.environ['APP_SETTINGS'])

migrate = Migrate(app, db)
manager = Manager(app)

manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
   manager.run()

Tiếp theo đinhj nghĩa môi trường chạy ứng dụng

export APP_SETTINGS="config.DevelopmentConfig"

OK, vậy là xong, giờ chúng ta cùng init database và chạy migrate command với lệnh

$ python manage.py db init
$ python manage.py db migrate

và cuối cùng bạn cần upgrades database để apply bản versions schema mới nhất.

$ python manage.py db upgrade

Vậy là bước kết nối tới database của chúng ta đã xong. Ở bài viết sau, tôi sẽ hướng dẫn các bạn tạo ứng dụng CRUD với Fask API. Mong các bạn sẽ ủng hộ.

Tài liệu tham khảo