開始
在本書的第一部分剪决,我們將建一個項(xiàng)目框架梢薪,并為構(gòu)建我們的Greenlight API打下基礎(chǔ)耻讽。我們將:
- 為項(xiàng)目創(chuàng)建一個框架目錄結(jié)構(gòu)有决,并從宏觀上解釋我們的Go代碼和其他文件將如何組織。
- 建立HTTP服務(wù)器來監(jiān)聽傳入的HTTP請求污桦。
- 介紹一個合適的管理配置模式(通過命令行flags)并使用依賴項(xiàng)注入使依賴項(xiàng)在我們的處理程序可用亩歹。
- 使用httprouter包實(shí)現(xiàn)API路由,達(dá)到標(biāo)準(zhǔn)RESTful結(jié)構(gòu)凡橱。
項(xiàng)目配制和代碼結(jié)構(gòu)
首先創(chuàng)建一個greenlight目錄小作,作為這個項(xiàng)目的家目錄。我將在$HOME/Projects/greenlight上創(chuàng)建我的項(xiàng)目目錄稼钩,但如果你愿意顾稀,可以自由選擇不同的位置。
$ mkdir -p $HOME/Projects/greenlight
然后切換到這個目錄坝撑,使用go mod init命令為項(xiàng)目啟用模塊静秆。
運(yùn)行此命令時粮揉,您需要指定模塊路徑,這實(shí)際上是項(xiàng)目的唯一標(biāo)識符抚笔。在本書中扶认,我將使用greenlight.alexedwards.net作為我的模塊路徑,如果你跟隨操作的話殊橙,你應(yīng)該把它替換成你自己的路徑辐宾。
$ cd $HOME/Projects/greenlight
$ go mod init greenlight.alexedwards.net
go: creating new go.mod: module greenlight.alexedwards.net
此時你將在項(xiàng)目的根目錄下看到go.mod文件被創(chuàng)建了。如果你打開該文件膨蛮,內(nèi)容類似如下所示:
File: go.mod
module greenlight.alexedwards.net
go 1.16
在第一本Let’s Go書中詳細(xì)討論了Go module叠纹,但作為快速復(fù)習(xí),我們在這里回顧一下要點(diǎn)敞葛。
- 當(dāng)在你項(xiàng)目的根路徑下面有一個合法的go.mod文件的話誉察,說明你的項(xiàng)目是一個模塊。
- 當(dāng)你在項(xiàng)目中工作時制肮,使用go get去下載依賴包冒窍,然后對應(yīng)特定版本的依賴包將在go.mod中記錄。因?yàn)榘姹臼谴_定的豺鼻,所以很容易在其他的機(jī)器或環(huán)境中執(zhí)行代碼。
- 當(dāng)你在項(xiàng)目中運(yùn)行或構(gòu)建代碼款慨,Go將使用go.mod中記錄的特定依賴儒飒。如果需要的依賴并不在當(dāng)前機(jī)器中,Go將自動為你下載檩奠,以及任何遞歸依賴桩了。
- go.mod文件還定義了模塊路徑(就是前面說的greenlight.alexedwards.net)。這將用作項(xiàng)目中包導(dǎo)入的根路徑標(biāo)識符埠戳。
- 讓模塊根路徑保持唯一性井誉,是一個好的編碼習(xí)慣。Go社區(qū)的常見約定是使用你的URL作為模塊根路徑整胃。
如果你不確定go module的工作原理颗圣,可以查看Go module wiki,包含很多FAQ-注意可能有些內(nèi)容已經(jīng)過時屁使。
生成目錄結(jié)構(gòu)
現(xiàn)在project目錄已經(jīng)創(chuàng)建好了并包含go.mod文件在岂,可以繼續(xù)執(zhí)行以下命令創(chuàng)建項(xiàng)目結(jié)構(gòu):
$ mkdir -p bin cmd/api internal migrations remote
$ touch Makefile
$ touch cmd/api/main.go
此時項(xiàng)目的目錄結(jié)構(gòu)應(yīng)該如下所示的樣子:
.
|____cmd
| |____api
| |____main.go
|____migrations
|____go.mod
|____bin
|____Makefile
|____internal
|____remote
我們花點(diǎn)時間來討論這些文件和文件夾,并解釋它們在項(xiàng)目中所起的作用蛮寂。
- bin目錄包含應(yīng)用編譯后的二進(jìn)制文件蔽午,可直接部署到生成環(huán)境中。
- cmd/api目錄包含Greenlight項(xiàng)目的API代碼文件酬蹋。包括運(yùn)行HTTP服務(wù)器及老、讀寫HTTP請求以及認(rèn)證管理等代碼抽莱。
- internal目錄包含API使用的各種輔助包。包括與數(shù)據(jù)庫交互骄恶、數(shù)據(jù)校驗(yàn)食铐、發(fā)送郵件等虱歪⊥讲郑基本上任何非應(yīng)用特定但可復(fù)用的代碼都放在這里。在cmd/api中的代碼會導(dǎo)入internal目錄的代碼(但從來沒有反過來導(dǎo)入的)
- imgrations目錄包含數(shù)據(jù)庫SQL遷移文件癌别。
- remote目錄包含配制文件和設(shè)置腳本悔捶。
- go.mod文件申明項(xiàng)目依賴铃慷,版本和module路徑。
- Makefile文件包含常見自動執(zhí)行管理任務(wù)的方法蜕该,例如:代碼審計(jì)犁柜、構(gòu)建二進(jìn)制文件和執(zhí)行數(shù)據(jù)庫遷移。
要重點(diǎn)指出的是internal目錄在Go中有特殊的含義:在這個目錄中的任何包堂淡,只能被該目錄的父目錄導(dǎo)入使用馋缅。在我們的項(xiàng)目中,這意味著internal中的所有包只能被greenlight項(xiàng)目中代碼所引用绢淀∮┿玻或者,從另一個角度來說皆的,這意味著internal的任何包都不能通過項(xiàng)目外部的代碼導(dǎo)入覆履。這是有用的,因?yàn)樗梢苑乐蛊渌a庫導(dǎo)入和依賴我們internal目錄中的(可能未版本化和不支持的)包——即使項(xiàng)目代碼在GitHub中公開可用费薄。
hello world
在繼續(xù)下一步之前硝全,我們快速檢查下所有設(shè)置是否正確。用文本編輯器打開cmd/api/main.go文件楞抡,添加以下代碼:
package main
import "fmt"
func main() { fmt.Println("Hello world!")
}
保存文件伟众,并在終端中使用go run命令編譯和執(zhí)行cmd/api包中的代碼。如果一切正常召廷,您將看到以下輸出:
$ go run ./cmd/api
Hello world!