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服务的主要内容,如果未能解决你的问题,请参考以下文章

go-kit微服务:日志功能

2.搭建第一个http服务:三层架构

如何在 go-kit 中使用 zap logger?

最终,为什么选择go-kit

5.服务注册与发现Consul,简学API,手动注册和删除服务

React 教程 - 如何为 reactJs 应用程序启动节点服务器?