Skip to content

kunlun-qilian/server-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

It is Gin!

  • provide a new function named Bind() to validate and bind values in http request,this function is more convenient than gin's function
  • print log
  • pprof
  • default swagger
  • inject env
  • generate dockerfile
  • inject traceID span
  • trace with jaeger
  • inject trace span in header

Code example

Server

func CarRouter(r *gin.RouterGroup) {
	r.GET("/car/:id", ListCar)
	r.POST("/car/:userID", CreateCar)
}

type Car struct {
	Name    string `json:"name"`
	CarType int    `json:"carType"`
}

type ListCarParam struct {
	// in path
	ID string `in:"path" name:"id"`         <-----  path 
	// in query
	Name string `in:"query" name:"name"`    <-------  query
}

// @BasePath /api/v1
// PingExample godoc
// @Summary ListCar
// @Schemes
// @Description List car
// @Tags ex
// @Accept json
// @Produce json
// @Success 200 {object}  []model.Example
// @Router /car [get]
// @ID ListCar
func ListCar(ctx *gin.Context) {

	param := ListCarParam{}
	err := confserver.Bind(ctx, &param)        <-------  Validate  params both in query and path
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, err)
		return
	}

	ex := model.Example{}

	cs := model.NewCondRules()
	where := builder.And(
		cs.When(true, ex.FieldName().Eq("bbb")),
	)
	where.Or(cs.When(true, ex.FieldCarType().Eq(123)))

	exList, err := ex.List(global.Config.DB, where)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, err)
		return
	}
	ctx.JSON(http.StatusOK, exList)
}


type CreateCarRequestBody struct {
	Name    string `json:"name"`
	CarType int    `json:"carType"`
}

type CreateCarReqeust struct {
	FF                   string `in:"query" name:"ff"`     <------  mark in query
	UserID               string `in:"path" name:"userID"`  <------  mark in path r.POST("/car/:userID", CreateCar)
	CanBeEmpty           string `in:"query" name:"canBeEmpty,omitempty"` <----- mark in query but can be ignored
	CreateCarRequestBody `in:"body"`                       <------  mark in body
}

type ErrorResp struct {
	Msg string `json:"msg"`
}

// @BasePath /api/v1
// PingExample godoc
// @Summary CreateCar
// @Schemes
// @Description Create Car
// @Tags ex
// @Accept json
// @Produce json
// @Param ReqeustBody body CreateCarReqeust true "Create Car"
// @Success 200 {object} model.Example OK
// @Success 400 {object} ErrorResp Error
// @Success 500 {object} ErrorResp Error
// @Router  /car [post]
// @ID CreateCar
func CreateCar(ctx *gin.Context) {
	req := CreateCarReqeust{}
	err := confserver.Bind(ctx, &req)      <------- Bind
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, ErrorResp{Msg: err.Error()})
		return
	}

	//
	m := model.Example{}
	m.FF = req.FF
	m.CarType = req.CarType
	m.Name = req.Name
	m.UserID = req.UserID
	m.SetNowForCreate()

	err = m.Create(global.Config.DB)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, err)
		return
	}
	ctx.JSON(http.StatusOK, nil)

}

Inject Env Value

Read the env value and overwrite the value

Env Tag

cmd/server/global/config.go

package global

import (
	"kunlun-qilian/server-example/internal/model"

	"github.com/kunlun-qilian/confmysql"
	"github.com/kunlun-qilian/confserver"
)

func init() {
	confserver.SetServiceName("example-server", "..")
	confserver.ConfP(&Config)

	confserver.AddCommand(Config.DB.Commands()...)
}

var Config = struct {
	DB     *confmysql.MySQL
	Server *confserver.Server

	TestEnvStr string `env:""`     <------   mark the env value
}{
	Server: &confserver.Server{
		Mode: "debug",
		LogOption: confserver.LogOption{
			LogLevel: "debug",
		},
	},

	DB: &confmysql.MySQL{
		Host:     "127.0.0.1",
		User:     "root",
		Port:     33306,
		DBName:   "example",
		Password: "123456",
		Database: model.DB,
	},
	TestEnvStr: "global.config",
}

Auto generate default.yml file,when started

cmd/server/config/default.yml

EXAMPLE_SERVER__DB_DBName: example
EXAMPLE_SERVER__DB_Extra: autocommit=true&charset=utf8mb4&interpolateParams=true&loc=Local&parseTime=true
EXAMPLE_SERVER__DB_Host: 127.0.0.1
EXAMPLE_SERVER__DB_Password: "123456"
EXAMPLE_SERVER__DB_PoolSize: "10"
EXAMPLE_SERVER__DB_Port: "33306"
EXAMPLE_SERVER__DB_User: root
EXAMPLE_SERVER__Server_LogFormatter: json
EXAMPLE_SERVER__Server_LogLevel: debug
EXAMPLE_SERVER__Server_Mode: debug
EXAMPLE_SERVER__TestEnvStr: global.config
GOENV: DEV

local env file

cmd/server/config/local.yml

this file will overwrite the value in default.yml, it just could be used at local machine!!! this file should be ignored in your project, put it into your .gitignore !!!!!!

EXAMPLE_SERVER__TestEnvStr: from.local.yml

ORM

Use Sqlx

klctl can generate model inerternal/model/example.go

//go:generate klctl gen model2 Example --database DB
// @def primary ID
// @def unique_index I_name_id Name
// @def index I_ff_user UserID FF      <--------  union index, this is more convenient than gorm
type Example struct {
	PrimaryID
	Name    string `db:"F_name,default='',size=100" json:"name"` // Name
	CarType int    `db:"F_car_type,default=0" json:"CarType"`
	FF      string `db:"f_FF,size=100"`
	RefUser
}

Openapi and sdk

use gin swagger swag swagger

use klctl convert swagger2.0 to openapi3.0

generate openapi3.0

make openapi

generate sdk

start the server and use "make client"

see more in makefile

PKG = $(shell cat go.mod | grep "^module " | sed -e "s/module //g")
NAME = $(shell basename $(PKG))
VERSION = v$(shell cat .version)
COMMIT_SHA ?= $(shell git rev-parse --short HEAD)

GOOS ?= $(shell go env GOOS)
GOARCH ?= $(shell go env GOARCH)
CGO_ENABLED ?= 0

GOBUILD=CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -a -ldflags "-X ${PKG}/version.Version=${VERSION}+sha.${COMMIT_SHA}"

WORKSPACE ?= name

build:
	cd ./cmd/$(WORKSPACE) && $(GOBUILD)

# swagger
swagger:
	swag init --pd -d ./cmd/server -o ./cmd/server/docs

# openapi 3.0
openapi: swagger
	cd ./cmd/server && klctl openapi  -f ./docs/swagger.json

# client
client:
	klctl gen client server  --output ./cmd/client --spec-url http://127.0.0.1/example-server


gen-web:
	npx create-react-app web --template typescript


gen-web-client:
	restful-react import --file ./cmd/server/docs/swagger.json  --output ./cmd/web/src/client-bff.ts

Tools

  1. swag
  2. swagger
  3. klctl
  4. confserver
  5. restful-react

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published