gors

package module
v1.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2023 License: MIT Imports: 4 Imported by: 0

README

gors

gors是一个代码生产器,基于个服务接口和描述,自动创建一个符合gin路由规则的服务.

快速开始

  1. 安装gors:
go install github.com/go-leo/gors/cmd/gors@latest
  1. 定义一个服务接口:
//go:generate gors -service Service

// Service
// @GORS @Path("/api)  @Path("/v1)
type Service interface {
	// Method
    // @GORS @GET @Path("/method/:id) @UriBinding @JSONRender
    Method(context.Context, *MethodReq) (*MethodResp, error)
}
type MethodReq struct {
	ID int `uri:"id"`
}
type MethodResp struct {
	V int `json:"v,omitempty"`
}
  1. 运行一下命令,生产文件service_gors.go
go generate ./...
// Code generated by "gors -service Service"; DO NOT EDIT.
package demo

import (
	gin "github.com/gin-gonic/gin"
	gors "github.com/go-leo/gors"
	http "net/http"
)

func ServiceRoutes(srv Service) []gors.Route {
	return []gors.Route{
		{
			HTTPMethod: http.MethodGet,
			Path:       "/api/v1/method/:id",
			HandlerFunc: func(c *gin.Context) {
				var req *MethodReq
				var resp *MethodResp
				var err error
				req = new(MethodReq)
				if err = c.BindUri(req); err != nil {
					c.String(http.StatusBadRequest, err.Error())
					_ = c.Error(err).SetType(gin.ErrorTypeBind)
					return
				}
				if err := gors.Validate(req); err != nil {
					c.String(http.StatusBadRequest, err.Error())
					_ = c.Error(err).SetType(gin.ErrorTypeBind)
					return
				}
				ctx := gors.NewContext(c)
				resp, err = srv.Method(ctx, req)
				if err != nil {
					if httpErr, ok := err.(*gors.HttpError); ok {
						c.String(httpErr.StatusCode(), httpErr.Error())
						_ = c.Error(err).SetType(gin.ErrorTypePublic)
						return
					}
					c.String(http.StatusInternalServerError, err.Error())
					_ = c.Error(err).SetType(gin.ErrorTypePrivate)
					return
				}
				statusCode := gors.GetCodeFromContext(ctx)
				c.JSON(statusCode, resp)
			},
		},
	}
}
  1. 实现服务接口
var _ demo.Service = new(Service)

type Service struct {}

func (svc *Service) Method(ctx context.Context, req *demo.MethodReq) (*demo.MethodResp, error) {
	fmt.Println(req.ID)
	return &demo.MethodResp{V: 10}, nil
}
  1. 创建gin.Engine,注册路由并启动http服务:
var routers []gors.Router
routers = append(routers, demo.ServiceRouters(new(svc.Service))...)

engine := gin.New()
for _, router := range routers {
    engine.Handle(router.HTTPMethod, router.Path, router.HandlerFunc)
}

srv := http.Server{Handler: engine}
listen, err := net.Listen("tcp", ":8088")
if err != nil {
    panic(err)
}
err = srv.Serve(listen)
if err != nil {
    panic(err)
}

方法入参

参数一

第一个参数必须是context.Context,其他类型都会生成失败。

参数二

第二个参数有四种类型:io.Reader[]bytestring结构体指针,其他类型都会生成失败。

  • io.Reader,直接取http.Request里的Body。所有Binding策略都不能用。
  • []byte,将http.Request里的Body以字节数组形式全部读出。所有Binding策略都不能用。
  • string,将http.Request里的Body以字符串形式全部读出。所有Binding策略都不能用。
  • 结构体指针,所有Binding策略都适用,将path、query、header和body中的参数,绑定到内部字段里。

响应

参数一

第一个响应参数有四种类型:string[]byteio.Reader结构体指针,其他类型都会生成失败。

  • io.Reader,将io.Reader写入响应的Body中,必须要配合@ReaderRender注解使用,可以自定义响应Content-Type,比如@ReaderRender(video/mpeg4)
  • []byte,将[]byte写入响应的Body中,必须要配合@BytesRender注解使用,可以自定义响应Content-Type,比如@BytesRender(image/png)
  • string,可以配合不同的Render策略进行响应。
    • @TextRender, 将文本以Content-Type"text/plain; charset=utf-8"写入响应的Body中。
    • @HTMLRender, 将文本以Content-Type"text/html; charset=utf-8"写入响应的Body中。
    • @StringRender, 将文本写入响应的Body中,可以自定义响应Content-Type,比如@StringRender(text/xml)
    • @RedirectRender, 重定向渲染,重定向到文本指定的位置。
  • 结构体指针,需要配合各自Render策略,将结构体指针序列化成[]byte后,写入响应的Body中。

参数二

第一个请求参数必须是error,其他类型都会生成失败。 如果error是*gors.HttpError类型,将设置指定的status code,然后将错误的文本写入响应的Body。 否则会设置500的status code,然后将错误的文本写入响应的Body。

注解大全

@GORS

必须设置, 基础注解。 代表gors的注解配置的开始,没有@GORS开始的都会被忽略。

