prefácio
Ao usar go para desenvolver serviços http, frequentemente definiremos estruturas de solicitação e retorno, bem como rotas, o que é uma perda de tempo. Existe uma maneira de evitar essa frequência ou reduzir a frequência? protoc-gen-hip nos ajuda a resolver esse problema. Com base no protobuffer para gerar automaticamente a lógica do código da API que precisamos
Como usar
ferramenta de download
- baixar protocolo
Primeiro você precisa baixar o sistema protoc mac: brew install protoc
Outros sistemas: github.com/protocolbuf…
- baixar protoc-gen-hip
// antes de ir 1.17
vá buscar -u github.com/GodWY/protoc-gen-hip@latest vá instalar github.com/GodWY/protoc-gen-hip
// após go1.17
vá instalar github.com/GodWY/protoc-gen-hip@latest
definir protobuffer
definir solicitação
syntax="proto3";
package account;
option go_package="pkg/gen/http/account";
message SendSmsCodeRQ {
// @gotags: json:"phone_num"
string PhoneNum = 1;
}
message SendSmsCodeRS {
}
definir serviço http
//@import:xxx.xxx.xxx @import:xxx.xxxx.xxxx
//@middle:xxx.Has()
//@root:/api/xx
service Account{
//@method:POST @middle:xxx.Has()
rpc SendSmsCode(SendSmsCodeRQ) returns (SendSmsCodeRS);
}
Executar geração de código
protocolo - --proto_path=. --hip_out=./ --go_out=./ ./proto/*.proto
código gerado
// Code generated by protoc-gen-go-hip. DO NOT EDIT.
// versions:v1.2.0
package account
// This is a compile-time assertion to ensure that this generated file
// is compatible with the kratos package it is being compiled against.
import (
"net/http"
"github.com/GodWY/gutil"
"xxx.xxx.xxx"
"github.com/gin-gonic/gin"
)
// generated http method
func registerAccountHttpHandler(srv *gin.Engine, srvs AccountHttpHandler) {
group := srv.Group("/api/account", xxx.Has())
group.POST("/v1/sendSmsCode", srvs.SendSmsCode, xxx.Has())
group.POST("/v1/accessLogin", srvs.AccessLogin)
}
var TAccount Account
func RegisterAccountHttpHandler(srv *gin.Engine, srvs Account) {
tmp := new(xxx_Account)
registerAccountHttpHandler(srv, tmp)
TAccount = srvs
}
type Account interface {
SendSmsCode(ctx *gin.Context, in *SendSmsCodeRQ) (out *SendSmsCodeRS, err error)
AccessLogin(ctx *gin.Context, in *AccessLoginRQ) (out *AccessLoginRS, err error)
}
// generated http handle
type AccountHttpHandler interface {
SendSmsCode(ctx *gin.Context)
AccessLogin(ctx *gin.Context)
}
type xxx_Account struct {
}
func (xx *xxx_Account) SendSmsCode(ctx *gin.Context) {
req := &SendSmsCodeRQ{}
if ok := ctx.Bind(req); ok != nil {
detail := "bind request error"
rt := gutil.RetFail(10000, detail)
ctx.JSON(http.StatusOK, rt)
return
}
rsp, err := TAccount.SendSmsCode(ctx, req)
if err != nil {
ctx.JSON(http.StatusOK, gutil.RetError(err))
return
}
ctx.JSON(http.StatusOK, gutil.RetSuccess("success", rsp))
}
func (xx *xxx_Account) AccessLogin(ctx *gin.Context) {
req := &AccessLoginRQ{}
if ok := ctx.Bind(req); ok != nil {
detail := "bind request error"
rt := gutil.RetFail(10000, detail)
ctx.JSON(http.StatusOK, rt)
return
}
rsp, err := TAccount.AccessLogin(ctx, req)
if err != nil {
ctx.JSON(http.StatusOK, gutil.RetError(err))
return
}
ctx.JSON(http.StatusOK, gutil.RetSuccess("success", rsp))
}
Notas
5. 支持导入三方包,自定义中间件和自定义路由
> 所有的自定义代码都是通过注释读取的。
- 自定义组中间件
> 每一个service对应gin都是一个组,定义组路由只需要使用`@middle:`关键字即可,value是对应的方法
- 导入项目包
> 在service中定义 `@import` 可以连续定义多个导入包
- 定义接口请求
> 在每个rpc接口中,自定义请求方法 `@method` 即可目前支持GET,POST,ANY 不区分大小写
- 定义接口中间件
> 在接口注释中 `@middle` 即可定义自定义和gin中间件
- 如何自定义组路由
> 在service 定义`@root`即可
usar
```
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type AccSrc struct {
}
func (a AccSrc) SendSmsCode(ctx *gin.Context, in *account.SendSmsCodeRQ) (out *account.SendSmsCodeRS, err error) {
panic("implement me")
}
func (a AccSrc) AccessLogin(ctx *gin.Context, in *account.AccessLoginRQ) (out *account.AccessLoginRS, err error) {
panic("implement me")
}
func main() {
en := gin.New()
ac:=&AccSrc{}
account.RegisterAccountHttpHandler(en,ac)
en.Run(":8081")
}
func Logger() gin.HandlerFunc {
return func(context *gin.Context) {
fmt.Printf("xxxxxx1")
}
}
Resumir
Usamos pb para obter a geração de roteamento que pode nos ajudar a gerar rapidamente o código http