74 lines
1.9 KiB
Markdown
74 lines
1.9 KiB
Markdown
|
|
# HTTP 統一回應
|
|||
|
|
|
|||
|
|
## 分工
|
|||
|
|
|
|||
|
|
| 層 | 職責 |
|
|||
|
|
|----|------|
|
|||
|
|
| **Logic** | `return data, err`(`err` 為 `*errs.Error` 或標準 `error`) |
|
|||
|
|
| **Handler** | `response.Write(ctx, w, data, err)` |
|
|||
|
|
| **`.api`** | 只描述 `data` 的型別(如 `PingData`),不描述外層 `Status` |
|
|||
|
|
|
|||
|
|
## Handler 範例
|
|||
|
|
|
|||
|
|
有 request 的 API,模板會自動生成 **參數綁定 + 驗證**(`httpx.Parse`):
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
var req types.GetUserReq
|
|||
|
|
if err := httpx.Parse(r, &req); err != nil {
|
|||
|
|
response.Write(r.Context(), w, nil, response.WrapRequestError(err)) // → 400 InputInvalidFormat
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
data, err := l.GetUser(&req)
|
|||
|
|
response.Write(r.Context(), w, data, err)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
無 request 的 API(如 `GET /health`)不會生成 Parse 區塊,屬正常行為。
|
|||
|
|
|
|||
|
|
在 `main` 可設定驗證錯誤使用的 scope:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
response.RequestErrScope = code.Facade
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`.api` 的 request struct 可加 `validate:` tag 或實作 `Validate() error`,由 go-zero `httpx.Parse` 觸發。
|
|||
|
|
|
|||
|
|
## Logic 範例
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
var errb = errs.For(code.Facade)
|
|||
|
|
|
|||
|
|
func (l *XLogic) GetUser(req *types.GetUserReq) (*types.UserVO, error) {
|
|||
|
|
if req.Id == "" {
|
|||
|
|
return nil, errb.InputMissingRequired("id")
|
|||
|
|
}
|
|||
|
|
// ...
|
|||
|
|
return vo, nil
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 回應 JSON
|
|||
|
|
|
|||
|
|
成功(HTTP 200):
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{ "code": 0, "message": "SUCCESS", "data": { ... } }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
失敗(HTTP 依 category,如 404):
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 10301000,
|
|||
|
|
"message": "user not found",
|
|||
|
|
"error": { "biz_code": "10301000", "scope": 10, "category": 301, "detail": 0 }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## goctl 模板(可選)
|
|||
|
|
|
|||
|
|
專案模板路徑:`generate/goctl/api/handler.tpl`(**不是** `api/gogen/`)。
|
|||
|
|
|
|||
|
|
`make gen-api` 已帶 `-home generate/goctl`,**新建的 handler** 會自動使用 `response.Write`。
|
|||
|
|
|
|||
|
|
注意:已存在的 handler 檔案 goctl **不會覆寫**(會顯示 `exists, ignored`)。新增 API 沒問題;若要重生成舊 handler,需先刪除該檔再 `make gen-api`。
|