Bỏ qua

Những bước đầu tiên

Tệp tin FastAPI đơn giản nhất có thể trông như này:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Sao chép sang một tệp tin main.py.

Chạy live server:

$ uvicorn main:app --reload

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
<span style="color: green;">INFO</span>:     Started reloader process [28720]
<span style="color: green;">INFO</span>:     Started server process [28722]
<span style="color: green;">INFO</span>:     Waiting for application startup.
<span style="color: green;">INFO</span>:     Application startup complete.

Note

Câu lệnh uvicorn main:app được giải thích như sau:

  • main: tệp tin main.py (một Python "mô đun").
  • app: một object được tạo ra bên trong main.py với dòng app = FastAPI().
  • --reload: làm server khởi động lại sau mỗi lần thay đổi. Chỉ sử dụng trong môi trường phát triển.

Trong output, có một dòng giống như:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Dòng đó cho thấy URL, nơi mà app của bạn đang được chạy, trong máy local của bạn.

Kiểm tra

Mở trình duyệt của bạn tại http://127.0.0.1:8000.

Bạn sẽ thấy một JSON response như:

{"message": "Hello World"}

Tài liệu tương tác API

Bây giờ tới http://127.0.0.1:8000/docs.

Bạn sẽ thấy một tài liệu tương tác API (cung cấp bởi Swagger UI):

Swagger UI

Phiên bản thay thế của tài liệu API

Và bây giờ tới http://127.0.0.1:8000/redoc.

Bạn sẽ thấy một bản thay thế của tài liệu (cung cấp bởi ReDoc):

ReDoc

OpenAPI

FastAPI sinh một "schema" với tất cả API của bạn sử dụng tiêu chuẩn OpenAPI cho định nghĩa các API.

"Schema"

Một "schema" là một định nghĩa hoặc mô tả thứ gì đó. Không phải code triển khai của nó, nhưng chỉ là một bản mô tả trừu tượng.

API "schema"

Trong trường hợp này, OpenAPI là một bản mô tả bắt buộc cơ chế định nghĩa API của bạn.

Định nghĩa cấu trúc này bao gồm những đường dẫn API của bạn, các tham số có thể có,...

"Cấu trúc" dữ liệu

Thuật ngữ "cấu trúc" (schema) cũng có thể được coi như là hình dạng của dữ liệu, tương tự như một JSON content.

Trong trường hợp đó, nó có nghĩa là các thuộc tính JSON và các kiểu dữ liệu họ có,...

OpenAPI và JSON Schema

OpenAPI định nghĩa một cấu trúc API cho API của bạn. Và cấu trúc đó bao gồm các dịnh nghĩa (or "schema") về dữ liệu được gửi đi và nhận về bởi API của bạn, sử dụng JSON Schema, một tiêu chuẩn cho cấu trúc dữ liệu JSON.

Kiểm tra openapi.json

Nếu bạn tò mò về việc cấu trúc OpenAPI nhìn như thế nào thì FastAPI tự động sinh một JSON (schema) với các mô tả cho tất cả API của bạn.

Bạn có thể thấy nó trực tiếp tại: http://127.0.0.1:8000/openapi.json.

Nó sẽ cho thấy một JSON bắt đầu giống như:

