iT邦幫忙

2025 iThome 鐵人賽

DAY 11
0

第十一日:從零到 CRUD,API 工地正式開張

一、開場:文件終於下地,工地開始冒煙

昨天我們還在整理文件,聊「黃金守則」,把挑選、壓縮、多專家模式都搬出來,像個在工地外指指點點的監工。但話說回來,光有藍圖和安全帽,工地還是一片空地。

今天,終於動工。
目標很簡單卻也很關鍵:把系統最基礎的 CRUD 先打通。因為任何再宏偉的架構,最後都要回歸到「能不能新增一筆資料,能不能查得到它,能不能修改,能不能刪掉」。

這就像蓋大樓,先把水電管線接起來,不然什麼豪華裝潢都是空談。


二、工地日誌:從資料庫到 API 的流水線

1. 資料庫打地基

先從最底層的 Postgres schema 開始:

  • companies:公司基本資料
  • users:使用者,掛在公司底下
  • projects:專案,連到公司與使用者
  • bots:Teams Bot 資訊
  • bot_installations:Bot 的安裝紀錄
  • destinations:通知的發送目標
  • notifications:通知紀錄
  • billing_plans:計費方案
  • usage_records:使用紀錄
  • audit_logs:稽核紀錄
  • system_logs:系統層級 log
  • system_settings:系統設定
  • feature_flags:功能開關

整個 schema 就像大樓的基樁,每個表格是鋼筋水泥,FK 則是鋼梁的連結。

在這一步,我們還做了一個 init.sql,放了種子資料:

  • 一家公司
  • 幾個使用者
  • 一個測試專案
  • 一個測試 Bot
  • 一筆安裝紀錄
  • 一個目的地

這樣之後測試時不用每次都從空白開始。算是工地裡的「臨時水電」。


2. Repository 層:倉管進場

Repository 負責對應每個資料表的操作,單純負責收貨、出貨,完全不干涉上層邏輯。

今天完成了:

  • CompanyRepository
  • UserRepository
  • ProjectRepository
  • BotRepository
  • BotInstallationRepository
  • DestinationRepository
  • NotificationRepository

每個 Repository 的介面都包含基本 CRUD,外加一些查詢方法。比如 FindByCompanyIDListByProject 這類。

這層做完,就等於工地有了倉庫:磚瓦可以收進去,水泥可以領出來。


3. Service 層:施工班長

Service 負責業務邏輯,把 Repository 的操作串起來。今天最大的亮點是 NotificationService

但這裡馬上踩到一個坑:

  • CreateNotification 時,要同時新增通知紀錄,並且為每個目的地插入子紀錄。
  • 問題是我們沒有用 transaction!
    👉 如果某一個目的地插入失敗,就會留下半成品,導致資料不一致。

這就像大樓蓋到 20 樓突然停電,結果 18 樓有牆、19 樓沒牆、20 樓只有鋼筋。住戶會崩潰,DBA 也會崩潰。

所以這裡被我列入 TODO:下一步一定要補上 transaction。


4. Handler 與路由:接線師傅

接下來是 Gin Handler 與 API Route:

  • POST /companies
  • POST /users
  • POST /projects
  • POST /bots
  • POST /bot-installations
  • POST /destinations
  • POST /notifications

這就是 API 的最小七龍珠:收集齊了,就能召喚第一個 smoke test。

Handler 做的事不多:接收 request、呼叫對應 Service、回傳 JSON。乾淨俐落,不摻雜太多邏輯。


5. HTTP 伺服器:總電盤接好

最後是 HTTP server:

  • internal/api/server.go 註冊所有 middleware:CORS、RequestLogger。
  • cmd/server/main.go 初始化 DB 連線,把 Repository、Service、Handler 全部串起來。

這一刻,API 服務算是「電燈通了」。
雖然屋子裡還沒裝家具,但至少一開燈開關,會亮。


三、Smoke Test:第一次水管測壓

寫完 API,當然不能光看 log 自嗨,要做 smoke test。

於是寫了一個 scripts/curl_smoke.sh,流程如下:

  1. 建立公司
  2. 建立使用者
  3. 建立專案
  4. 建立 Bot
  5. 建立目的地
  6. 發送通知

第一次跑,卡在 ID 格式。因為 JSON key 大寫小寫不一致,結果整個流程爆掉。
修正後,用 here-doc 傳 JSON,並用 jq 抓 ID,成功跑通。

再跑一次,結果依舊正確,代表 idempotency 還算穩定。

這感覺就像工地第一次通水:水龍頭一打開,水真的流出來,而且沒爆管。


四、Code Review:美中不足的角落

雖然 CRUD 打通,但整個流程還有不少缺陷:

  1. JSON Tag 缺失

    • Go struct 回傳是 PascalCase,API 文件是 snake_case
    • 新手看到一定會懷疑人生:「這 API 是同一個專案的嗎?」
    • 解法:加上 json tag,或定義 DTO。
  2. Transaction 缺失

    • NotificationService 缺乏 transaction,風險很大。
  3. 測試不足

    • go test ./... 雖然能跑,但沒有實際測試檔。
    • 現在只有 smoke test 撐場,感覺像是用膠帶綁著水管。

五、今日心得:工地真的開張了

今天的進展很關鍵,因為這是專案第一次從「文件」跨到「程式」。
總結一下:

  • ✅ Database schema 上線
  • ✅ Repository 層完成
  • ✅ Service 層初版完成
  • ✅ Handler & Router 上線
  • ✅ HTTP server 啟動成功
  • ✅ CRUD 全線打通
  • ✅ Smoke Test 成功

雖然還是個半成品,但至少今天可以很驕傲地說:

👉 工地開始冒煙,API 真的跑起來了。


六、展望明天:補強細節,避免豆腐渣工程

接下來的任務:

  • 修正 JSON Tag 與 DTO,讓 API 輸出對齊文件。
  • 加上 transaction,避免半成品紀錄。
  • 開始寫 unit test 與 integration test,不能再靠 curl 撐場。
  • 規劃 Docker Compose 與 CI pipeline,自動化起來。

✍️ Day11 收工感言
今天是 milestone:API 工地正式開張,第一次跑通一條龍 CRUD。雖然有不少缺陷,但這種「看到結果真的跑起來」的成就感,遠比文件更爽。


上一篇
第十日:黃金守則出爐,挑選・壓縮・多專家大法
下一篇
第十二日:CRUD 升級,全方位 API 工地驗收
系列文
Vibe Code與context engineering來打造個人專屬夥伴14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言