provide your service easier, focus on service not server.
- easier to use
- focus on service not server
- help standardized project params handle and response
- interface annotation code generate
- interface annotation doc generate
Get by running:
go get github.com/Just-maple/serverless-gin
function as service
package main
import (
"context"
"errors"
svrlessgin "github.com/Just-maple/serverless-gin"
"github.com/gin-gonic/gin/ginS"
)
var (
easy = svrlessgin.NewEasyController()
)
type Param struct {
A int `form:"a"`
B int `form:"b"`
}
func main() {
// raw gin
ginS.GET("add/raw", func(c *gin.Context) {
type ret struct {
Data int `json:"data"`
}
var param Param
err := c.Bind(¶m)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
c.JSON(http.StatusOK, ret{Data: param.A + param.B})
})
// easy
ginS.GET("add", easy(func(param Param) (int, error) {
return param.A + param.B, nil
}))
ginS.GET("dec", easy(func(param Param) (int, error) {
return param.A - param.B, nil
}))
ginS.GET("multi", easy(func(param Param) (int, error) {
return param.A * param.B, nil
}))
// if first param is context.Context
// fill from gin.Context.Request.Context()
ginS.GET("divide", easy(func(ctx context.Context, param Param) (float64, error) {
if param.B == 0 {
return 0, errors.New("b cannot be zero")
}
return float64(param.A) / float64(param.B), nil
}))
panic(ginS.Run(":80"))
}
there is some service interface in common
actually in ours real project service modules and interface will much more than example
and your params in and response will much more complex
if your want to provide them as api by gin
// this example provide all api routers
package main
import (
"github.com/Just-maple/serverless-gin/example/internal/common"
"github.com/gin-gonic/gin"
)
func RegisterComputeService(group gin.IRoutes, svc common.Compute) {
group.GET("/add", wrapper(svc.Add))
group.GET("/dec", wrapper(svc.Dec))
}
func RegisterAccountService(group gin.IRoutes, svc common.Account) {
group.GET("/new", wrapper(svc.NewAccount))
group.POST("/edit", wrapper(svc.EditAccountPassword))
}
func RegisterOrderService(group gin.IRoutes, svc common.Order) {
group.PUT("/new", wrapper(svc.New))
}
- the old raw way
// this example provide only one api router
package order
import (
"net/http"
"github.com/Just-maple/serverless-gin/example/internal/common"
"github.com/gin-gonic/gin"
)
func RegisterOrderService(group gin.IRoutes, svc common.Order) {
group.PUT("/new", func(c *gin.Context) {
var param common.ParamNewOrder
if err := c.Bind(¶m); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
get, _ := c.Get("user_id")
userID, ok := get.(common.UserID)
if !ok {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
ret, err := svc.New(c.Request.Context(), param, userID)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
c.JSON(http.StatusOK, ret)
})
}
per request may lost 5µs
cause it based on reflect
but you can save time (api-count - 1) * time-waist-in-api-code
in your life
just use these time to do more funny things