
Gag
- Gag是一个用Go实现的HTTP API网关,Gag提供了一个声明性的接口,并且它具有高度的可配置性。
支持的功能
- 基于路径处理请求。
- 基于HTTP方法处理请求。
- 处理有配置的头信息的请求。
- 处理有配置好的头信息键的请求,同时还有值。
- 用你自己的处理程序处理请求,该处理程序实现了API组合模式。
- 将请求路由(重定向)到不同的服务。
- 为每个请求应用中间件。
例子
简单的路由
func main() {
g := gag.NewGag(gag.Config{Port: 8080})
g.Conditions.
Path("/foo").Method(http.MethodGet).Route(&gag.RouteRequest{Url: "http://some.url/route-to", HttpMethod: http.MethodGet}, g)
err := g.Serve()
if err != nil {
panic(err)
}
}
- 在上面的例子中,只有符合
/foo 路径、具有HTTP GET方法的请求才会被路由到http://some.url/route-to 。
简单处理
type sampleResponse struct {
Message string `json:"message"`
}
func sampleHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
res, err := json.Marshal(sampleResponse{Message: "sample handler!"})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("something went wrong.."))
}
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(res)
}
}
func main() {
g := gag.NewGag(gag.Config{Port: 8080})
g.Conditions.
Path("/bar").Method(http.MethodPost).HandlerFunc(sampleHandler(), g)
err := g.Serve()
if err != nil {
panic(err)
}
}
- 在上面的例子中,只有符合
/bar 路径、具有HTTP POST方法的请求才会被处理。
使用中间件
func sampleTimingMiddleware() func(h http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
h.ServeHTTP(w, r)
end := time.Now()
log.Printf("request time for %s: %v", r.URL.Path, end.Sub(start))
})
}
}
func main() {
g := gag.NewGag(gag.Config{Port: 8080})
g.Conditions().
Path("/some-path").Middlewares(sampleTimingMiddleware()).HandlerFunc(sampleHandler(), g)
err := g.Serve()
if err != nil {
panic(err)
}
}
- 由于Gag是建立在gorilla/mux之上的,所以path支持路径变量和更多的东西。 下面是一个使用path变量的示例代码:
func samplePathVariableHandler() http.HandlerFunc {
type sampleResponse struct {
Message string `json:"message"`
}
return func(w http.ResponseWriter, r *http.Request) {
vars := gorillaMux.Vars(r)
id, ok := vars["id"]
if !ok {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("something went wrong.."))
}
res, err := json.Marshal(sampleResponse{Message: fmt.Sprintf("id: %s", id)})
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("something went wrong.."))
}
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(res)
}
}
func main() {
g := gag.NewGag(gag.Config{Port: 8080})
g.Conditions().
Path("/this-is-path/{id}").HandlerFunc(samplePathVariableHandler(), g)
err := g.Serve()
if err != nil {
panic(err)
}
}