@Path

必须设置,路径注解。

  • 可以设置参数,@Path(/api)
  • 如果设置在接口名上,代表为所有path定义基础的path。
  • 如果设置在方法上,代表为此方法定义path。
  • 可以设置多个@Path注解,此时多个path会被拼接成一个。

HTTP Method注解

必须设置,设置此方法的只能响应指定的Method请求。 Method只能有一个有效,如果设置多个,只有最后一个有效。支持标准库里定义的9种method:

@GET

此注解设置此方法为Get请求。

@HEAD

此注解设置此方法为Head请求。

@POST

此注解设置此方法为Post请求。

@PUT

此注解设置此方法为Put请求。

@PATCH

此注解设置此方法为Patch请求。

@DELETE

此注解设置此方法为Delete请求。

@CONNECT

此注解设置此方法为Connect请求。

@OPTIONS

此注解设置此方法为Options请求。

@TRACE

此注解设置此方法为Trace请求。

Binding 注解

数据绑定注解。

  • 当第二个参数是结构体指针时候,可以设置。
  • 可以设置多种Binding策略。
@UriBinding

将对应的Uri参数绑定到结构体指针中。

支持gin的路径参数语法gin的uri绑定策略

@QueryBinding

将对应的Query参数绑定到结构体指针中。

支持gin的只绑定Query策略

@HeaderBinding

将对应的Header参数绑定到结构体指针中。

支持gin的header绑定策略

@JSONBinding

将请求的Body以JSON形式解析出来,并绑定到结构体指针中。

@XMLBinding

将请求的Body以XML形式解析出来,并绑定到结构体指针中。

@FormBinding

将请求的Query和Body同时以Form形式解析出来,并绑定到结构体指针中。

不支持文件上传。

支持gin的form绑定策略

@FormPostBinding

将请求的Body以FormPost形式解析出来,并绑定到结构体指针中。

只支持application/x-www-form-urlencoded的Form请求。

不支持文件上传。

支持gin的urlencoded绑定策略

@FormMultipartBinding

将请求的Body以Multipart形式解析出来并绑定到结构体指针中。

只支持multipart/form-data的Form请求。

支持文件上传。

支持gin的Multipart绑定策略

@ProtoBufBinding

将请求的Body以protobuf形式解析出来并绑定到结构体指针中。

@MsgPackBinding

将请求的Body以msgpack形式解析出来并绑定到结构体指针中。

@YAMLBinding

将请求的Body以YAML形式解析出来并绑定到结构体指针中。

@TOMLBinding

将请求的Body以TOML形式解析出来并绑定到结构体指针中。

@CustomBinding

预定义的Binding策略不能满足需求,需要使用自定义Binding策略,请求结构体需要实现gors.Binding接口。

Render 注解

响应渲染注解。

  • 方法的一个返回参数的类型不通,相对应的渲染也不同。
  • 只能设置一种渲染策略。
@BytesRender

字节数组渲染。

只有当方法的第一个返回参数类型为[]byte时才能使用,@BytesRender将数据以字节数组写入响应的Body中,可以自定义响应Content-Type,比如:@BytesRender(image/png)代表渲染一张图片。

@StringRender

字符串渲染。

只有当方法的第一个返回参数类型为string时才能使用,@StringRender将数据以文本的方式写入响应的Body中,可以自定义响应Content-Type,比如@StringRender(image/xml)代表渲染xml文件。

@TextRender

文本渲染。

只有当方法的第一个返回参数类型为string时才能使用,@TextRender将数据以文本的方式写入响应的Body中,Content-Type固定为text/plain; charset=utf-8

@HTMLRender

HTML渲染。

只有当方法的第一个返回参数类型为string时才能使用,@HTMLRender将数据以文本的方式写入响应的Body中,Content-Type固定为text/html; charset=utf-8

@RedirectRender

重定向渲染。

只有当方法的第一个返回参数类型为string时才能使用,此参数应该是个可以重定向的地址位置。

@ReaderRender

数据流渲染,只有当方法的第一个返回参数类型为io.Reader时才能使用,@ReaderRender将数据流写入响应的Body中,可以自定义响应Content-Type,比如:@ReaderRender(video/mpeg4)代表渲染一个视频文件。

@JSONRender

JSON渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@JSONRender将结构体指针以JSON格式序列化并且写入响应的Body中,Content-Type固定为application/json; charset=utf-8。参考gin文档-json

@IndentedJSONRender

漂亮的JSON渲染,在JSON渲染的基础上,加上了缩进和结束行。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@IndentedJSONRender将结构体指针以JSON格式序列化并且写入响应的Body中,Content-Type固定为application/json; charset=utf-8。比较耗资源。

@SecureJSONRender

安全的的JSON渲染,防止一些代码注入。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@SecureJSONRender将结构体指针以JSON格式序列化并且写入响应的Body中,Content-Type固定为application/json; charset=utf-8gin文档-SecureJSON

@JsonpJSONRender

jsonp方式渲染,jsonp可以跨域请求,如果查询参数callback存在,则将callback添加到响应体中。

