kapi

package module
v0.6.2 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2024 License: MIT Imports: 25 Imported by: 1

README

KAPI

description

base on gin, support comments like //@METHOD, generate swagger doc automatically

the final target: make you write http api server quickly.

PS: not stable now, use it in caution

feature

  1. mark and register route with comments
  2. write codes just like Asp .Net Core's Controller
  3. Dependency Inject using https://github.com/linxlib/inject
  4. less comments to generate swagger doc
  5. a built-in modified swagger ui(api path can be copied one-click) now use the latest version of Swagger UI

golang version

golang > 1.18

quick start

go install github.com/linxlib/kapi/cmd/k@latest
mkdir kapi_example && cd kapi_example
k init kapi_example
k run

comments support

use it like //@XXX parameter...

comment location description default optional comment optional
@TAG Struct the tag of swagger 注释
@AUTH Struct HTTP Header name for authorization Authorization
@ROUTE Struct route prefix of api None
@HTTPMETHOD Method http method
@RESP Method specify the model of result body

sample

// @GET /test
func (e *Example) TestPure(c *kapi.Context) {
	a, _ := c.Get("123456")
	c.SuccessExit(a)
}

can be

// @GET /test
func (e *Example) TestPure(c *kapi.Context,req *MyRequest) {
	a, _ := c.Get("123456")
	c.SuccessExit(a)
}

kapi will analysis MyRequest,and show it in swagger

type MyRequest struct {
  Page int `query:"page,default=1"` // you can set a default value for a parameter. only take effect in swagger
	Size int `query:"size,default=15"` // this parameter will be bind from query
  MyHeader string `header:"MyHeader"`
  MyBodyParam1 string `json:"myBodyParam1"`
  MyBodyParam2 int `json:"myBodyParam2"`
  MyPathParam int `path:"id" binding:"required"` //this parameter is required
  MyFormParam string `form:"myForm"` 
}

also

type Form struct {
	FileHeader multipart.FileHeader `form:"file"` //you will see a file upload component in swagger ui
}

use @RESP mark response body's Model, the second way of writing belows are also ok

type MyResult struct {
	Name string `json:"name"`
}

// @GET /test
// @RESP MyResult
func (e *Example) TestPure(c *kapi.Context) {
	a, _ := c.Get("123456")
	c.SuccessExit(a)
}

// @GET /TestResult
func (e *Example) TestResult(c *kapi.Context) (*MyResult, error) {
	return nil, nil
}

request model can inherit from another struct
type PageSize struct {
    Page int `query:"page,default=1"`
    Size int `query:"size,default=15"`
}

func (p *PageSize) GetLimit() (int, int) {
    return p.Size, (p.Page - 1) * p.Size
}
type GetBannerListReq struct {
	PageSize
}
register multiple HTTPMETHOD on the same time

the route should be different

// @POST /testResult
// @GET /TestResult
func (e *Example) TestResult(c *kapi.Context) (*MyResult, error) {
	return nil, nil
}

belows are not suggested

// @POST /TestResult
// @GET /TestResult
func (e *Example) TestResult(c *kapi.Context) (*MyResult, error) {
	return nil, nil
}

Dependency Inject

register your service before RegisterRouter, you should handle dependency order by yourself

k.Map(config.AppConfig)
s3Svc := storage.NewS3Service()
k.MapTo(s3Svc, (*storage.IStorage)(nil))

k.RegisterRouter(...)

use it in Controller

type MainController struct {
	CC    *config.Config   `inject:""`
	Store storage.IStorage `inject:""`
}

you can also use inject.Default() to register a service globally

AA := new(config.Config)
err := inject.Default().Provide(AA)

Controller Method can supported DI

type MyService interface {
	Test() string
}
type MyServiceImpl struct {
}

func (m *MyServiceImpl) Test() string {
	return "MyServiceImpl"
}

// GetList 获取列表
// @GET /list
func (e *Example) GetList(
	c *kapi.Context,
	req *MyReq,
	svc MyService, //here
) {
	fmt.Println(req.Page, req.Size)
	fmt.Println(svc.Test())
	fmt.Println(e.CustomData)
	c.Success()
}

customize the result model

kapi.Context has some method for easy return data, eg. c.ListExit(count, list) will return like

{
  "code":"SUCCESS",
  "count": count,
  "data":[{},{}]
}

implement kapi.IResultBuilder to customize it.

type MyResultBuilder struct {
	kapi.DefaultResultBuilder
}

type myMessageBody struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data any    `json:"data"`
}

func (m MyResultBuilder) OnSuccess(msg string, data any) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 200,
		Msg:  msg,
		Data: data,
	}
}

func (m MyResultBuilder) OnData(msg string, count int64, data any) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 200,
		Msg:  msg,
		Data: data,
	}
}

func (m MyResultBuilder) OnFail(msg string, data any) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 400,
		Msg:  msg,
		Data: data,
	}
}

func (m MyResultBuilder) OnError(msg string, err error) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 500,
		Msg:  msg,
		Data: err,
	}
}

func (m MyResultBuilder) OnErrorDetail(msg string, err any) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 500,
		Msg:  msg,
		Data: err,
	}
}

func (m MyResultBuilder) OnUnAuthed(msg string) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 401,
		Msg:  msg,
		Data: nil,
	}
}

func (m MyResultBuilder) OnNoPermission(msg string) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 403,
		Msg:  msg,
		Data: nil,
	}
}

func (m MyResultBuilder) OnNotFound(msg string) (statusCode int, result any) {
	return 200, myMessageBody{
		Code: 404,
		Msg:  msg,
		Data: nil,
	}
}

just register it

k.RegisterResultBuilder(new(MyResultBuilder))

pprof

import "github.com/gin-contrib/pprof"

pprof.Register(k.GetEngine(), "/pprof")

deploy

The "k" cli tool provides release feature, see "k" section below.

TODOList

see README_CN.md for details.

Thanks

the initial version is from https://github.com/xxjwxc/ginrpc

k

Description

a cli tool for KAPI.

Features
  1. initialize project struct
  2. run project and restart project on file changed
  3. build project
  4. generate some codes
Installation
go install github.com/linxlib/kapi/cmd/k@latest
Usage
k -h 
k add -h
k build -h
k init -h
k run -h

JetBrains Logo (Main) logo

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	VERSION     string
	BUILDTIME   string
	GOVERSION   string
	BUILDOS     string
	BUILDARCH   string
	OS          string
	ARCH        string
	PACKAGENAME string
)

编译时植入变量

View Source
var KAPIEXIT = "kapiexit"

Functions

This section is empty.

Types

type AfterBind

type AfterBind interface {
	AfterBind(c *Context)
}

type AfterCall

type AfterCall interface {
	AfterCall(c *Context)
}

type BeforeBind

type BeforeBind interface {
	BeforeBind(c *Context)
}

type BeforeCall

type BeforeCall interface {
	BeforeCall(c *Context)
}

type Context

type Context struct {
	*gin.Context

	ResultBuilder IResultBuilder `inject:""`
	// contains filtered or unexported fields
}

Context KApi Context

func (*Context) Apply

func (c *Context) Apply(ctl interface{}) error

Apply 为一个结构注入带inject标签的Field

@param ctl 需要为指针

@return error

func (*Context) DataExit

func (c *Context) DataExit(data interface{})

func (*Context) Exit

func (c *Context) Exit()

func (*Context) FailAndExit

func (c *Context) FailAndExit(data ...interface{})

func (*Context) File added in v0.6.0

func (c *Context) File(fileName string, fileData []byte)

File returns a file

@param fileName
@param fileData

func (*Context) GetFormFloat32

func (c *Context) GetFormFloat32(key string, def ...float32) float32

GetFormFloat32 return the float32 value of query param

@param key
@param def

@return string

func (*Context) GetFormFloat64

func (c *Context) GetFormFloat64(key string, def ...float64) float64

GetFormFloat64 return the float64 value of form param

@param key
@param def

@return string

func (*Context) GetFormInt

func (c *Context) GetFormInt(key string, def ...int) int

GetFormInt return the int value of form param

@param key

@return string

func (*Context) GetFormInt64

func (c *Context) GetFormInt64(key string, def ...int64) int64

GetFormInt64 return the int64 value of form param

@param key

@return string

func (*Context) GetFormString

func (c *Context) GetFormString(key string, def ...string) string

GetFormString return the string value of form param

@param key

@return string

func (*Context) GetFormUInt

func (c *Context) GetFormUInt(key string, def ...uint) uint

GetFormUInt return the uint value of form param

@param key

@return string

func (*Context) GetPageSize

func (c *Context) GetPageSize(def ...int) (int, int)

GetPageSize return the values of "page"-1 and "size" query params

@param def
def[0] can be the default value of "page" param and def[1] can be the default value of "size" param

@return int page-1
@return int size

func (*Context) GetQueryBool

func (c *Context) GetQueryBool(key string) bool

GetQueryBool return the boolean value of query param

@param key

@return bool

func (*Context) GetQueryInt

func (c *Context) GetQueryInt(key string, def ...int) int

GetQueryInt return the int value of query param

@param key
@param def

@return int

func (*Context) GetQueryInt64

func (c *Context) GetQueryInt64(key string, def ...int64) int64

GetQueryInt64 return the int64 value of query param

@param key
@param def

@return int64

func (*Context) GetQueryString

func (c *Context) GetQueryString(key string, def ...string) string

GetQueryString return the string value of query param

@param key

@return string

func (*Context) GetQueryUInt

