最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

全球新动态:2.【go-kit教程】go-kit启动http服务

来源:博客园


【资料图】

环境准备

  • gokit工具集:go get github.com/go-kit/kit
  • http请求路由组件:go get github.com/gorilla/mux

快速上手

  • 上代码

    package mainimport ("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 fooResponse{res, err.Error()}, nil}return fooResponse{res, ""}, 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 barResponse{res, err.Error()}, nil}return barResponse{res, ""}, nil}}func decodeFooRequest(_ context.Context, r *http.Request) (interface{}, error) {var req fooRequestif 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 barRequestif 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 servicesvc := myService{}// Create the endpointsfooEndpoint := makeFooEndpoint(svc)barEndpoint := makeBarEndpoint(svc)// Create the router and register the endpointsr := 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 serverlog.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 endpointsimport "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 endpointsimport ("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 FooResponse{res, err.Error()}, nil}return FooResponse{res, ""}, 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 BarResponse{res, err.Error()}, nil}return BarResponse{res, ""}, nil}}
  • transports/my_transport.go

    /** * @date: 2023/2/18 * @desc: 传输层 http/rpc... */package endpointsimport ("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.FooRequestif 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.BarRequestif 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 muxfunc 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 mainimport ("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 servicesvc := services.MyService{}ctx := context.Background()// Create the endpointsfooEndpoint := endpoints.MakeFooEndpoint(&svc)barEndpoint := endpoints.MakeBarEndpoint(&svc)r := transports.MakeHttpHandler(ctx, fooEndpoint, barEndpoint)go func() {fmt.Println("Http Server start at port:8080")handler := rerrChan <- 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)}

完整代码

  • https://github.com/daniuEvan/go-kit-demo/tree/main/kit-demo

关键词: 执行命令