只有当方法的第一个返回参数类型为结构体指针时才能使用。参考gin文档-jsonp

@PureJSONRender

纯净的JSON渲染,普通的JSON渲染,会将一些html特殊字符会被转义,比如<转成\u003c@PureJSONRender则不会转义。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@PureJSONRender将结构体指针以JSON格式序列化并且写入响应的Body中,Content-Type固定为application/json; charset=utf-8gin文档-PureJSON

@AsciiJSONRender

AsciiJSON渲染,只渲染Ascii字符,非Ascii字符则会被转义。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@AsciiJSONRender将结构体指针以JSON格式序列化并且写入响应的Body中,Content-Type固定为application/json; charset=utf-8gin文档-AsciiJSON

@XMLRender

XML渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@XMLRender将结构体指针以XML格式序列化并且写入响应的Body中,Content-Type固定为application/xml; charset=utf-8。参考gin文档-XMLRender

@YAMLRender

YAML渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@YAMLRender将结构体指针以YAML格式序列化并且写入响应的Body中,Content-Type固定为application/x-yaml; charset=utf-8。参考gin文档-YAMLRender

@ProtoBufRender

ProtoBuf渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@ProtoBufRender将结构体指针以Protocol Buffer格式序列化并且写入响应的Body中,Content-Type固定为application/x-protobuf。参考gin文档-ProtoBufRender

@MsgPackRender

MsgPack渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@MsgPackRender将结构体指针以MsgPack格式序列化并且写入响应的Body中,Content-Type固定为application/msgpack; charset=utf-8

@TOMLRender

TOML渲染。

只有当方法的第一个返回参数类型为结构体指针时才能使用,@TOMLRender将结构体指针以TOML格式序列化并且写入响应的Body中,Content-Type固定为application/toml。参考gin文档-TOMLRender

@CustomRender

预定义的Render策略不能满足需求,需要使用自定义Render策略,响应结构体需要实现gors.Render接口。

Validate

除了gin框架支持的参数校验方案外,gors也提供了另外一种参数校验方式,方法的第一个返回参数类型为结构体指针,并且实现了Validator接口,则在数据绑定后,会对数据进行校验。

Validator接口

type Validator interface {
	Validate() error
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendRichRoutes added in v1.1.1

func AppendRichRoutes[R gin.IRoutes](iRoutes R, routes ...RichRoute) R

AppendRichRoutes 追加富路由

func AppendRoutes added in v1.1.1

func AppendRoutes[R gin.IRoutes](iRoutes R, routes ...Route) R

AppendRoutes 追加基础路由

func FromContext

func FromContext(ctx context.Context) *gin.Context

FromContext 从context获取gin.Contenxt

func HttpStatusCode added in v1.2.0

func HttpStatusCode(c *gin.Context, resp any) int

func NewContext

func NewContext(c *gin.Context) context.Context

NewContext 向context注入gin.Context

func Validate

func Validate(req interface{}) error

Types

type Binding added in v1.2.0

type Binding interface {
	Bind(c *gin.Context) error
}

Binding 如果请求参数struct实现Binding接口,框架会用自定义绑定逻辑来绑定请求参数

type HttpError

type HttpError struct {
	// contains filtered or unexported fields
}

HttpError 指定http状态码和错误信息

func NewHttpError

func NewHttpError(statusCode int, err error) *HttpError

NewHttpError 创建Http错误

func (*HttpError) Error

func (e *HttpError) Error() string

func (*HttpError) StatusCode

func (e *HttpError) StatusCode() int

type HttpStatusCoder added in v1.2.0

type HttpStatusCoder interface {
	StatusCode(c *gin.Context) int
}

HttpStatusCoder 如果响应参数struct实现HttpStatusCoder接口,框架会用自定义状态码,默认都是 http.StatusOK

type Render added in v1.2.0

type Render interface {
	Render(c *gin.Context) error
}

Render 如果响应参数struct实现Render接口,框架会用自定义渲染逻辑来渲染响应参数

type RichRoute added in v1.1.1

type RichRoute interface {
	Method() string
	Path() string
	Handlers() []gin.HandlerFunc
}

RichRoute 富路由,在 Route 基础上,为路由增加了中间件功能。

func NewRichRoute added in v1.1.1

func NewRichRoute(route Route, middlewares ...gin.HandlerFunc) RichRoute

NewRichRoute 创建一个富路由

func NewRichRoutes added in v1.2.0

func NewRichRoutes(routes []Route, middlewares ...gin.HandlerFunc) []RichRoute

NewRichRoutes 创建一个多个富路由

type Route

type Route interface {
	Method() string
	Path() string
	Handler() gin.HandlerFunc
}

Route 基础路由,定义一个接口路由,包括method、path和处理器

func NewRoute

func NewRoute(method string, path string, handler gin.HandlerFunc) Route

NewRoute 创建一个路由

type Validator

type Validator interface {
	Validate() error
}

Validator 如果请求参数struct实现Validator接口,框架会验证数据

Directories

Path Synopsis
cmd
example
cmd
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL