HomeLập trìnhPythonCách xây dựng...

Cách xây dựng API JSON bằng Python


Đặc tả API JSON là một cách mạnh mẽ để cho phép giao tiếp giữa máy khách và máy chủ. Nó chỉ định cấu trúc của các yêu cầu và phản hồi được gửi giữa hai bên, sử dụng định dạng JSON.

Là một định dạng dữ liệu, JSON có ưu điểm là nhẹ và dễ đọc. Điều này làm cho nó rất dễ dàng để làm việc với một cách nhanh chóng và hiệu quả. Thông số kỹ thuật được thiết kế để giảm thiểu số lượng yêu cầu và lượng dữ liệu cần gửi giữa máy khách và máy chủ.

Tại đây, bạn có thể tìm hiểu cách tạo API JSON cơ bản bằng Python và Flask. Sau đó, phần còn lại của bài viết sẽ chỉ cho bạn cách thử một số tính năng mà đặc tả API JSON cung cấp.

Flask là một thư viện Python cung cấp ‘khuôn khổ vi mô’ để phát triển web. Thật tuyệt vời cho sự phát triển nhanh chóng vì nó đi kèm với chức năng cốt lõi đơn giản nhưng có thể mở rộng.

Một ví dụ thực sự cơ bản về cách gửi phản hồi giống như JSON bằng Flask được hiển thị bên dưới:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def example():
   return '{"name":"Bob"}'

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

Bài viết này sẽ sử dụng hai add-on cho Flask:

bức tranh lớn

Mục tiêu cuối cùng là tạo một API cho phép tương tác phía máy khách với cơ sở dữ liệu bên dưới. Sẽ có một vài lớp giữa cơ sở dữ liệu và máy khách – lớp trừu tượng hóa dữ liệu và lớp quản lý tài nguyên.

lưu lượng

Dưới đây là tổng quan về các bước liên quan:

  1. Xác định cơ sở dữ liệu bằng Flask-SQLAlchemy
  2. Tạo trừu tượng hóa dữ liệu với Marshmallow-JSONAPI
  3. Tạo trình quản lý tài nguyên với Flask-REST-JSONAPI
  4. Tạo điểm cuối URL và khởi động máy chủ bằng Flask

Ví dụ này sẽ sử dụng một lược đồ đơn giản mô tả các nghệ sĩ hiện đại và mối quan hệ của họ với các tác phẩm nghệ thuật khác nhau.

Cài đặt mọi thứ

Trước khi bắt đầu, bạn sẽ cần thiết lập dự án. Điều này liên quan đến việc tạo một không gian làm việc và môi trường ảo, cài đặt các mô-đun cần thiết và tạo các tệp cơ sở dữ liệu và Python chính cho dự án.

Từ dòng lệnh tạo một thư mục mới và điều hướng bên trong.

$ mkdir flask-jsonapi-demo
$ cd flask-jsonapi-demo/

Bạn nên tạo môi trường ảo cho từng dự án Python của mình. Bạn có thể bỏ qua bước này, nhưng nó được khuyến khích mạnh mẽ.

$ python -m venv .venv
$ source .venv/bin/activate

Khi môi trường ảo của bạn đã được tạo và kích hoạt, bạn có thể cài đặt các mô-đun cần thiết cho dự án này.

$ pip install flask-rest-jsonapi flask-sqlalchemy

Mọi thứ bạn cần sẽ được cài đặt theo yêu cầu cho hai tiện ích mở rộng này. Điều này bao gồm chính Flask và SQLAlchemy.

Bước tiếp theo là tạo tệp Python và cơ sở dữ liệu cho dự án.

$ touch application.py artists.db

Tạo lược đồ cơ sở dữ liệu

Tại đây, bạn sẽ bắt đầu sửa đổi application.py để xác định và tạo lược đồ cơ sở dữ liệu cho dự án.

Mở application.py trong trình soạn thảo văn bản ưa thích của bạn. Bắt đầu bằng cách nhập một số mô-đun. Để rõ ràng, các mô-đun sẽ được nhập khi bạn thực hiện.

Tiếp theo, tạo một đối tượng được gọi là app như một thể hiện của lớp Flask.

