前面我們已經完成 C# 的核心基礎:
OOP
Interface
Collection
Lambda
LINQ
Exception Handling
async / await
Modern C#
從今天開始,正式進入:
ASP.NET Core
但在開始寫 Controller 之前,先不要急著學 ASP.NET Core 語法。
先思考一個每天都會發生的事情:
當我們在 Browser 輸入網址,或 Frontend 呼叫 API,到 Server 回傳結果之前,中間到底發生了什麼?
例如使用者輸入:
https://example.com/api/products/10
最後得到:
{
"id": 10,
"name": "Keyboard",
"price": 2000
}
中間可以先簡化成:
使用者
↓
Browser / Frontend
↓
HTTP Request
↓
Server / ASP.NET Core
↓
執行程式邏輯
↓
HTTP Response
↓
Browser / Frontend
↓
使用者
今天學習的:
HTTP
Request
Response
URL
Method
Headers
Body
JSON
Status Code
REST
其實全部都在這條流程裡。
今天最重要的一句話:
Web API 的核心,就是 Client 發出 HTTP Request,Server 執行程式邏輯,再透過 HTTP Response 把結果回傳給 Client。
假設使用者在 Browser 輸入:
https://example.com/api/products/10
並按下 Enter。
可以先把整個過程理解成:
① 使用者輸入 URL
https://example.com/api/products/10
↓
② Browser 發出 HTTP Request
GET /api/products/10
↓
③ Request 到達 Server
ASP.NET Core
↓
④ Server 執行程式邏輯
查詢 Product 10
↓
⑤ Server 建立 HTTP Response
200 OK
Content-Type: application/json
{
"id": 10,
"name": "Keyboard",
"price": 2000
}
↓
⑥ Response 回到 Browser
↓
⑦ 使用者看到結果
今天整篇文章,就是把這條流程拆開來理解。
先建立最基本的 Mental Model:
Client
↓
Request
↓
Server
↓
Response
↓
Client
在剛才的例子中:
Browser
→ Client
ASP.NET Core Application
→ Server 端應用程式
可以先理解:
Client
→ 主動提出需求的一方
Server
→ 接收需求、執行處理、回傳結果的一方
但 Client 不一定只有 Browser。
例如:
Browser
Frontend
Mobile App
Postman
都可能向 Server 發出 Request。
Client 和 Server 需要一套共同的溝通規則,Web 最常使用:
HTTP
→ Hypertext Transfer Protocol
今天可以先把 HTTP 理解成:
Client 與 Server 在 Web 上交換 Request 與 Response 的規則。
因此:
HTTP Request
→ Client 告訴 Server:「我想做什麼?」
HTTP Response
→ Server 告訴 Client:「處理結果是什麼?」
Browser 把 Request 送到 Server 之前,實際上還可能經過:
URL
↓
DNS
↓
找到 Server IP
↓
建立網路連線
↓
HTTPS / TLS
↓
HTTP
這些屬於較底層的網路知識。
今天先聚焦在 ASP.NET Core 最需要理解的部分:
HTTP Request
↓
Server
↓
HTTP Response
回到:
https://example.com/api/products/10
可以先簡單拆成:
https
→ 使用 HTTPS
example.com
→ Host
/api/products/10
→ Path
HTTPS 可以先理解成:
使用加密連線的 HTTP。
今天不深入 TLS。
目前真正需要掌握:
Host
→ 要連到哪個網站 / Server
Path
→ 要操作哪個 Resource
例如:
/api/products
→ Product Resource
/api/products/10
→ 指定 Product 10
有時不是指定單一 Resource,而是提供搜尋條件:
/api/products?keyword=keyboard&page=1
其中:
/api/products
→ Path
?keyword=keyboard&page=1
→ Query String
例如:
GET /api/products?keyword=keyboard
可以理解成:
取得 Products,而且搜尋條件是
keyword = keyboard。
所以:
/api/products/10
→ Path
→ 指定 Product 10
/api/products?keyword=keyboard
→ Query String
→ 提供查詢條件
之後學 Model Binding 時,會正式處理:
Route Parameter
Query Parameter
Request Body
知道要去哪裡之後,Client 就要把需求送給 Server。
一個 HTTP Request 可以先關注四個部分:
Method
URL
Headers
Body
例如:
POST /api/products
Content-Type: application/json
{
"name": "Keyboard",
"price": 2000
}
可以拆成:
POST
→ Method
→ 想做什麼?
/api/products
→ URL
→ 想操作什麼 Resource?
Content-Type: application/json
→ Header
→ 描述這次 Request 的相關資訊
{
...
}
→ Body
→ Client 要傳給 Server 的資料
所以 Request 的 Mental Model:
HTTP Request
Method
→ 做什麼?
URL
→ 操作什麼?
Headers
→ Request 的相關資訊
Body
→ 傳什麼資料?
只有:
/api/products
還不知道 Client 到底想:
取得商品?
建立商品?
修改商品?
刪除商品?
所以 HTTP Request 還需要:
HTTP Method
常見 Method:
| Method | 常見用途 | 範例 |
|---|---|---|
GET |
取得資料 | GET /api/products |
POST |
建立資料 | POST /api/products |
PUT |
完整更新/取代指定 Resource | PUT /api/products/10 |
DELETE |
刪除資料 | DELETE /api/products/10 |
可以先記:
URL
→ 操作誰?
Method
→ 對它做什麼?
例如:
GET /api/products/10
可以讀成:
取得 Product 10。
而:
DELETE /api/products/10
就是:
刪除 Product 10。
假設 Client 發出:
POST /api/products
Server 已經知道:
POST
→ 建立
/api/products
→ Product
但還不知道:
要建立什麼 Product?
因此通常需要 Request Body:
{
"name": "Keyboard",
"price": 2000
}
這裡使用的是:
JSON
→ JavaScript Object Notation
Web API 很常使用 JSON 在 Client 與 Server 之間交換資料。
完整 Request 可能是:
POST /api/products
Content-Type: application/json
{
"name": "Keyboard",
"price": 2000
}
其中:
Body
→ Product 資料
Content-Type: application/json
→ Body 的資料格式是 JSON
所以:
Headers
→ 描述 HTTP Message 的相關資訊
例如未來還會看到:
Authorization
用來傳遞與身分驗證相關的資訊。
今天先知道:
Request Headers
→ 描述 Request 的相關資訊
Response Headers
→ 描述 Response 的相關資訊
即可。
Day 24 我們學過:
public record CreateProductRequest(
string Name,
decimal Price
);
Client 傳來:
{
"name": "Keyboard",
"price": 2000
}
之後 ASP.NET Core 可以把這份 JSON 資料轉成 C# Object:
Request Body
↓
JSON
↓
ASP.NET Core
↓
CreateProductRequest
↓
C# Object
後端就可以取得:
request.Name
request.Price
但這裡會產生另一個問題:
ASP.NET Core 怎麼知道 JSON 的
name要對應到Name,price要對應到Price?
這就是後面會正式學到的:
Model Binding
今天只需要先建立:
JSON
→ C# Object
這個概念。
現在 Client 發出:
GET /api/products/10
Request 到達:
ASP.NET Core
接下來 Server 必須決定:
這個 Request 應該交給哪一段 C# 程式碼?
可以先理解成:
GET /api/products/10
↓
ASP.NET Core
↓
找到負責處理的程式
↓
執行 C# 程式邏輯
↓
查詢 Product 10
今天先不用知道 ASP.NET Core 怎麼找到它。
因為這正是 Day 26 要回答的問題:
Request
↓
Routing
↓
Controller
↓
Action
這裡要區分兩個角色:
HTTP
→ 負責 Client 與 Server 之間的「溝通」
C# / ASP.NET Core
→ 負責 Server 上真正的「處理」
例如:
GET /api/products/10
↓
HTTP Request
↓
ASP.NET Core
↓
執行 C# 程式
↓
取得 Product 10
HTTP 本身不負責查資料。
真正執行:
查詢
計算
驗證
商業邏輯
的是 Server 上的程式。
假設 Server 找到 Product 10。
它需要把結果回給 Client,因此建立:
HTTP Response
例如:
200 OK
Content-Type: application/json
{
"id": 10,
"name": "Keyboard",
"price": 2000
}
Response 可以先關注:
Status Code
Headers
Body
也就是:
HTTP Response
Status Code
→ 處理結果如何?
Headers
→ Response 的相關資訊
Body
→ Server 回傳什麼資料?
在剛才的例子:
200 OK
→ Request 成功
Content-Type: application/json
→ Response Body 的資料格式是 JSON
{
...
}
→ Product 資料
Status Code 是 Server 告訴 Client:
這次 Request 的處理結果。
先掌握三個大方向:
2xx
→ Request 成功處理
4xx
→ Request 無法被 Server 接受或完成
5xx
→ Server 處理 Request 時發生問題
常見 Status Code:
| Status Code | 意義 |
|---|---|
200 OK |
Request 成功 |
201 Created |
Resource 建立成功 |
204 No Content |
成功,但沒有 Response Body |
400 Bad Request |
Request 資料有問題 |
404 Not Found |
找不到 Resource |
500 Internal Server Error |
Server 發生未預期錯誤 |
把它放回實際流程會更容易理解:
GET /api/products/10
↓
找到 Product
↓
200 OK
GET /api/products/999
↓
找不到 Product
↓
404 Not Found
POST /api/products
↓
建立成功
↓
201 Created
DELETE /api/products/10
↓
刪除成功,不需要回傳 Body
↓
204 No Content
如果 Request 資料不符合 API 規則:
POST /api/products
↓
資料不符合要求
↓
400 Bad Request
如果 Server 執行時發生未處理錯誤:
Request
↓
Server 發生未處理 Exception
↓
500 Internal Server Error
所以:
Status Code 不是單純要背的數字,而是在告訴 Client「這次處理發生了什麼」。
到目前為止,我們使用 Browser 網址列來理解流程:
使用者
↓
Browser
↓
GET /api/products/10
↓
Server
↓
Response
↓
Browser
但實際的前後端分離網站中,使用者通常不會自己輸入 API URL。
比較常見的是:
使用者
↓
操作畫面
↓
Frontend
↓
JavaScript 呼叫 API
例如:
const response =
await fetch(
"/api/products/10"
);
const product =
await response.json();
背後仍然是:
使用者
↓
Browser 裡的 Frontend
↓
fetch()
↓
HTTP Request
GET /api/products/10
↓
ASP.NET Core
↓
執行程式邏輯
↓
HTTP Response
200 OK
+
JSON
↓
Frontend 取得資料
↓
更新畫面
↓
使用者看到商品
所以無論:
Browser 網址列發出 Request
或:
Frontend JavaScript 使用 fetch() 發出 Request
核心都一樣:
Client
↓
HTTP Request
↓
Server
↓
HTTP Response
↓
Client
Browser 是:
Chrome
Edge
Firefox
Safari
Frontend 則是執行在 Browser 裡的:
HTML
CSS
JavaScript
Vue
React
所以前後端分離網站可以理解成:
使用者
↓
Browser
↓
Frontend Application
↓
HTTP
↓
Backend / ASP.NET Core
現在我們已經看過:
GET /api/products
GET /api/products/10
POST /api/products
PUT /api/products/10
DELETE /api/products/10
這時就可以認識:
REST API
RESTful API
REST 是一種常見的 Web API 架構風格。
今天先掌握其中一個重要方向:
以 Resource 為核心設計 URL,再利用 HTTP Method 表達操作。
例如:
Product
→ Resource
/api/products
→ Resource URL
再使用:
GET
POST
PUT
DELETE
表示不同操作。
| Method | URL | 意義 |
|---|---|---|
GET |
/api/products |
取得商品列表 |
GET |
/api/products/10 |
取得商品 10 |
POST |
/api/products |
建立商品 |
PUT |
/api/products/10 |
完整更新/取代商品 10 |
DELETE |
/api/products/10 |
刪除商品 10 |
核心:
URL
→ 描述 Resource
HTTP Method
→ 描述操作
因此相較於:
/getProducts
/createProduct
/updateProduct
/deleteProduct
Resource-oriented 的設計更常使用:
GET /api/products
POST /api/products
PUT /api/products/10
DELETE /api/products/10
例如:
DELETE /api/products/10
可以直接讀成:
刪除 Product 10。
要注意:
REST
≠
只有 CRUD 與 URL 命名
今天學到的:
Resource
+
HTTP Method
只是理解 REST API 的第一步。
現在回到文章最開始。
使用者在 Browser 輸入:
https://example.com/api/products/10
完整流程:
使用者
↓
Browser / Frontend
↓
HTTP Request
GET /api/products/10
↓
ASP.NET Core
↓
執行 C# 程式邏輯
查詢 Product 10
↓
HTTP Response
200 OK
Content-Type: application/json
{
"id": 10,
"name": "Keyboard",
"price": 2000
}
↓
Browser / Frontend
↓
使用者看到結果
這條流程就是今天所有知識的核心。
今天沒有急著開始寫 Controller,而是先理解 Web API 背後最重要的流程:
Client
↓
HTTP Request
↓
Server
↓
HTTP Response
↓
Client
Request 可以先拆成:
Method
→ 想做什麼
URL
→ 操作什麼 Resource
Headers
→ Request 的相關資訊
Body
→ 傳送資料
URL 裡可能看到:
Path
→ 指定 Resource
Query String
→ 提供查詢條件
Client 與 Server 很常使用:
JSON
交換資料。
Response 則可以先關注:
Status Code
→ 處理結果
Headers
→ Response 的相關資訊
Body
→ 回傳資料
常見 Status Code:
200 OK
→ 成功
201 Created
→ 建立成功
204 No Content
→ 成功,但沒有 Response Body
400 Bad Request
→ Request 資料有問題
404 Not Found
→ 找不到 Resource
500 Internal Server Error
→ Server 發生未預期錯誤
REST 今天先掌握:
URL
→ 描述 Resource
HTTP Method
→ 描述操作
整篇最重要的 Mental Model:
使用者
↓
Browser / Frontend
↓
HTTP Request
↓
ASP.NET Core
↓
執行 C# 程式邏輯
↓
HTTP Response
↓
Browser / Frontend
↓
使用者
整篇最重要的一句話:
Web API 的核心,就是 Client 發出 HTTP Request,Server 執行程式邏輯,再透過 HTTP Response 把處理結果回傳給 Client。