func (c *Context) GetQueryUInt(key string, def ...uint) uint

GetQueryUInt return the uint value of query param

@param key
@param def

@return uint

func (*Context) GetQueryUInt64

func (c *Context) GetQueryUInt64(key string, def ...uint64) uint64

GetQueryUInt64 return the uint64 value of query param

@param key
@param def

@return uint64

func (*Context) ListExit

func (c *Context) ListExit(count int64, list interface{})

func (*Context) Map

func (c *Context) Map(i ...interface{}) inject.TypeMapper

Map an instance

@param i

@return inject.TypeMapper

func (*Context) MapTo

func (c *Context) MapTo(i interface{}, j interface{}) inject.TypeMapper

MapTo map instance to interface

@param i 要注入的值(指针)
@param j 接口类型(指针)

@return inject.TypeMapper

func (*Context) MessageAndDataExit

func (c *Context) MessageAndDataExit(message string, data interface{})

func (*Context) Method

func (c *Context) Method() string

Method return HTTP method

@return string

func (*Context) NoPerm

func (c *Context) NoPerm(msg ...string)

func (*Context) NoPermissionExit

func (c *Context) NoPermissionExit(msg ...string)

func (*Context) NotFoundExit

func (c *Context) NotFoundExit(msg ...string)

func (*Context) OfFormFile

func (c *Context) OfFormFile(form string) (string, int64)

OfFormFile 获取Form File的文件名和大小

@param form

@return string
@return int64

func (*Context) Provide

func (c *Context) Provide(i interface{}) error

Provide 提供已注入的实例

@param i 需要为指针

@return error

func (*Context) RemoteAddr

func (c *Context) RemoteAddr() string

RemoteAddr returns more real IP address.

func (*Context) SaveFile

func (c *Context) SaveFile(form string, dst string) error

SaveFile save form file to destination

@param form name of form file
@param dst destination file name

@return error

func (*Context) Success

func (c *Context) Success(data ...interface{})

func (*Context) SuccessExit

func (c *Context) SuccessExit(data ...interface{})

func (*Context) UnAuthed

func (c *Context) UnAuthed(msg ...string)

func (*Context) WriteJSON

func (c *Context) WriteJSON(obj interface{})

WriteJSON 写入json对象

type ContextInvoker

type ContextInvoker func(ctx *Context)

ContextInvoker method like this will be FastInvoke by inject package(not use reflect)

func (ContextInvoker) Invoke

func (invoke ContextInvoker) Invoke(params []interface{}) ([]reflect.Value, error)

type DefaultResultBuilder

type DefaultResultBuilder struct {
}

func (DefaultResultBuilder) OnData

func (d DefaultResultBuilder) OnData(msg string, count int64, data any) (statusCode int, result any)

func (DefaultResultBuilder) OnError

func (d DefaultResultBuilder) OnError(msg string, err error) (statusCode int, result any)

func (DefaultResultBuilder) OnErrorDetail

func (d DefaultResultBuilder) OnErrorDetail(msg string, err any) (statusCode int, result any)

func (DefaultResultBuilder) OnFail

func (d DefaultResultBuilder) OnFail(msg string, data any) (statusCode int, result any)

func (DefaultResultBuilder) OnNoPermission

func (d DefaultResultBuilder) OnNoPermission(msg string) (statusCode int, result any)

func (DefaultResultBuilder) OnNotFound

func (d DefaultResultBuilder) OnNotFound(msg string) (statusCode int, result any)

func (DefaultResultBuilder) OnSuccess

func (d DefaultResultBuilder) OnSuccess(msg string, data any) (statusCode int, result any)

func (DefaultResultBuilder) OnUnAuthed

func (d DefaultResultBuilder) OnUnAuthed(msg string) (statusCode int, result any)

type HeaderAuth

type HeaderAuth interface {
	HeaderAuth(c *Context)
}

type IResultBuilder

type IResultBuilder interface {
	OnSuccess(msg string, data any) (statusCode int, result any)
	OnData(msg string, count int64, data any) (statusCode int, result any)
	OnFail(msg string, data any) (statusCode int, result any)
	OnError(msg string, err error) (statusCode int, result any)
	OnErrorDetail(msg string, err any) (statusCode int, result any)
	OnUnAuthed(msg string) (statusCode int, result any)
	OnNoPermission(msg string) (statusCode int, result any)
	OnNotFound(msg string) (statusCode int, result any)
}

type Interceptor

type Interceptor interface {
	Before(*Context)
	After(*Context)
}

Interceptor implement this to intercept controller method

type KApi

type KApi struct {
	inject.Injector
	// contains filtered or unexported fields
}

func New

func New(f ...func(*Option)) *KApi

New 创建新的KApi实例

@param f 配置函数

@return *KApi

func (*KApi) AddControllers added in v0.6.0

