Cwww3's Blog

Record what you think

0%

go-kit

go-kit

入门

go-kit 分为三层:Transport 层、Endpoint 层、Service 层。

Transport 层:负责与传输协议 HTTP、GRPC、THRIFT 等相关的逻辑处理。

Endpoint 层: 负责 request、response 格式的转换,以及提供公用拦截器

Service 层: 专注于业务逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
# 目录结构

go-kit-demo
├── endpoint
│   └── endpoint.go
├── go.mod
├── go.sum
├── main.go
├── service
│   └── service.go
└── transport
└── transport.go

  • endpoint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

package endpoint

import (
"context"
"github.com/go-kit/kit/endpoint"
"go-kit-demo/service"
)

// 定义请求响应格式
type HelloRequest struct {
Name string
}

type HelloResponse struct {
Reply string
}

func NewHelloEndpoint(s service.IService) endpoint.Endpoint{
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
r,ok := request.(HelloRequest)
if !ok {
return HelloResponse{},nil
}
return HelloResponse{Reply: s.Hello(r.Name)},nil
}
}
  • service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package service

import "fmt"

// 业务类
type IService interface {
Hello(name string) string
}

type Service struct {
Name string
}

func (s Service)Hello(name string) string {
return fmt.Sprintf("name:%v",name)
}

  • transport.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package transport

import (
"context"
"encoding/json"
"errors"
localEndpoint "go-kit-demo/endpoint"
"net/http"
)

// 负责与传输协议相关的逻辑
func HelloDecodeRequest(ctx context.Context,request *http.Request) (interface{},error) {
name := request.URL.Query().Get("name")
if name == "" {
return nil,errors.New("参数为空")
}
return localEndpoint.HelloRequest{Name: name},nil
}
func HelloEncodeResponse(ctx context.Context,w http.ResponseWriter,response interface{}) error {
w.Header().Set("Content-type","application/json;charset=utf-8")
return json.NewEncoder(w).Encode(response)
}
  • main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
httpTransport "github.com/go-kit/kit/transport/http"
localEndpoint "go-kit-demo/endpoint"
"go-kit-demo/service"
"go-kit-demo/transport"
"net/http"
)

func main() {
// 业务接口服务
s := service.Service{}
// 创建业务服务
helloEndpoint := localEndpoint.NewHelloEndpoint(s)
// 使用 kit 创建 handler
// 传入 业务服务 以及 定义的 加密解密方法
helloServer := httpTransport.NewServer(helloEndpoint,transport.HelloDecodeRequest,transport.HelloEncodeResponse)
http.ListenAndServe(":9090",helloServer)
}

  • 测试
image-20211009161918628

中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 目录结构
go-kit-demo
├── endpoint
│   └── endpoint.go
├── go.mod
├── go.sum
├── main.go
├── middleware
│   └── logMiddleware.go
├── service
│   └── service.go
└── transport
└── transport.go

  • logMiddleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package middleware

import (
"context"
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/endpoint"
)

//声明一个中间件类型
type Middleware func(endpoint.Endpoint) endpoint.Endpoint

// 日志中间件 在开始和结束打印日志
func LogMiddleware(logger log.Logger) Middleware {
return func(next endpoint.Endpoint) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
logger.Log("msg", "call start")
defer logger.Log("msg", "call end")
return next(ctx, request)
}
}
}

  • main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main

import (
"github.com/go-kit/kit/log"
httpTransport "github.com/go-kit/kit/transport/http"
localEndpoint "go-kit-demo/endpoint"
"go-kit-demo/middleware"
"go-kit-demo/service"
"go-kit-demo/transport"
"net/http"
"os"
)

func main() {
// 业务接口服务
s := service.Service{}
// 创建业务服务
helloEndpoint := localEndpoint.NewHelloEndpoint(s)
// 添加了log中间件的服务
logger := log.NewLogfmtLogger(os.Stderr)
helloEndpoint = middleware.LogMiddleware(logger)(helloEndpoint)
// 使用 kit 创建 handler
// 传入 业务服务 以及 定义的 加密解密方法
helloServer := httpTransport.NewServer(helloEndpoint, transport.HelloDecodeRequest, transport.HelloEncodeResponse)
http.ListenAndServe(":9090", helloServer)
}

  • 测试

image-20211009163859928

源码

项目源码

Donate comment here.