第三章是全系列的重頭戲,因為我們要介紹 Django Ninja 的核心部分——API。
我把本章分成了三個小節:
第三章也是唯一有區分小節的篇章。
現在我們進入第一節——路由。讓我們先了解一下本節的學習重點。
本節一共有兩篇,分別是:
為什麼要這樣安排呢?因為端點與路由是 API 請求的起點。
沒有它們,你的 view 函式根本無法接收請求,更不用說回應了。因此,路由設定必須放在第一位,作為 API 開發的學習入口。
所謂的「端點」(endpoints),你就簡單想成 API 所在的 URL 就可以了。
其次,Django Ninja 的路由設定與傳統 Django 或 Django REST Framework(以下簡稱 DRF)的路由設定有很大的不同,反而更接近 FastAPI 或 Flask 風格。
這是我在學習 Django Ninja 時遇到的第一個門檻(畢竟我寫了 2 年的 DRF😅),所以決定分成上下兩篇文章詳細解說,幫助你打好基礎、減少混淆。
本文的重點是介紹 Django 傳統路由的設定方式。讓我們開始吧!
路由(Router)是 Web 服務的重要元件之一,它負責將客戶端(通常是瀏覽器)發送的 HTTP 請求,對應到正確的處理邏輯。
在 Django 中,路由就是決定「哪個請求應該由哪個 View 來處理」的機制。
當客戶端訪問特定的 URL(我們稱為「端點」)時,Django 伺服器會根據這個 URL,找到對應的處理函式來執行特定邏輯。
這個「對應(mapping)」的過程,就是路由的核心職責。
Django 的路由機制主要透過urls.py
中的設定,來管理不同層級的路由結構,並通過一級路由和二級路由,加以整合、組織所有端點。
至此,我們已經提到了 Django 路由的三個關鍵元素:
urls.py
以下是對它們的介紹。
一級路由是「專案級別」的路由,通常位於 Django 專案目錄底下(即範例專案中的NinjaForum
目錄)的urls.py
中。
一級路由主要用來為每一個 Django app 分別加上全 app 統一的「路由前綴」,並整合來自所有 app 的路由。
以本專案為例,它可能會長這樣:
# NinjaForum/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('posts/', include('post.urls')), # 處理 post app 的路由
path('users/', include('user.urls')), # 處理 user app 的路由
]
這裡的urlpatterns
是 Django 的一級路由。它將/posts/
和/users/
路徑分別指向 post 和 user app 的二級路由,作為各 app 二級路由的統一前綴。
二級路由是各 Django app 自行管理的路由。直接對應 app 本身的 view 函式:
# post/urls.py
from django.urls import path
from post import views
urlpatterns = [
path('', views.get_posts)
path('<int:post_id>/', views.post_detail),
]
將一級與二級路由的邏輯重新組合後,上述兩個 app 級路由,實際的端點是:
/posts/
:取得所有文章。/posts/<int:post_id>/
:取得特定文章細節。這種層級式的路由結構不僅使 URL 更有組織,也讓不同 app 的功能更加模組化。
舉例而言,如果我們想要為 user app 新增一個「獲取用戶資料」API,我們只需要在 user app 的urls.py
中建立相對應的路由即可,不需修改專案級別的路由設定。
用鳥瞰的角度可能會更清楚。
就 Django 傳統路由部分,整個範例專案的目錄與檔案結構如下(已省略無關部分):
├── NinjaForum
│ ├── urls.py # 專案一級路由
│ ├── ...
├── post
│ ├── urls.py # app 二級路由
│ ├── ...
├── user
│ ├── urls.py # app 二級路由
│ ├── ...
├── ...
這樣的結構在 Django 專案中十分常見,同時也是 DRF 的標準做法。
專案一級路由負責全域的入口,二級路由負責 app 中 view 函式的配對。這樣的設計,使得專案架構更具模組化與擴展性。
Django 傳統的路由機制藉由專案與 app 層級的urls.py
,來組織並定義完整的 URL 路徑(端點),這樣的設計有好有壞,讓我們來探討其中的利弊。
Django 傳統路由的一大優點就是所有的端點、路由都集中在 urls.py
中。這意味著開發者可以一眼看出目前所有的 API 端點(app 部分),例如:
# app 層級 urls.py
from django.urls import path
from . import views
urlpatterns = [
path('home/', views.home, name='home'),
path('about/', views.about, name='about'),
path('contact/', views.contact, name='contact'),
]
urls.py
就像路由目錄一樣,一目了然。
如前所述,路由負責連接端點與 view 函式。
由於每個端點都需要對應一個 view 函式,而對應的 view 函式通常放在views.py
。
這帶來了一個問題:開發者需要在urls.py
和views.py
之間來回切換,才能完整理解一個端點與背後的實現邏輯。
這樣的「不直觀」不僅增加了開發時的認知負擔,也容易在修改 API 時發生錯誤。
此外,隨著專案規模不斷擴大,urls.py
中的端點清單會越來越長——要找到對應的 view 函式變得耗時且繁瑣,進一步增加了出錯的可能。
本文中,我們深入了解了傳統 Django 的路由設計,並探討了其優缺點。
這種結構化的設計讓路由的管理更加模組化,但也引發了在大型專案中維護和閱讀困難的問題。
接下來,我們將探索 Django Ninja 如何提供更簡潔的路由機制,並與傳統 Django 路由進行比較。
Django Ninja 採用了一種更現代化的方式,來處理路由和 view 函式——它將兩者緊密結合,提供了一種更直觀的手段來定義 API 端點。(其實大家都是學 Flask 的☺️)
不僅大幅減少了在不同檔案間切換的需求,還提高了程式碼的可讀性和維護性。
下一篇,就讓我們來了解 Django Ninja 的路由機制,看看它是如何改善這些問題的。
本文同步發表於我的部落格——Code and Me