gokit的理解
Posted lishuangquan1987
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gokit的理解相关的知识,希望对你有一定的参考价值。
理解的流程图如下所示:
现更加具体示例来理解。
示例目的
新建两个WebApi:
-
根据UserId获取UserInfo
-
获取所有的年龄大于30的UserInfo
期望如下: -
请求
http://xxxx:8080?userId=1
,返回如下格式:
user_id:1,
user_name:"tony",
age:35
- 请求
http://xxxx:8081?age=30
返回格式如下:
[
user_id:1,
user_name:"tony",
age:35
,
user_id:2,
user_name:"TEST",
age:40
,
]
开始编码
搭建使用gokit的项目目录:
为了避免命名冲突所以在三个文件夹和包名称前面加上了My
,不过不影响,只不过是名称而已
初始化包管理器
go mod init microservicetest
引用gokit
go get -u github.com/go-kit/kit
定义通用的Model实体
model.go
:
package Model
type UserInfo struct
UserId int `json:"user_id"`
UserName string `json:"user_name"`
Age int `json:"age"`
定义业务逻辑
上的请求和响应
业务逻辑上的请求和响应,需要为结构体
请注意,为什么要定义业务逻辑上的请求和响应:
这里有个区分:
- 传输层(http请求)的参数和响应
- 业务逻辑处理的请求(方法参数)和响应(方法返回值)
这两个是不一样的,但是有一些关键的信息关联。
传输层(http请求)的参数,只是提供一些关键的简单的信息,比如用户ID等
业务逻辑处理的请求,包含业务逻辑处理所需要的全部参数。
比如:http请求中包含很多参数,有用户ID,有token,有用户姓名,我们的逻辑处理可能只需要用到用户ID。
又比如:http请求中只包含关键信息用户ID,但是连接数据的信息没有包含,业务逻辑层的处理函数可能会使用到这些。
简单来讲,就是如下的一个转换过程:
从http
请求中得到我们需要的信息,组成业务逻辑的request
。
这个定义过程,放在endpoint.go
中:
- 请求
http://xxxx:8080?userId=1
,返回如下格式:
user_id:1,
user_name:"tony",
age:35
对应的Request与Response如下:
type GetUserInfoByUserIdRequest struct
UserId int `json:"user_id"`
type GetUserInfoByUserIdResponse struct
UserInfo
- 请求
http://xxxx:8081?age=30
返回格式如下:
[
user_id:1,
user_name:"tony",
age:35
,
user_id:2,
user_name:"TEST",
age:40
,
]
对应的Request与Response如下:
type GetUserInfoByMoreThanAgeRequest struct
Age int `json:"age"`
type GetUserInfoByMoreThanAgeResponse struct
UserInfos []UserInfo
定义核心业务逻辑函数
在MyServer
中定义核心业务逻辑。即如何根据业务逻辑的参数得到业务逻辑的返回值。
这里可能需要连接数据,可能需要从其他地方请求数据等等。
server.go
:
package Myserver
import (
"microservicetest/Model"
)
type IMyServer interface
GetUserById(userId int) Model.UserInfo
GetUsersByMoreThanAge(age int) []Model.UserInfo
type Myserver struct
func (s *Myserver) GetUserById(userId int) Model.UserInfo
return Model.UserInfo
UserId: 1,
UserName: "tony",
Age: 35,
func (s *Myserver) GetUsersByMoreThanAge(age int) []Model.UserInfo
return []Model.UserInfo
Model.UserInfo
UserId: 1,
UserName: "tony",
Age: 35,
,
Model.UserInfo
UserId: 2,
UserName: "TEST",
Age: 40,
,
再回到Myendpoint
中,调用Myserver
中的业务逻辑,构造Endpoint
endpoint.go
:
func MakeGetUserInfoByUserIdEndpoint(s Myserver.IMyServer) endpoint.Endpoint
return func(ctx context.Context, request interface) (response interface, err error)
r, ok := request.(GetUserInfoByUserIdRequest)
if !ok
return GetUserInfoByUserIdResponse, nil
return GetUserInfoByUserIdResponseUserInfo: s.GetUserById(r.UserId), nil
func MakeGetUserInfoByMoreThanAgeEndpoint(s Myserver.IMyServer) endpoint.Endpoint
return func(ctx context.Context, request interface) (response interface, err error)
r, ok := request.(GetUserInfoByMoreThanAgeRequest)
if !ok
return GetUserInfoByMoreThanAgeResponse, nil
return GetUserInfoByMoreThanAgeResponseUserInfos: s.GetUsersByMoreThanAge(r.Age), nil
最后Transport层
Transport层定义了如何从*http.Request
中解析到我们需要的参数,以及通过http.ResponseWriter
将最终的结果以什么样的格式和形式反馈出去.
transport.go
:
package Mytransport
import (
"context"
"encoding/json"
"microservicetest/Myendpoint"
"net/http"
"strconv"
)
func DecodeGetUserByIdRequest(c context.Context, request *http.Request) (interface, error)
userIdStr := request.URL.Query().Get("user_id")
userId, err := strconv.Atoi(userIdStr)
if err != nil
return nil, err
return Myendpoint.GetUserInfoByUserIdRequestUserId: userId, nil
func EncodeResponse(c context.Context, w http.ResponseWriter, response interface) error
return json.NewEncoder(w).Encode(response)
func DecodeGetUserByMoreThanAgeRequest(c context.Context, request *http.Request) (interface, error)
ageStr := request.URL.Query().Get("age")
age, err := strconv.Atoi(ageStr)
if err != nil
return nil, err
return Myendpoint.GetUserInfoByMoreThanAgeRequestAge: age, nil
最终使用
main.go
:
package main
import (
"fmt"
"microservicetest/Myendpoint"
"microservicetest/Myserver"
"microservicetest/Mytransport"
"net/http"
kitHttp "github.com/go-kit/kit/transport/http"
)
func main()
s := &Myserver.Myserver
getUserInfoByUserIdServer := Myendpoint.MakeGetUserInfoByUserIdEndpoint(s)
getUserInfoByMoreThanAgeServer := Myendpoint.MakeGetUserInfoByMoreThanAgeEndpoint(s)
s1 := kitHttp.NewServer(getUserInfoByUserIdServer, Mytransport.DecodeGetUserByIdRequest, Mytransport.EncodeResponse)
s2 := kitHttp.NewServer(getUserInfoByMoreThanAgeServer, Mytransport.DecodeGetUserByMoreThanAgeRequest, Mytransport.EncodeResponse)
go http.ListenAndServe(":8080", s1)
go http.ListenAndServe(":8081", s2)
fmt.Println("server is start")
select
以上是关于gokit的理解的主要内容,如果未能解决你的问题,请参考以下文章
NUCLEO-L496ZG+Gokit3S+Rtthead+AT组件组网