[Golang] 實作 RESTful API

Teddy
Goons
Published in
7 min readMay 1, 2020

本篇目標是使用 Golang 寫出 CRUD 4個 API 的服務、並連結至 Mongodb 資料庫,接著建置到 Docker 環境上,最後使用 Postman 進行測試。

整個操作流程大致上可以分成以下幾個步驟:

  • Golang 專案架構規劃以及 API 功能開發。
  • 在 Docker 的環境上建置 Mongodb 和 API 的容器。
  • 部署到 server 上並啟用服務。

接著可以開始來一步步的實作出這樣一個需求的服務:

(1) Golang 專案架構規劃以及 API 功能開發。

在開發前當然需要先規劃好我們的專案架構,這邊參考了 Go 實作 Restful API 這篇教學的設計架構,把專案分成了以下幾個部分:

  1. main:整個專案的起始點。
  2. router:用來管理 API 的路徑。
  3. controller:負責控制處理流程。
  4. services:接收請求後,用來回應一些對應資料。

資料夾的目錄結構最後會是這樣子:

由於這篇教學說明得蠻清楚的,大部分參考裡面的程式碼,只針對所需要的模型以及 API 的功能進行了修改,這邊只提出對於模型相關欄位的定義。

實作需求上,期望有個後台記錄產品使用者回報的問題;在定義好模型後,我們需要在初始化時先連結近資料庫,這邊需要注意的是資料庫的路徑設定,連結到本機的路徑和在 docker 上連結到不同的容器的路徑是不一樣的。

// 連結到名為 mongodb 的容器裡
databaseURL = "mongodb://mongodb:27017"
// 單純在本機測試的路徑,如果這一段運行在 docker 上他會連到容器裡的 localhost
databaseURL = "mongodb://:27017"

接著依照需求開出了 5 支 API:

  1. 使用 POST 來新增問題描述:產生一個不會重名的 ID、圖片使用 base 64的 string 進行傳輸。
  2. 使用 GET 來取得問題列表:不輸入參數會回傳所有列表內容,也可以輸入 ID 、標題、新增時間等等來過濾列表已取得特定資料。
  3. 使用 DELETE 進行刪除資料:對於已經處理完畢的問題或是不小心回報錯誤的內容進行刪除。
  4. 使用 POST 對於新增後的問題進行修改內容:需要帶入 ID 以及需要修改的欄位和對應的內容進行修改,其餘不修改的欄位則不需要上傳。
  5. 使用 GET 在使用者點擊上傳圖片的網址可以進行瀏覽問題說明的圖片。

(2) 在 Docker 的環境上建置 Mongodb 和 API 的容器。

使用 Docker 之前當然需要先進行安裝,這裡參考這篇教學 How To Install Docker On Ubuntu 18.04 Bionic Beaver

在完成功能開發後,需要把這些內容建置到 docker 的環境上,第一個步驟需要先編譯好 Dockerfile,這邊我的寫法是有幾個步驟:

  1. 使用 golang:1.11.2-alpine 作為底層的環境。
  2. 把本地端的文件使用 ADD 複製根目錄以及檔案到容器裡面。
  3. 使用 RUN 在容器裡面產生 git 、 儲存圖片的檔案夾、golang 使用到相關的套件位置以及讓應用程序跑起來的指令。
  4. 指定接收的 Port 為 3000。
  5. 容器的進路點目錄。

每個人的需求不同,其他相關指令可以參考官方文件進行客製化的調整。

FROM golang:1.11.2-alpine
WORKDIR /go/src/api
ADD . /go/src/api
RUN apk add git \
&& cd /go/src/api \
&& mkdir uploaded \
&& go get github.com/gorilla/mux \
&& go get go.mongodb.org/mongo-driver/mongo \
&& go get go.mongodb.org/mongo-driver/mongo/options \
&& go get github.com/aws/aws-sdk-go/aws \
&& go build
EXPOSE 3000
ENTRYPOINT ./api

由於需要建立兩個容器,分別為 golang 的應用程序、mongodb資料庫,所以會需要一個共通的網路 ( container network ) 來連結。在終端機輸入下面的指令來新增一個名為 golangapi_defualt 的網路。

docker network create -d bridge golangapi_defualt

使用底層 image: mongo:latest + network: golangapi_defualt 建立出 db 的 container 名稱為 mongodb。

docker run -itd --name mongodb --network golangapi_defualt -p 27017:27017 mongo:latest

使用 Dockerfile 建立 golang 服務的 image 名稱為 mongo-microservice 。

docker build -t mongo-microservice .

使用底層 image: mongo-microservice + network: container-net 建立出 go 的 container 名稱為 go-mongo-microservice。

docker run --name go-mongo-microservice -d -p 3000:3000 --network golangapi_defualt mongo-microservice:latest

這幾個步驟大致上直接輸入不會產生什麼特別的問題,只要注意一下有時候可能某些 port 已經被佔用導致建立失敗,這時候可以參考 https://dev.to/dechamp/the-dreaded-bind-address-already-in-use-kill-it-583l 在確認後釋放被佔用的 port。

可能在過程中會不知不覺建立了不少沒有用到的 image 或是 container,也可以參考這篇 https://note.qidong.name/2017/06/26/docker-clean/ 來清除沒有使用到的內容。

(3) 部署到 server 上並啟用服務。

到這裡大致上已經完成了所有的實作內容,我們只要確認一下 container 是否已經在 server 上面跑起來了就好。在終端機輸入以下指令:

docker ps

使用 postman 進行一下測試:

最後整個後台部署後,就可以依照應用在前端網頁來查詢內容、也可以透過介接 API 於行動裝置上來新增問題給予工程師修復 issue。

這篇內容主要是實作一個簡單的服務,所以全程以能夠 word run 為優先,過程還有很多的問題沒有考量進去,例如還沒使用 Docker Volume 進行資料的備份,以及目前模型的設計,如果要撈取特定時間範圍的表單,可能需要進行調整欄位等等,不過先有一個雛形,後續再依照不同需求再進行調整即可,希望同時也能夠幫助到想要對後端進行了解的讀者 ^^

我是果思設計的 iOS 工程師 Teddy,我們專注在 App 設計與 App 開發,希望文章對各位有幫助!非常期待在留言區與大家討論、吸收更多觀點:)

--

--