2.go-kit教程go-kit启动http服务
Posted 高薪程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.go-kit教程go-kit启动http服务相关的知识,希望对你有一定的参考价值。
环境准备
- gokit工具集:
go get github.com/go-kit/kit
; - http请求路由组件:
go get github.com/gorilla/mux
;
快速上手
-
上代码
package main import ( "context" "encoding/json" "errors" "log" "net/http" "github.com/gorilla/mux" httptransport "github.com/go-kit/kit/transport/http" "github.com/go-kit/kit/endpoint" ) type MyService interface Foo(context.Context, string) (string, error) Bar(context.Context, int64) (bool, error) type myService struct func (s myService) Foo(ctx context.Context, str string) (string, error) return "foo" + str, nil func (s myService) Bar(ctx context.Context, n int64) (bool, error) return n%2 == 0, nil type fooRequest struct Str string `json:"str"` type fooResponse struct Str string `json:"str"` Err string `json:"err,omitempty"` type barRequest struct N int64 `json:"n"` type barResponse struct Result bool `json:"result"` Err string `json:"err,omitempty"` func makeFooEndpoint(svc MyService) endpoint.Endpoint return func(ctx context.Context, request interface) (interface, error) req := request.(fooRequest) res, err := svc.Foo(ctx, req.Str) if err != nil return fooResponseres, err.Error(), nil return fooResponseres, "", nil func makeBarEndpoint(svc MyService) endpoint.Endpoint return func(ctx context.Context, request interface) (interface, error) req := request.(barRequest) res, err := svc.Bar(ctx, req.N) if err != nil return barResponseres, err.Error(), nil return barResponseres, "", nil func decodeFooRequest(_ context.Context, r *http.Request) (interface, error) var req fooRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil return nil, err return req, nil func decodeBarRequest(_ context.Context, r *http.Request) (interface, error) var req barRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil return nil, err return req, nil func encodeResponse(_ context.Context, w http.ResponseWriter, response interface) error return json.NewEncoder(w).Encode(response) func main() // Create a new service svc := myService // Create the endpoints fooEndpoint := makeFooEndpoint(svc) barEndpoint := makeBarEndpoint(svc) // Create the router and register the endpoints r := mux.NewRouter() r.Methods("POST").Path("/foo").Handler(httptransport.NewServer( fooEndpoint, decodeFooRequest, encodeResponse, )) r.Methods("POST").Path("/bar").Handler(httptransport.NewServer( barEndpoint, decodeBarRequest, encodeResponse, )) // Start the server log.Fatal(http.ListenAndServe(":8080", r))
-
执行命令
curl http://127.0.0.1:8080/foo -d \'"data":"111"\' -XPOST
响应"str":"foo"
代码分层
-
目录结构
. ├── endpoints │ └── my_endpoint.go ├── go.mod ├── go.sum ├── main.go ├── services │ └── my_service.go └── transports └── my_transport.go
-
services/my_service.go
/** * @date: 2023/2/18 * @desc: 服务层 业务具体实现 */ package endpoints import "context" type MyServicer interface Foo(context.Context, string) (string, error) Bar(context.Context, int64) (bool, error) type MyService struct func (s *MyService) Foo(ctx context.Context, str string) (string, error) return "foo" + str, nil func (s *MyService) Bar(ctx context.Context, n int64) (bool, error) return n%2 == 0, nil
-
endpoints/endpoint.go
/** * @date: 2023/2/18 * @desc: endpoints 层 */ package endpoints import ( "context" "github.com/go-kit/kit/endpoint" services "kit-demo/services" ) type FooRequest struct Str string `json:"str"` type FooResponse struct Str string `json:"str"` Err string `json:"err,omitempty"` type BarRequest struct N int64 `json:"n"` type BarResponse struct Result bool `json:"result"` Err string `json:"err,omitempty"` func MakeFooEndpoint(svc services.MyServicer) endpoint.Endpoint return func(ctx context.Context, request interface) (interface, error) req := request.(FooRequest) res, err := svc.Foo(ctx, req.Str) if err != nil return FooResponseres, err.Error(), nil return FooResponseres, "", nil func MakeBarEndpoint(svc services.MyServicer) endpoint.Endpoint return func(ctx context.Context, request interface) (interface, error) req := request.(BarRequest) res, err := svc.Bar(ctx, req.N) if err != nil return BarResponseres, err.Error(), nil return BarResponseres, "", nil
-
transports/my_transport.go
/** * @date: 2023/2/18 * @desc: 传输层 http/rpc... */ package endpoints import ( "context" "encoding/json" "github.com/go-kit/kit/endpoint" httptransport "github.com/go-kit/kit/transport/http" "github.com/gorilla/mux" "kit-demo/endpoints" "net/http" ) func decodeFooRequest(_ context.Context, r *http.Request) (interface, error) var req endpoints.FooRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil return nil, err return req, nil func decodeBarRequest(_ context.Context, r *http.Request) (interface, error) var req endpoints.BarRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil return nil, err return req, nil func encodeResponse(_ context.Context, w http.ResponseWriter, response interface) error return json.NewEncoder(w).Encode(response) // MakeHttpHandler make http handler use mux func MakeHttpHandler(ctx context.Context, fooEndpoint, barEndpoint endpoint.Endpoint) http.Handler r := mux.NewRouter() options := []httptransport.ServerOption httptransport.ServerErrorEncoder(httptransport.DefaultErrorEncoder), r.Methods("POST").Path("/foo").Handler(httptransport.NewServer( fooEndpoint, decodeFooRequest, encodeResponse, options..., )) r.Methods("POST").Path("/bar").Handler(httptransport.NewServer( barEndpoint, decodeBarRequest, encodeResponse, options..., )) return r
-
main.go
package main import ( "context" "fmt" "kit-demo/endpoints" services "kit-demo/services" transports "kit-demo/transports" "net/http" "os" "os/signal" "syscall" ) func main() errChan := make(chan error) // Create a new service svc := services.MyService ctx := context.Background() // Create the endpoints fooEndpoint := endpoints.MakeFooEndpoint(&svc) barEndpoint := endpoints.MakeBarEndpoint(&svc) r := transports.MakeHttpHandler(ctx, fooEndpoint, barEndpoint) go func() fmt.Println("Http Server start at port:8080") handler := r errChan <- http.ListenAndServe(":8080", handler) () go func() c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) errChan <- fmt.Errorf("%s", <-c) () fmt.Println(<-errChan)
完整代码
以上是关于2.go-kit教程go-kit启动http服务的主要内容,如果未能解决你的问题,请参考以下文章