template-monorepo/etc/README.md

238 lines
7.5 KiB
Markdown
Raw Normal View History

# gateway.yaml 設定說明
Gateway 使用 [go-zero `conf`](https://go-zero.dev/docs/tutorials/go-zero/configuration/overview) 載入 YAML。結構定義在 `internal/config/config.go`,對應各模組的 `Conf` 結構。
## 用哪個檔案?
| 檔案 | 用途 | 啟動方式 |
|------|------|----------|
| **`gateway.yaml`** | 預設:不需 Docker僅 HTTP / health | `make run` |
| **`gateway.dev.yaml`** | 本機完整功能Mongo + Redis + Notification | `make deps-up``make run-dev` |
```bash
# 僅 API最快
make run
# Notification / Member OTP需 Docker
make deps-up
make mongo-index # 首次建議執行
make run-dev
```
---
## go-zero 填寫規則(重要)
1. **欄位名稱必須與 Go struct 一致**(駝峰在 yaml 裡通常照抄,如 `MaxPoolSize`)。**不要**填 struct 裡沒有的欄位(例如以前的 `MaxStaleness`),否則可能觸發奇怪錯誤。
2. **沒標 `optional` 的頂層欄位**:在該區塊出現時需型別正確;我們已在 Mongo / Notification / Member 加上 `json:",optional"`,多數子欄位可省略。
3. **空字串 `""`**:可寫,表示無帳密 / 無 AuthSource。
4. **時間**`30m`、`10s``time.Duration`)。
5. **字串陣列**(如 `Compressors`)必須是 YAML 列表,**不能**寫成單一字串:
```yaml
Compressors:
- zstd
- snappy
```
6. **Mongo 埠號**:用整數 `Port: 27017`,不要 `Port: "27017"`;或直接在 `Host``127.0.0.1:27017`
---
## 頂層HTTP 服務(`rest.RestConf`
| 欄位 | 必填 | 說明 | 範例 |
|------|:----:|------|------|
| `Name` | ✓ | 服務名稱 | `gateway` |
| `Host` | ✓ | 監聽位址 | `0.0.0.0` |
| `Port` | ✓ | HTTP 埠 | `8888` |
其餘 `RestConf` 欄位(`Timeout`、`Log`、`Prometheus` 等)可省略,使用 go-zero 預設。
---
## `Mongo``internal/library/mongo.Conf`
**`Host` 留空或整段註解** → 不連 Mongo`Notifier` / `MemberVerification` 不會注入(仍可跑 health API
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|------|:----:|------|----------------|
| `Schema` | 選 | 連線 scheme預設 `mongodb` | `mongodb` |
| `Host` | 啟用時 ✓ | 主機;可含埠 `127.0.0.1:27017` | `127.0.0.1` |
| `Port` | 選 | `Host` 無埠時附加,**整數** | `27017` |
| `Database` | 啟用時 ✓ | 資料庫名 | `gateway`(與 docker init 一致) |
| `User` | 選 | 帳號 | 本機留空 |
| `Password` | 選 | 密碼 | 本機留空 |
| `AuthSource` | 選 | 驗證用 DB帳號在 `admin` 建則填 `admin` | 本機留空 |
| `ReplicaName` | 選 | replica set 名稱 | 本機單機**留空** |
| `TLS` | 選 | 是否 `tls=true` | `false` |
| `MaxPoolSize` | 選 | 連線池上限 | `30` |
| `MinPoolSize` | 選 | 連線池下限 | `10` |
| `MaxConnIdleTime` | 選 | 閒置連線逾時 | `30m` |
| `Compressors` | 選 | 壓縮演算法陣列 | 省略(程式預設 zstd、snappy |
| `ConnectTimeoutMs` | 選 | 啟動 Ping 逾時(毫秒) | 省略(預設 10s |
**會建立的 collections**(自動,無需手動建表):`notifications`、`notification_dlq`。索引:`make mongo-index` 或 docker init。
**常見錯誤**
| 錯誤訊息 | 原因 |
|----------|------|
| `type mismatch for field "Mongo.Compressors"` | 曾用不存在的 `Port: "27017"``Compressors` 寫成單一字串 |
| `field "Mongo.xxx" is not set` | 舊版未加 `optional`;請更新程式或改用最精簡的 `gateway.dev.yaml` |
| `mongo: ping primary` 失敗 | 有填 `Mongo.Host` 但沒跑 `make deps-up` |
---
## `Redis`go-zero `redis.RedisConf`
**`Host` 留空**`gateway.yaml` 預設)→ 不連 Redis。有 Mongo 時仍可用 memory 冪等/配額,但**無異步重試 worker**、**無 Member OTP**。
`gateway.yaml` 建議保留區塊並設空 Host
```yaml
Redis:
Host: ""
Type: node
```
| 欄位 | 必填 | 說明 | 本機 dev 建議 |
|------|:----:|------|----------------|
| `Host` | 啟用時 ✓ | `host:port` | `localhost:6379` |
| `Type` | 啟用時 ✓ | 單機填 `node` | `node` |
| `Pass` | 選 | 密碼 | 省略 |
| `Tls` | 選 | TLS | 省略 |
---
## `Notification``internal/model/notification/config`
僅在 **Mongo 已連線** 時由 `ServiceContext` 組裝 Notifier。子欄位皆可省略有程式預設
### 根層
| 欄位 | 說明 | 預設 / 建議 |
|------|------|-------------|
| `DefaultLocale` | 模板語系 fallback | `zh-tw` |
| `RatePerTenant.Email` | 每租戶每日 Email 上限 | `100` |
| `RatePerTenant.SMS` | 每租戶每日 SMS 上限 | `50` |
### `Notification.Email`
| 欄位 | 說明 |
|------|------|
| `Provider` | 無真實 provider 時填 `mock` |
| `From` | 寄件者Send 時帶入) |
| `APIKey` | 保留,目前未用 |
**SMTP**`Enable: true` 時加入發信鏈,依 `Sort` failover
| 欄位 | 說明 |
|------|------|
| `Enable` / `Sort` | 是否啟用、優先順序(數字小先試) |
| `Host` / `Port` | SMTP 主機與埠MailHog`localhost:1025` |
| `Username` / `Password` | 認證 |
**SES**AWS
| 欄位 | 說明 |
|------|------|
| `Enable` / `Sort` | 同上 |
| `Region` / `AccessKey` / `SecretKey` / `SessionToken` | AWS 憑證 |
### `Notification.SMS`
| 欄位 | 說明 |
|------|------|
| `Provider` | 無真實 provider 時 `mock` |
| `Mitake.Enable` | 三竹簡訊 |
| `Mitake.User` / `Mitake.Password` | 三竹帳密 |
| `Mitake.Sort` | failover 順序 |
### `Notification.Async`
| 欄位 | 說明 |
|------|------|
| `QueueRedisKey` | Redis ZSET key空則用內建 `notif:retry:zset` |
| `Worker` | 背景重試 goroutine 數 |
| `MaxRetry` | 最大重試次數 |
| `BackoffSeconds` | 重試間隔(秒)陣列 |
**Mongo + Redis** 才會啟動 `RetryWorker`
### `Notification.Push` / `Webhook`
保留欄位,目前未接線。
---
## `Member``internal/model/member/config`
僅在 **Mongo + Redis + Notifier** 皆就緒時注入 `MemberVerification`
### `Member.OTP`
| 欄位 | 說明 | 建議 |
|------|------|------|
| `Length` | OTP 位數 | `6` |
| `TTLSeconds` | challenge 存活秒數 | `300` |
| `MaxAttempts` | 驗證嘗試上限 | `5` |
| `ResendCooldownSeconds` | 重發冷卻 | `60` |
| `DailyVerifyLimit` | 每日驗證上限 | `10` |
---
## 功能與依賴對照
```mermaid
flowchart LR
subgraph always [永遠可用]
H[health API]
end
subgraph mongo [Mongo.Host 有值]
N[Notifier Send/Get]
A[Admin DLQ]
end
subgraph redis [Redis.Host 有值]
Q[Enqueue + RetryWorker]
O[Member OTP]
end
H --> always
mongo --> N
mongo --> A
mongo --> redis
redis --> Q
redis --> O
```
| 你想用的功能 | Mongo | Redis |
|--------------|:-----:|:-----:|
| `/api/v1/health` | — | — |
| `Notifier.Send`(同步) | ✓ | 選(冪等/配額建議開) |
| `Notifier.Enqueue` + 重試 | ✓ | ✓ |
| Member 信箱/手機驗證 | ✓ | ✓ |
---
## 疑難排解
```bash
# 1. 只驗證 yaml 能否載入(不啟動服務)
go test ./internal/config/ -run TestLoadGatewayYAML -v
# 2. 看缺什麼欄位(啟動時)
go run gateway.go -f etc/gateway.yaml
# 3. dev 完整栈
make deps-up && make run-dev
curl -s http://127.0.0.1:8888/api/v1/health
```
若你改壞了 yaml可從 repo 內的 `gateway.yaml` / `gateway.dev.yaml` 重新複製,再依本文件逐段打開需要的區塊。
---
## 相關文件
- [deploy/README.md](../deploy/README.md) — Docker Compose
- [internal/model/notification/README.md](../internal/model/notification/README.md) — 通知模組
- [internal/library/mongo/README.md](../internal/library/mongo/README.md) — Mongo 存取層