iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0

前言

昨天介紹了如何設定路由,那接下來要面對的就是,該怎麼設計合理的路由?如果要帶資訊到後端,是應該像昨天的動態路由那樣放在路由上?還是有其他作法?

這邊我們分成兩部分來討論

  1. 路由該怎麼設計
  2. 參數該怎麼攜帶到後端

API 的路由該怎麼設計?

誠如上方所說,在我們實際開發的時候,第一個需要面對的問題就是:
我該把這個 API 放在哪個路由上?名稱要叫什麼?HTTP方法要用什麼?

這樣或許還有點抽象,讓我們來舉個實際一點的例子

假如我們有一系列的 API,要負責處理使用者資料,包含新增、刪除、查詢、修改,我們可以這樣設計:

method route 說明
POST /user/add 新增使用者
GET /user/1 取得使用者 1 的資料
POST /user/1/update 更新使用者 1 的資料
GET /user/1/delete 刪除使用者 1 的資料

也可以這樣設計:

method route 說明
POST /user/add 新增使用者
GET /user/1 取得使用者 1 的資料
POST /user/update 更新使用者 1 的資料*
POST /user/delete 刪除使用者 1 的資料*

*將使用者 ID 放在 request body 送到後端

當然,也可以這樣設計:

method route 說明
POST /user 新增使用者
GET /user/1 取得使用者 1 的資料
PUT /user/1 更新使用者 1 的資料
DELETE /user/1 刪除使用者 1 的資料

上面這幾組不同風格的 API 都是可以實做出來的,並不會因為選擇哪種就導致程式無法運作。然而,相信大家應該有發現,最後這組的 API 路由是最簡潔的,也最好懂的,這種風格就叫做 RESTful API

RESTful API 是什麼?

REST 是 Representational State Transfer 的縮寫,它的概念簡單來說就是讓相同的做事目標有相同的路由,再依據要怎麼執行來選擇使用對應的 HTTP 方法,藉此來區分要做什麼事。

這兩篇文章(文章一文章二)我覺得都介紹的很好,歡迎大家去看看~

需要注意的是,REST 只是一種風格,不是硬性規定或標準,只是讓 API 路由更容易被理解和使用。不過,如果情況允許的話,還是會建議大家盡量遵照這個風格去開發 API,避免造成大家困擾 O v O

meme

API 的參數該怎麼攜帶到後端?

當我們向後端發送請求時,通常需要帶上額外資訊,例如:

  1. 查看使用者(公開的)資料時需要指定是看哪一位的
  2. 查詢時需要帶上要搜尋的關鍵字
  3. 登入時需要帶上帳號、密碼
  4. 查看個人隱私資料時需要附上已經登入成功的證明

以下是對應的做法:

  1. 動態路由
  2. 參數
  3. 在 Request body 放資料,常見格式為 JSON、FormData
  4. 在 Header 放上 JWT Token

昨天我們只介紹了怎麼再 FastAPI 設定動態路由,今天會介紹參數的做法,剩下兩個會在後面的文章陸續介紹

API 路由的其他常見議題

單數 or 複數?

當我們向後端請求資料時,有時候只要一筆,有時候則需要所有符合條件的資料,這時候就產生一個問題:

我的路由應該使用單數還是複數?是依據情況選擇單數或複數?還是選一個統一?

舉例來說,下面這是其中一種做法:

method route 說明
POST /user 新增一個使用者
GET /user/1 取得使用者 1 的資料
GET /users 取得所有使用者的資料

這個問題沒有標準答案,也有許多文章在討論 (例如這一篇)

我自己個人是喜歡統一使用單數,因為這樣在開發上可以省去一些重複的程式碼~

JSON or FormData?

在發送某些請求時 (例如:POST),需要附帶需要的資料在請求的 Body,主要有兩種格式:JSONFormData

如果是需要傳送檔案,那一定是選擇使用 FormData,但是,如果只是傳送一般的資訊 (例如:帳號、密碼),那麼這兩個作法其實是都可以的

這部分的實作留到明天再介紹

實作夾帶資訊的 API

最後還是來寫一點程式吧XD

昨天提到的設定路由,只有沒有帶參數的部分,接下來來介紹怎麼帶參數

GET + 參數

在 FastAPI,這個參數稱為 Query Parameter。來看下面這段程式碼範例

from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Item-1"}, {"item_name": "Item-2"}, {"item_name": "Item-3"}]


@app.get("/items")
async def read_item(skip: int = 0, limit: int = 10):
    return fake_items_db[skip : skip + limit]

我們在 /items 這個路由對應的函數 (也就是 read_item) 添加了兩個 input,並且指定它的型別都是 int,以及各自的預設值。

讓我們直接來看這三個結果

items

items_skip

items_skip_limit

可以發現在不帶任何參數時,可以拿到完整的資料。

加上參數後,可以對資料做對應的處理,而加參數的方法,就是在網址後面加上「?」和「{參數名稱}={數值}」,如果有多個參數,則使用「&」隔開就好。

重點整理

今天就介紹的這邊了,上面我們介紹了

  1. 路由的設計思維
  2. 帶參數到後端的方法
  3. RESTful API
  4. GET + 參數的路由設定

明天會繼續介紹該怎麼使用 FormData,以及該怎麼測試 POST 的回傳~

原本想趁周末多寫一點的,但時間怎麼一下就沒了/images/emoticon/emoticon02.gif


上一篇
[Day 03] 路由設定
下一篇
[Day 05] 後端開發的得力助手:Postman
系列文
FastAPI 開發筆記:從新手到專家的成長之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言