Sau đó, sử dụng SQLAlchemy để kết nối với tệp cơ sở dữ liệu bạn đã tạo. Bước cuối cùng là xác định và tạo một bảng gọi là artists.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# Create a new Flask application
app = Flask(__name__)

# Set up SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////artists.db'
db = SQLAlchemy(app)

# Define a class for the Artist table
class Artist(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    birth_year = db.Column(db.Integer)
    genre = db.Column(db.String)

# Create the table
db.create_all()

Tạo một lớp trừu tượng

Bước tiếp theo sử dụng mô-đun Marshmallow-JSONAPI để tạo một dữ liệu logic trừu tượng trên các bảng vừa được xác định.

Đọc thêm  Cách bảo mật cơ sở hạ tầng không dây tại nhà của bạn bằng Kismet và Python

Lý do để tạo lớp trừu tượng này rất đơn giản. Nó cung cấp cho bạn nhiều quyền kiểm soát hơn đối với cách dữ liệu cơ bản của bạn được hiển thị thông qua API. Hãy nghĩ về lớp này như một thấu kính mà qua đó ứng dụng khách API có thể xem dữ liệu cơ bản một cách rõ ràng và chỉ những bit họ cần xem.

Untitled-Sơ đồ-Trang-2

Trong mã bên dưới, lớp trừu tượng hóa dữ liệu được định nghĩa là một lớp kế thừa từ Marshmallow-JSONAPI’s Schema lớp. Nó sẽ cung cấp quyền truy cập thông qua API cho cả bản ghi đơn và nhiều bản ghi từ bảng nghệ sĩ.

Bên trong khối này, Meta class định nghĩa một số siêu dữ liệu. Cụ thể, tên của điểm cuối URL để tương tác với các bản ghi đơn lẻ sẽ là artist_onetrong đó mỗi nghệ sĩ sẽ được xác định bằng một tham số URL <id>. Tên của điểm cuối để tương tác với nhiều bản ghi sẽ là artist_many.

Các thuộc tính còn lại được xác định liên quan đến các cột trong bảng nghệ sĩ. Tại đây, bạn có thể kiểm soát thêm cách mỗi thứ được hiển thị thông qua API.

Ví dụ: khi thực hiện yêu cầu POST để thêm nghệ sĩ mới vào cơ sở dữ liệu, bạn có thể đảm bảo rằng name trường là bắt buộc bằng cách đặt required=True.

Và nếu vì bất kỳ lý do gì bạn không muốn birth_year trường được trả về khi thực hiện yêu cầu GET, bạn có thể chỉ định như vậy bằng cách đặt load_only=True.

from marshmallow_jsonapi.flask import Schema
from marshmallow_jsonapi import fields

# Create data abstraction layer
class ArtistSchema(Schema):
    class Meta:
        type_ = 'artist'
        self_view = 'artist_one'
        self_view_kwargs = {'id': '<id>'}
        self_view_many = 'artist_many'

    id = fields.Integer()
    name = fields.Str(required=True)
    birth_year = fields.Integer(load_only=True)
    genre = fields.Str()

Tạo trình quản lý tài nguyên và điểm cuối URL

Phần cuối cùng của câu đố là tạo một trình quản lý tài nguyên và điểm cuối tương ứng cho mỗi tuyến đường /artists và /artists/id.

Mỗi trình quản lý tài nguyên được định nghĩa là một lớp kế thừa từ các lớp Flask-REST-JSONAPI ResourceListResourceDetail.

Ở đây họ có hai thuộc tính. schema được sử dụng để biểu thị lớp trừu tượng hóa dữ liệu mà trình quản lý tài nguyên sử dụng và data_layer cho biết phiên và mô hình dữ liệu sẽ được sử dụng cho lớp dữ liệu.

Tiếp theo, xác định api như một phiên bản của Flask-REST-JSONAPI’s Api lớp và tạo các tuyến cho API với api.route(). Phương thức này nhận ba đối số – lớp lớp trừu tượng hóa dữ liệu, tên điểm cuối và đường dẫn URL.

Bước cuối cùng là viết một vòng lặp chính để khởi chạy ứng dụng ở chế độ gỡ lỗi khi tập lệnh được chạy trực tiếp. Chế độ gỡ lỗi rất phù hợp để phát triển, nhưng nó không phù hợp để chạy trong sản xuất.

# Create resource managers and endpoints

from flask_rest_jsonapi import Api, ResourceDetail, ResourceList

class ArtistMany(ResourceList):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}

