最近在準備畢業(yè)設(shè)計,雖然為 Android 項目鞠评,但還是需要一些后端支持,所以我就想能不能有一種方便的方式開發(fā)后端 api 的方式。
在之前 Rails 開發(fā)中畦徘,養(yǎng)成的了“急躁”的好習慣,轉(zhuǎn)到 Go 后抬闯,明顯感覺思維的轉(zhuǎn)變井辆,Go 的思維方式相對 Rails 來說,更注重正交性溶握,清晰度杯缺,KISS。
所以開發(fā)之前睡榆,我明確了這個項目的定位:
- 能快速開啟一個符合 Restful 原則的 api 服務器萍肆。
- 實現(xiàn)
http.Helper
接口袍榆,能組合別的路由,保證擴展性塘揣。 - 用 json 文件包雀,不用數(shù)據(jù)庫,降低復雜度亲铡,能回寫到文件馏艾,保證數(shù)據(jù)一致性。
- 能實現(xiàn)簡單的數(shù)據(jù)驗證奴愉。
然后琅摩,決定了主要的 struct ApiFaker 的主要成員變量及其對外接口:
type ApiFaker struct {
// 匿名組合,使用 Engine 的路由
*gin.Engine
// json api 文件目錄
ApiDir string
// 內(nèi)部路由
Routers []*Router
// 外部路由
TrueMux http.Handler
// 內(nèi)部路由的前綴
Prefix string
}
// 創(chuàng)建新的 ApiFaker
func NewWithApiDir(dir string) (*ApiFaker, error)
// 設(shè)置 ApiFaker 前綴并組合其外部路由
func (af *ApiFaker) MountTo(path string, handler http.Handler)
// 將運行事的數(shù)據(jù)回寫到 json 文件中
func (af *ApiFaker) SaveToFile()
// 實現(xiàn) http.Handler 接口
func (af *ApiFaker) ServeHTTP(rw http.ResponseWriter, req *http.Request)
這一步锭硼,非常重要房资,因為它關(guān)系到整個項目的走向,正所謂檀头,選擇比努力重要轰异。然而,大部分項目都不能在一開始就確定所有變量和方法暑始,然后不再改變搭独,所以我們的設(shè)計標準就是KISS,從最核心的功能出發(fā)廊镜,逐步迭代牙肝。
接下來要設(shè)計的就是 Router
及其包含的最復雜的 Model
:
- 一個 Rouer 應該包含一個資源,可等同于數(shù)據(jù)庫中的 table, 及其一系列 restful 的 path嗤朴。
- 資源對應的就是 Model配椭,它應該:
- 記錄資源的每一個 table 的 column
- 基本的 CRUD
- 由于還要回寫到 json 文件,所以應該有一個標示記錄數(shù)據(jù)是否改變
- 需要對應 json 文件的結(jié)構(gòu)雹姊,和運行時數(shù)據(jù)的容器
type Router struct {
Model *Model
Routes []Route
filePath string
}
type Model struct {
Name string
Seeds []map[string]interface{}
Columns []*Column
Set *gset.SetThreadSafe
dataChanged bool
sync.Mutex
}
這里用到的我之前的實現(xiàn)的一個集合 gset
到這里股缸,我們已經(jīng)設(shè)計好項目的邊界,和主要的數(shù)據(jù)結(jié)構(gòu)吱雏,當然還有一些細節(jié)沒有設(shè)計敦姻,比如,Route
和 Colmun
還有運行時的數(shù)據(jù)管理歧杏。 然而只要方向確定镰惦,內(nèi)部不斷迭代,一定能到達一個穩(wěn)定的水平得滤。
由于我 Go 開發(fā)經(jīng)驗和設(shè)計能力有限陨献,還請高手可以指點。
源碼:github.com/Focinfi/apifaker
服務器設(shè)計文章:許式偉:服務端開發(fā)那些事兒