iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0

前言

前面我們已經寫了幾個 API 昨天我們也為了實現 JWT 的功能而使用了套件內的 ViewSet。目前為止我們還可以透過文件或是寫程式的記憶力去知道 API 會需要什麼傳入並回傳哪個格式,但隨著 API 越來越多後我們可能會記不清楚。而且如果其他要使用這個 API 我們也需要提供一份文件才能讓他們方便使用,所以讓我們為我們的 API 加上文件吧!

而目前常被用來當作 API 文件的是一個名為 OpenAPI 的格式,他會描述我們有哪些 API 還有傳入傳出的格式,搭配一些工具例如 Swagger 或是 Redoc 就可以產生一個 API 文件了

產生 API 文件

前面我們提到格式會使用 OpenAPI 這個格式,在一些情況我們需要自己寫,這樣才能讓工具正確的產生我們的文件,但是自己寫實在是太浪費時間了,所以我們要借助一個套件,他會自動的列出我們的 API 並根據我們設定的序列化產生對應的輸入輸出格式。

我們這次會使用的套件是 drf-spectacular 他會協助我們從程式碼自動的產出 OpenAPI 格式

poetry add drf-spectacular

P.S. 以前大家可能比較習慣使用的套件是 drf-yasg 但他產生出來的格式是 OpenAPI 2.0 而 drf-spectacular 產出來的是 3.0 所以我們會使用新的。

安裝完成後別忘了把 APP 加入 server/settings.py

# ...... 以上省略 ......

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "rest_framework_simplejwt",
+   "drf_spectacular",
    "server.app.common",
    "server.app.todo",
]

# ...... 以下省略 ......

設定 API 文件

我們已經把套件安裝好了,接下來我們要進行設定,打開 server/settings.py 並依照下方方式修改

# ...... 以上省略 ......

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
+   "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": datetime.timedelta(minutes=5),
    "REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=1),
    "ROTATE_REFRESH_TOKENS": True,
}

+SPECTACULAR_SETTINGS = {
+    "TITLE": "DRF Todo List",
+    "DESCRIPTION": "This is a todo list for DRF practice.",
+    "VERSION": "1.0.0",
+    "SERVE_INCLUDE_SCHEMA": False,
+}

以上設定我們告訴 DRF 我們的 Schema class 要使用我們剛剛安裝的套件提供的 AutoSchema

並在 SPECTACULAR_SETTINGS 中設定文件標題(title)、說明(description)、版本(version)以及是否隱藏 Schema(後面會提到)

設定路由

# ...... 以上省略 ......

from django.contrib import admin
from django.urls import include, path
+from drf_spectacular import views as doc_views
from rest_framework import routers
from rest_framework_simplejwt import views as jwt_views

from server.app.common import views as common_views
from server.app.todo import views as todo_views

router = routers.SimpleRouter(trailing_slash=False)
router.register("todo/tasks", todo_views.TaskViewSet)
router.register("todo/tags", todo_views.TagViewSet)

urlpatterns = [
    path("admin/", admin.site.urls),
    path("health", common_views.HealthView.as_view()),
    path("api/token", jwt_views.TokenObtainPairView.as_view()),
    path("api/token/refresh", jwt_views.TokenRefreshView.as_view()),
+   path("api/schema.json", doc_views.SpectacularJSONAPIView.as_view(), name="schema"),
+   path("api/swagger/", doc_views.SpectacularSwaggerView.as_view()),
+   path("api/redoc/", doc_views.SpectacularRedocView.as_view()),
    path("api/", include(router.urls)),
]

在這邊我們設定了三個路由

  1. /api/schema.json:這個路由會提供 OpenAPI Schema 的 JSON 格式,前面的 SERVE_INCLUDE_SCHEMA 就是設定是否在文件中隱藏這個 API,如果設定為 False 文件中就不會出現這個路由。而我們在設定這個路由時有給他一個名字 schema 因為等等的工具會使用它。
  2. /api/swagger/:這個路由會產生一個 Swagger 的網頁畫面,他會使用 /api/schema.json 提供的內容產生對應的文件(這就為什麼我們在設定前面那個路由後需要給他名字的原因)。
  3. /api/redoc/:這個路由與 Swagger 差不多,只是畫面變成 Redoc 格式。

驗證

現在我們已經設定好了所有設定,現在我們要開啟 server(別忘了啟動虛擬環境)

python manage.py runserver

接著使用瀏覽器訪問下方三個網址

  1. http://127.0.0.1:8000/api/schema.json:會看到 JSON 內容,是 OpenAPI 的格式
  2. http://127.0.0.1:8000/api/swagger:會看到 Swagger 格式的文件
  3. http://127.0.0.1:8000/api/redoc:會看到 Redoc 格式的文件

總結

今天我們透過套件的協助我們就建立了文件,這樣前端或是其他人需要使用這個 API 時就可以依照文件的格式使用,而且我們的文件當我們修改 API 時也會產生對應的變化,這樣就不用費心再去修改文件。

結束前別忘了檢查一下今天的程式碼有沒有問題,並排版好喔。

ruff check --fix .
black .
pyright .

今天的內容就到這邊了,讓我們期待明天的內容吧。

P.S. 今天的檔案更新可以參考我的 Git Commit 大家可以搭配服用


上一篇
Day15 - JWT 驗證
下一篇
Day17 - 為 API 加上分頁
系列文
Django REST 大冒險:探索精彩紛呈的 API 開發世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言