1.API服務器的總流程
分為兩步:
- 啟動API服務器
- API服務器對HTTP請求進行處理
2.API服務器啟動流程
- 解析配置文件,利用配置文件完成對服務器的初始化配置
- 初始化logger,開啟日志記錄
- 與數據庫建立連接
- 設置http連接(例如設置響應頭,注冊路由,注冊中間件)
3.HTTP 請求處理流程
-
DNS域名解析
DNS的過程是這樣的:首先我們知道我們本地的機器上在配置網絡時都會填寫DNS,這樣本機就會把這個url發給這個配置的DNS服務器,如果能夠找到相應的url則返回其ip,否則該DNS將繼續將該解析請求發送給上級DNS,整個DNS可以看做是一個樹狀結構,該請求將一直發送到根直到得到結果。現在已經擁有了目標ip和端口號,這樣我們就可以打開socket連接了。 -
建立連接
當我們輸入這樣一個請求時,首先要建立一個socket連接,因為socket是通過ip和端口建立的(tcp鏈接),所以之前還有一個DNS解析過程,把域名變成ip,如果url里不包含端口號,則會使用該協議的默認端口號。 -
發送請求
連接成功建立后,開始向web服務器發送請求,這個請求一般是GET或POST命令(POST用于FORM參數的傳遞)。GET命令的格式為GET 路徑/文件名 HTTP/1.0(
文件名指出所訪問的文件,HTTP/1.0指出Web瀏覽器使用的HTTP版本)
現在可以發送GET命令:GET /mydir/index.html HTTP/1.0
-
接收請求
API服務器收到這個請求,進行處理,首先根據 HTTP 請求行的信息來解析到 HTTP 方法和路徑,之后根據 API 服務器注冊的路由信息(大概可以理解為:HTTP 方法 + 路徑和具體處理函數的映射)找到具體的處理函數。 -
處理請求
在接收到請求之后,API 通常會解析 HTTP 請求報文獲取請求頭和消息體,然后根據這些信息進行相應的業務處理,HTTP 框架一般都有自帶的解析函數,只需要輸入 HTTP 請求報文,就可以解析到需要的請求頭和消息體。
例如對應剛剛的get請求,就會解析出請求的消息頭和消息體,然后API服務器就根據解析出來的內容,從它的文檔空間中搜索子目錄mydir的文件index.html。如果找到該文件,Web服務器把該文件內容傳送給相應的Web瀏覽器。
業務處理主要可以分為:
- 包含對數據庫的操作:需要訪問數據庫(增刪改查),然后獲取指定的數據,對數據處理后構建指定的響應結構體,返回響應包。
- 不包含對數據庫的操作:進行業務邏輯處理后,構建指定的響應結構體,返回響應包。
4.REST Web 框架選擇
要編寫一個 RESTful 風格的 API 服務器,首先需要一個 RESTful Web 框架,選擇 GitHub star 數最多的 Gin。采用輕量級的 Gin 框架,具有如下優點:
- 快速
基于 Radix 樹的路由,小內存占用。沒有反射。可預測的 API 性能。
- 支持中間件
傳入的 HTTP 請求可以由一系列中間件和最終操作來處理。例如:Logger,Authorization,GZIP,最終操作 DB。
- Crash 處理
Gin 可以 catch 一個發生在 HTTP 請求中的 panic 并 recover 它。這樣,你的服務器將始終可用。例如,你可以向 Sentry 報告這個 panic!
- JSON 驗證
Gin 可以解析并驗證請求的 JSON,例如檢查所需值的存在。
- 路由組
更好地組織路由。是否需要授權,不同的 API 版本…… 此外,這些組可以無限制地嵌套而不會降低性能。
- 錯誤管理
Gin 提供了一種方便的方法來收集 HTTP 請求期間發生的所有錯誤。最終,中間件可以將它們寫入日志文件,數據庫并通過網絡發送。
- 內置渲染
Gin 為 JSON,XML 和 HTML 渲染提供了易于使用的 API。
- 可擴展性
新建一個中間件非常簡單
5.配置解決方案
Viper是適用于Go應用程序的完整配置解決方案。它被設計用于在應用程序中工作,并且可以處理所有類型的配置需求和格式,具有如下特性:
- 設置默認值
- 從JSON、TOML、YAML、HCL、envfile和Java properties格式的配置文件讀取配置信息
- 實時監控和重新讀取配置文件(可選)
- 從環境變量中讀取
- 從遠程配置系統(etcd或Consul)讀取并監控配置變化
- 從命令行參數讀取配置
- 從buffer讀取配置
- 顯式配置值
從上面這些特性來看,Viper 毫無疑問是非常強大的,而且 Viper 用起來也很方便,在初始化配置文件后,讀取配置只需要調用 viper.GetString()、viper.GetInt() 和 viper.GetBool() 等函數即可。
Viper能夠執行下列操作:
- 查找、加載和反序列化JSON、TOML、YAML、HCL、INI、envfile和Java properties格式的配置文件;
- 提供一種機制為你的不同配置選項設置默認值;
- 提供一種機制來通過命令行參數覆蓋指定選項的值;
- 提供別名系統,以便在不破壞現有代碼的情況下輕松重命名參數;
- 當用戶提供了與默認值相同的命令行或配置文件時,可以很容易地分辨出它們之間的區別;