func (b *KApi) AddControllers(cList ...interface{}) bool

func (*KApi) GetEngine

func (b *KApi) GetEngine() *gin.Engine

GetEngine returns the inner gin.Engine

@return *gin.Engine

func (*KApi) RegisterResultBuilder

func (b *KApi) RegisterResultBuilder(builder IResultBuilder)

RegisterResultBuilder 注册返回body的builder处理类

@param builder 实现 IResultBuilder 接口

func (*KApi) RegisterRouter

func (b *KApi) RegisterRouter(cList ...interface{}) bool

func (*KApi) Run

func (b *KApi) Run()

Run the server

func (*KApi) Settings

func (b *KApi) Settings() *config.YAML

type OnError

type OnError interface {
	OnError(c *Context, err error)
}

type OnPanic

type OnPanic interface {
	OnPanic(c *Context, err interface{})
}

type OnUnmarshalError

type OnUnmarshalError interface {
	OnUnmarshalError(c *Context, err error)
}

type OnValidationError

type OnValidationError interface {
	OnValidationError(c *Context, err error)
}

type Option

type Option struct {
	Server ServerOption
	// contains filtered or unexported fields
}

func (*Option) Get

func (o *Option) Get() *config.YAML

func (*Option) SetGinLoggerFormatter

func (o *Option) SetGinLoggerFormatter(formatter gin.LogFormatter) *Option

func (*Option) SetIntranetIP

func (o *Option) SetIntranetIP(ip string) *Option

func (*Option) SetRecoverFunc

func (o *Option) SetRecoverFunc(f func(interface{})) *Option

type RecoverFunc added in v0.6.0

type RecoverFunc func(interface{})

RecoverFunc recover 错误设置

type ResultBuilderUnimplemented

type ResultBuilderUnimplemented struct{}

func (ResultBuilderUnimplemented) OnData

func (r ResultBuilderUnimplemented) OnData(msg string, count int64, data any) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnError

func (r ResultBuilderUnimplemented) OnError(msg string, err error) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnErrorDetail

func (r ResultBuilderUnimplemented) OnErrorDetail(msg string, err any) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnFail

func (r ResultBuilderUnimplemented) OnFail(msg string, data any) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnNoPermission

func (r ResultBuilderUnimplemented) OnNoPermission(msg string) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnNotFound

func (r ResultBuilderUnimplemented) OnNotFound(msg string) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnSuccess

func (r ResultBuilderUnimplemented) OnSuccess(msg string, data any) (statusCode int, result any)

func (ResultBuilderUnimplemented) OnUnAuthed

func (r ResultBuilderUnimplemented) OnUnAuthed(msg string) (statusCode int, result any)

type RouteInfo

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

func NewRouteInfo added in v0.6.0

func NewRouteInfo() *RouteInfo

func (*RouteInfo) AddFunc

func (ri *RouteInfo) AddFunc(handlerFuncName, routerPath string, method string)

AddFunc add one method to method comments

func (*RouteInfo) Clean added in v0.6.0

func (ri *RouteInfo) Clean()

func (*RouteInfo) GetGenInfo added in v0.6.0

func (ri *RouteInfo) GetGenInfo() *genInfo

func (*RouteInfo) GetRouteItems added in v0.6.0

func (ri *RouteInfo) GetRouteItems() map[string][]RouteItem

GetRouteItems get router info of method comments

@return map[string][]RouteItem

func (*RouteInfo) SetApiBody

func (ri *RouteInfo) SetApiBody(api *openapi.Spec)

SetApiBody store swagger json spec

@param api

func (*RouteInfo) WriteOut added in v0.6.0

func (ri *RouteInfo) WriteOut()

WriteOut write router info to gen.gob

type RouteItem added in v0.6.0

type RouteItem struct {
	Key         string //may be [controller name] + / + [method name]. unique
	RouterPath  string
	Summary     string
	Description string
	Method      string //HTTP METHOD
}

RouteItem store the comment from controller's method. fields should be exported for gob encoding and decoding

type ServerOption

type ServerOption struct {
	NeedDoc    bool        `yaml:"needDoc"`
	DocName    string      `yaml:"docName"`
	DocDesc    string      `yaml:"docDesc"`
	BasePath   string      `yaml:"basePath"`
	Port       int         `yaml:"port"`
	DocVer     string      `yaml:"docVer"`
	StaticDirs []StaticDir `yaml:"staticDirs"`
	Cors       cors.Config `yaml:"cors"`
}

type StaticDir

type StaticDir struct {
	Path string `yaml:"path"`
	Root string `yaml:"root"`
}

Directories

Path Synopsis
cmd
k Module
example module
ast_parser
Package ast_parser get type information from a package using go/ast
Package ast_parser get type information from a package using go/ast

Jump to

Keyboard shortcuts

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