sqler sql 轉rest api 原始碼解析(一)應用的啟動入口
阿新 • • 發佈:2019-01-14
sqler sql 轉rest api 的原始碼還是比較簡單的,沒有比較複雜的設計,大部分都是基於開源
模組實現的。
說明: 當前的版本為2.0,程式碼使用go mod 進行包管理,如果本地執行注意golang 版本,我使用docker 執行,
參考 https://github.com/rongfengliang/sqler-docker-compose/blob/master/Dockerfile
依賴的開源包
- 配置解析的(比如bind,exec,validates,include。。。) 使用hashicorp/hcl ,同時使用了text/template 主要是處理sql 的
- redis 協議支援的(包含了list,help) tidwall/redcon
- validate,bind ,authorizer 的指定解析 dop251/goja golang 版的js 包
- exec sql 引數傳遞,通過js 包解析的,dop251/goja
- rest 路由、請求處理 labstack/echo ,基於context 的巨集解析引數傳遞
處理流程
入口
入口主要包含的資料庫連線的檢測,以及配置檔案巨集的解析,以及rest 、resp 支援協議的啟動
- 啟動引數的定義
vars.go,主要是對於啟動引數的定義,包括dsn,driver,resp rest埠定義,同時定義了macrosManager
這個變數在init 階段進行初始化
// 啟動變數定義
var (
flagDBDriver = flag.String("driver", "mysql", "the sql driver to be used")
flagDBDSN = flag.String("dsn", "root: [email protected](127.0.0.1)/test?multiStatements=true", "the data source name for the selected engine")
flagAPIFile = flag.String("config", "./config.example.hcl", "the config file(s) that contains your endpoints configs, it accepts comma seprated list of glob style pattern")
flagRESTListenAddr = flag.String("rest", ":8025", "the http restful api listen address")
flagRESPListenAddr = flag.String("resp", ":3678", "the resp (redis protocol) server listen address")
flagWorkers = flag.Int("workers", runtime.NumCPU(), "the maximum workers count")
)
var (
errNoMacroFound = errors.New("Resource not found")
errValidationError = errors.New("Validation error")
errAuthorizationError = errors.New("Authorization Error")
)
var (
errStatusCodeMap = map[error]int{
errNoMacroFound: 404,
errValidationError: 422,
errAuthorizationError: 401,
}
)
// 巨集管理變數定義
var (
macrosManager *Manager
)
- init
init.go
init 使用的是golang 的特性,主要是對於資料庫驅動的載入、配置資料庫連線狀態的檢測、以及巨集的解析,賦值(vars.go )
{
// 配置資料庫狀態檢測
tstconn, err := sqlx.Connect(*flagDBDriver, *flagDBDSN)
if err != nil {
fmt.Println(color.RedString("[%s] %s - connection error - (%s)", *flagDBDriver, *flagDBDSN, err.Error()))
os.Exit(0)
}
tstconn.Close()
}
{
// 巨集的解析以及vars.go 中變數的賦值
manager, err := NewManager(*flagAPIFile)
if err != nil {
fmt.Println(color.RedString("(%s)", err.Error()))
os.Exit(0)
}
macrosManager = manager
}
- macrosManager 的處理
macrosManager 主要是解析hcl 配置檔案,並儲存map 物件中,同時提供了GET以及LIST 方便後邊
echo rest 框架處理巨集呼叫的
macrosManager 資料結構
type Manager struct {
// 巨集物件,包含了,rest 請求的生命週期的元件
macros map[string]*Macro
// 主要是為了使用使用text/template 模版解析exec 巨集
compiled *template.Template
}
Macro 資料結構
Macro 定義了每個巨集的完整資訊: method validator authorizer exec bind include(依賴),transformer 資料轉換
主要的方式是Call ,更具輸入的input 資料指定rest 的處理(資料校驗,資料繫結,依賴執行,資料轉換),後邊
為具體分析
type Macro struct {
Methods []string
Include []string
Validators map[string]string
Authorizer string
Bind map[string]string
Exec string
Aggregate []string
Transformer string
name string
manager *Manager
}
- mian 入口
main.go 主要是對於rest 以及resp 協議服務的初始化&&啟動
// resp 協議支援
go (func() {
err <- initRESPServer()
})()
// rest 協議支援
go (func() {
err <- initRESTServer()
})()
參考資料
https://github.com/dop251/goja
https://github.com/tidwall/redcon
https://github.com/labstack/echo
https://github.com/hashicorp/hcl