class ArtistOne(ResourceDetail):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}

api = Api(app)
api.route(ArtistMany, 'artist_many', '/artists')
api.route(ArtistOne, 'artist_one', '/artists/<int:id>')

# main loop to run app in debug mode
if __name__ == '__main__':
    app.run(debug=True)

Thực hiện các yêu cầu GET và POST

Bây giờ bạn có thể bắt đầu sử dụng API để thực hiện các yêu cầu HTTP. Điều này có thể từ trình duyệt web hoặc từ công cụ dòng lệnh như curl hoặc từ bên trong chương trình khác (ví dụ: tập lệnh Python sử dụng thư viện Yêu cầu).

Để khởi chạy máy chủ, hãy chạy application.py kịch bản với:

$ python application.py

Trong trình duyệt của bạn, điều hướng đến http://localhost:5000/artists. Bạn sẽ thấy đầu ra JSON của tất cả các bản ghi trong cơ sở dữ liệu cho đến nay. Ngoại trừ, không có.

Để bắt đầu thêm bản ghi vào cơ sở dữ liệu, bạn có thể thực hiện yêu cầu POST. Một cách để làm điều này là từ dòng lệnh sử dụng curl. Ngoài ra, bạn có thể sử dụng công cụ như Insomnia hoặc có thể viết mã giao diện người dùng HTML đơn giản để đăng dữ liệu bằng biểu mẫu.

Đọc thêm  Cách sử dụng đối tượng timedelta trong Python để làm việc với ngày tháng

Với curl, từ dòng lệnh:

curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artist", "attributes":{"name":"Salvador Dali", "birth_year":1904, "genre":"Surrealism"}}}' http://localhost:5000/artists

Bây giờ nếu bạn điều hướng đến http://localhost:5000/artists, bạn sẽ thấy bản ghi mà bạn vừa thêm vào. Nếu bạn thêm nhiều bản ghi hơn, tất cả chúng cũng sẽ hiển thị ở đây vì đường dẫn URL này gọi artists_many điểm cuối.

Để xem chỉ một nghệ sĩ duy nhất của họ id số, bạn có thể điều hướng đến URL có liên quan. Ví dụ: để xem nghệ sĩ đầu tiên, hãy thử http://localhost:5000/artists/1.

Lọc và sắp xếp

Một trong những tính năng thú vị của đặc tả API JSON là khả năng trả về phản hồi theo những cách hữu ích hơn bằng cách xác định một số tham số trong URL. Chẳng hạn, bạn có thể sắp xếp kết quả theo trường đã chọn hoặc lọc dựa trên một số tiêu chí.

Flask-REST-JSONAPI được tích hợp sẵn.

Để sắp xếp các nghệ sĩ theo thứ tự năm sinh, chỉ cần điều hướng đến http://localhost:5000/artists?sort=birth_year. Trong một ứng dụng web, điều này sẽ giúp bạn không phải sắp xếp kết quả ở phía máy khách, điều này có thể gây tốn kém về hiệu suất và do đó ảnh hưởng đến trải nghiệm người dùng.

Lọc cũng dễ dàng. Bạn thêm tiêu chí bạn muốn lọc vào URL, nằm trong dấu ngoặc vuông. Có ba phần thông tin bao gồm:

  • “tên” – trường bạn đang lọc theo (ví dụ: birth_year)
  • “op” – thao tác lọc (“bằng”, “lớn hơn”, “nhỏ hơn”, v.v.)
  • “val” – giá trị để lọc theo (ví dụ: 1900)

Ví dụ: URL bên dưới truy xuất các nghệ sĩ có năm sinh lớn hơn 1900:

http://localhost:5000/artists?filter=[{“name”:”birth_year”,”op”:”gt”,”val”:1900}]

Chức năng này giúp việc chỉ truy xuất thông tin liên quan khi gọi API trở nên dễ dàng hơn nhiều. Điều này có giá trị để cải thiện hiệu suất, đặc biệt là khi truy xuất khối lượng dữ liệu lớn qua kết nối chậm.

Một tính năng khác của đặc tả API JSON hỗ trợ hiệu suất là phân trang. Đây là khi các phản hồi lớn được gửi qua nhiều “trang”, thay vì tất cả trong một lần. Bạn có thể kiểm soát kích thước trang và số lượng trang bạn yêu cầu trong URL.

Vì vậy, ví dụ: bạn có thể nhận được 100 kết quả trên 10 trang thay vì tải tất cả 100 kết quả trong một lần. Trang đầu tiên sẽ chứa kết quả 1-10, trang thứ hai sẽ chứa kết quả 11-20, v.v.

Để chỉ định số lượng kết quả bạn muốn nhận trên mỗi trang, bạn có thể thêm tham số ?page[size]=X vào URL, trong đó X là số lượng kết quả. Flask-REST-JSONAPI sử dụng 30 làm kích thước trang mặc định.

Để yêu cầu một số trang nhất định, bạn có thể thêm tham số ?page[number]=X, số trang ở đâu. Bạn có thể kết hợp cả hai tham số như hình dưới đây:

http://localhost:5000/artists?page[size]=2&trang[number]=2

URL này đặt kích thước trang thành hai kết quả trên mỗi trang và yêu cầu trang kết quả thứ hai. Điều này sẽ trả về kết quả thứ ba và thứ tư từ phản hồi tổng thể.

Các mối quan hệ

Hầu như luôn luôn, dữ liệu trong một bảng sẽ liên quan đến dữ liệu được lưu trữ trong một bảng khác. Ví dụ: nếu bạn có một bảng nghệ sĩ, rất có thể bạn cũng muốn có một bảng tác phẩm nghệ thuật. Mỗi tác phẩm nghệ thuật có liên quan đến nghệ sĩ đã tạo ra nó.

Đặc tả API JSON cho phép bạn làm việc với dữ liệu quan hệ một cách dễ dàng và Flask-REST-JSONAPI cho phép bạn tận dụng điều này. Ở đây, điều này sẽ được chứng minh bằng cách thêm một bảng tác phẩm nghệ thuật vào cơ sở dữ liệu và bao gồm các mối quan hệ giữa nghệ sĩ và tác phẩm nghệ thuật.

Để triển khai ví dụ về tác phẩm nghệ thuật, cần phải thực hiện một vài thay đổi đối với mã trong application.py.

Đầu tiên, thực hiện một vài lần nhập bổ sung, sau đó tạo một bảng mới liên kết từng tác phẩm nghệ thuật với một nghệ sĩ:

from marshmallow_jsonapi.flask import Relationship
from flask_rest_jsonapi import ResourceRelationship


# Define the Artwork table
class Artwork(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    artist_id = db.Column(db.Integer, 
        db.ForeignKey('artist.id'))
    artist = db.relationship('Artist',
        backref=db.backref('artworks'))

Tiếp theo, viết lại lớp trừu tượng:

# Create data abstraction 
class ArtistSchema(Schema):
    class Meta:
        type_ = 'artist'
        self_view = 'artist_one'
        self_view_kwargs = {'id': '<id>'}
        self_view_many = 'artist_many'

    id = fields.Integer()
    name = fields.Str(required=True)
    birth_year = fields.Integer(load_only=True)
    genre = fields.Str()
    artworks = Relationship(self_view = 'artist_artworks',
        self_view_kwargs = {'id': '<id>'},
        related_view = 'artwork_many',
        many = True,
        schema="ArtworkSchema",
        type_ = 'artwork')

class ArtworkSchema(Schema):
    class Meta:
        type_ = 'artwork'
        self_view = 'artwork_one'
        self_view_kwargs = {'id': '<id>'}
        self_view_many = 'artwork_many'

    id = fields.Integer()
    title = fields.Str(required=True)
    artist_id = fields.Integer(required=True)

Điều này xác định một lớp trừu tượng cho bảng tác phẩm nghệ thuật và thêm mối quan hệ giữa nghệ sĩ và tác phẩm nghệ thuật vào bảng ArtistSchema lớp.

Đọc thêm  Cách sử dụng Python trong Power BI

Tiếp theo, xác định các trình quản lý tài nguyên mới để truy cập nhiều tác phẩm nghệ thuật cùng lúc và mỗi lần một tác phẩm, đồng thời cũng để truy cập các mối quan hệ giữa nghệ sĩ và tác phẩm nghệ thuật.

class ArtworkMany(ResourceList):
    schema = ArtworkSchema
    data_layer = {'session': db.session,
                  'model': Artwork}

class ArtworkOne(ResourceDetail):
    schema = ArtworkSchema
    data_layer = {'session': db.session,
                  'model': Artwork}

class ArtistArtwork(ResourceRelationship):
    schema = ArtistSchema
    data_layer = {'session': db.session,
                  'model': Artist}

Cuối cùng, thêm một số điểm cuối mới:

api.route(ArtworkOne, 'artwork_one', '/artworks/<int:id>')
api.route(ArtworkMany, 'artwork_many', '/artworks')
api.route(ArtistArtwork, 'artist_artworks',
    '/artists/<int:id>/relationships/artworks')

Chạy application.py và thử đăng một số dữ liệu từ dòng lệnh qua curl:

curl -i -X POST -H 'Content-Type: application/json' -d '{"data":{"type":"artwork", "attributes":{"title":"The Persistance of Memory", "artist_id":1}}}' http://localhost:5000/artworks

Điều này sẽ tạo ra một tác phẩm nghệ thuật liên quan đến nghệ sĩ với id=1.

Trong trình duyệt, điều hướng đến http://localhost:5000/artists/1/relationships/artworks. Điều này sẽ hiển thị các tác phẩm nghệ thuật liên quan đến nghệ sĩ với id=1. Điều này giúp bạn không phải viết một URL phức tạp hơn với các tham số để lọc các tác phẩm nghệ thuật theo artist_id cánh đồng. Bạn có thể nhanh chóng liệt kê tất cả các mối quan hệ giữa một nghệ sĩ nhất định và tác phẩm nghệ thuật của họ.

Một tính năng khác là khả năng bao gồm các kết quả liên quan trong phản hồi để gọi artists_one điểm cuối:

http://localhost:5000/artists/1?include=artworks

Điều này sẽ trả về phản hồi thông thường cho điểm cuối của nghệ sĩ và cũng là kết quả cho từng tác phẩm nghệ thuật của nghệ sĩ đó.

Ruộng thưa

Một tính năng cuối cùng đáng nói – các trường thưa thớt. Khi làm việc với các nguồn dữ liệu lớn có nhiều mối quan hệ phức tạp, kích thước phản hồi có thể tăng lên rất nhanh. Sẽ rất hữu ích nếu chỉ truy xuất các trường mà bạn quan tâm.

Đặc tả API JSON cho phép bạn thực hiện việc này bằng cách thêm tham số trường vào URL. Ví dụ: URL bên dưới nhận phản hồi cho một nghệ sĩ nhất định và các tác phẩm nghệ thuật có liên quan của họ. Tuy nhiên, thay vì trả về tất cả các trường cho tác phẩm nghệ thuật nhất định, nó chỉ trả về tiêu đề.

http://localhost:5000/artists/1?include=artworks&fields[artwork]= tiêu đề

Điều này một lần nữa rất hữu ích để cải thiện hiệu suất, đặc biệt là khi kết nối chậm. Theo nguyên tắc chung, bạn chỉ nên thực hiện các yêu cầu đến và từ máy chủ với lượng dữ liệu tối thiểu được yêu cầu.

Đặc tả API JSON là một khung rất hữu ích để gửi dữ liệu giữa máy chủ và máy khách ở định dạng rõ ràng, linh hoạt. Bài viết này đã cung cấp một cái nhìn tổng quan về những gì bạn có thể làm với nó, với một ví dụ hoạt động bằng Python sử dụng thư viện Flask-REST-JSONAPI.

Vậy bạn sẽ làm gì tiếp theo? Có rất nhiều khả năng. Ví dụ trong bài viết này là một bằng chứng về khái niệm đơn giản, chỉ với hai bảng và một mối quan hệ duy nhất giữa chúng. Bạn có thể phát triển một ứng dụng phức tạp như bạn muốn và tạo một API mạnh mẽ để tương tác với nó bằng cách sử dụng tất cả các công cụ được cung cấp tại đây.

Cảm ơn bạn đã đọc và hãy tiếp tục viết mã bằng Python!



Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status