{
    "openapi": "3.1.0",
    "info": {
        "title": "FastAPI",
        "version": "0.1.0"
    },
    "paths": {
        "/items/": {
            "get": {
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {



...

OpenAPI dùng để làm gì?

Cấu trúc OpenAPI là sức mạnh của tài liệu tương tác.

Và có hàng tá các bản thay thế, tất cả đều dựa trên OpenAPI. Bạn có thể dễ dàng thêm bất kì bản thay thế bào cho ứng dụng của bạn được xây dựng với FastAPI.

Bạn cũng có thể sử dụng nó để sinh code tự động, với các client giao viết qua API của bạn. Ví dụ, frontend, mobile hoặc các ứng dụng IoT.

Tóm lại, từng bước một

Bước 1: import FastAPI

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

FastAPI là một Python class cung cấp tất cả chức năng cho API của bạn.

Chi tiết kĩ thuật

FastAPI là một class kế thừa trực tiếp Starlette.

Bạn cũng có thể sử dụng tất cả Starlette chức năng với FastAPI.

Bước 2: Tạo một FastAPI "instance"

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Biến app này là một "instance" của class FastAPI.

Đây sẽ là điểm cốt lõi để tạo ra tất cả API của bạn.

app này chính là điều được nhắc tới bởi uvicorn trong câu lệnh:

$ uvicorn main:app --reload

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Nếu bạn tạo ứng dụng của bạn giống như:

from fastapi import FastAPI

my_awesome_api = FastAPI()


@my_awesome_api.get("/")
async def root():
    return {"message": "Hello World"}

Và đặt nó trong một tệp tin main.py, sau đó bạn sẽ gọi uvicorn giống như:

$ uvicorn main:my_awesome_api --reload

<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Bước 3: tạo một đường dẫn toán tử

Đường dẫn

"Đường dẫn" ở đây được nhắc tới là phần cuối cùng của URL bắt đầu từ /.

Do đó, trong một URL nhìn giống như:

https://example.com/items/foo

...đường dẫn sẽ là:

/items/foo

Info

Một đường dẫn cũng là một cách gọi chung cho một "endpoint" hoặc một "route".

Trong khi xây dựng một API, "đường dẫn" là các chính để phân tách "mối quan hệ" và "tài nguyên".

Toán tử (Operation)

"Toán tử" ở đây được nhắc tới là một trong các "phương thức" HTTP.

Một trong những:

  • POST
  • GET
  • PUT
  • DELETE

...và một trong những cái còn lại:

  • OPTIONS
  • HEAD
  • PATCH
  • TRACE

Trong giao thức HTTP, bạn có thể giao tiếp trong mỗi đường dẫn sử dụng một (hoặc nhiều) trong các "phương thức này".


Khi xây dựng các API, bạn thường sử dụng cụ thể các phương thức HTTP này để thực hiện một hành động cụ thể.

Thông thường, bạn sử dụng

  • POST: để tạo dữ liệu.
  • GET: để đọc dữ liệu.
  • PUT: để cập nhật dữ liệu.
  • DELETE: để xóa dữ liệu.

Do đó, trong OpenAPI, mỗi phương thức HTTP được gọi là một "toán tử (operation)".

Chúng ta cũng sẽ gọi chúng là "các toán tử".

Định nghĩa moojt decorator cho đường dẫn toán tử

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/") nói FastAPI rằng hàm bên dưới có trách nhiệm xử lí request tới:

  • đường dẫn /
  • sử dụng một toán tửget

@decorator

Cú pháp @something trong Python được gọi là một "decorator".

Bạn đặt nó trên một hàm. Giống như một chiếc mũ xinh xắn (Tôi ddonas đó là lí do mà thuật ngữ này ra đời).

Một "decorator" lấy một hàm bên dưới và thực hiện một vài thứ với nó.

Trong trường hợp của chúng ta, decorator này nói FastAPI rằng hàm bên dưới ứng với đường dẫn / và một toán tử get.

Nó là một "decorator đường dẫn toán tử".

Bạn cũng có thể sử dụng với các toán tử khác:

  • @app.post()
  • @app.put()
  • @app.delete()

Và nhiều hơn với các toán tử còn lại:

  • @app.options()
  • @app.head()
  • @app.patch()
  • @app.trace()

Tip

Bạn thoải mái sử dụng mỗi toán tử (phương thức HTTP) như bạn mơ ước.

FastAPI không bắt buộc bất kì ý nghĩa cụ thể nào.

Thông tin ở đây được biểu thị như là một chỉ dẫn, không phải là một yêu cầu bắt buộc.

Ví dụ, khi sử dụng GraphQL bạn thông thường thực hiện tất cả các hành động chỉ bằng việc sử dụng các toán tử POST.

Step 4: Định nghĩa hàm cho đường dẫn toán tử

Đây là "hàm cho đường dẫn toán tử":

  • đường dẫn: là /.
  • toán tử: là get.
  • hàm: là hàm bên dưới "decorator" (bên dưới @app.get("/")).
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Đây là một hàm Python.

Nó sẽ được gọi bởi FastAPI bất cứ khi nào nó nhận một request tới URL "/" sử dụng một toán tử GET.

Trong trường hợp này, nó là một hàm async.


Bạn cũng có thể định nghĩa nó như là một hàm thông thường thay cho async def:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {"message": "Hello World"}

Note

Nếu bạn không biết sự khác nhau, kiểm tra Async: "Trong khi vội vàng?".

Bước 5: Nội dung trả về

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
async def root():
    return {"message": "Hello World"}

Bạn có thể trả về một dict, list, một trong những giá trị đơn như str, int,...

Bạn cũng có thể trả về Pydantic model (bạn sẽ thấy nhiều hơn về nó sau).

Có nhiều object và model khác nhau sẽ được tự động chuyển đổi sang JSON (bao gồm cả ORM,...). Thử sử dụng loại ưa thích của bạn, nó có khả năng cao đã được hỗ trợ.

Tóm lại

  • Import FastAPI.
  • Tạo một app instance.
  • Viết một decorator cho đường dẫn toán tử (giống như @app.get("/")).
  • Viết một hàm cho đường dẫn toán tử (giống như def root(): ... ở trên).
  • Chạy server trong môi trường phát triển (giống như uvicorn main:app --reload).