Inspired by swaggest/rest
- Built with echo.
- Automatic OpenAPI 3 documentation with openapi-go.
- Automatic request JSON schema validation with jsonschema-go, jsonschema.
- Embedded Swagger UI.
Go struct with field tags defines input.
// Declare input port type.
type helloInput struct {
Locale string `query:"locale" default:"en-US" pattern:"^[a-z]{2}-[A-Z]{2}$" enum:"zh-CN,en-US"`
Name string `path:"name" minLength:"3"` // Field tags define parameter location and JSON schema constraints.
_ struct{} `title:"My Struct" description:"Holds my data."`
}
Input data can be located in:
path
parameter in request URI, e.g./users/:name
,query
parameter in request URI, e.g./users?locale=en-US
,form
parameter in request body withapplication/x-www-form-urlencoded
content,formData
parameter in request body withmultipart/form-data
content,json
parameter in request body withapplication/json
content,cookie
parameter in request cookie,header
parameter in request header.
Field tags
- number
maximum
,exclusiveMaximum
,minimum
,exclusiveMinimum
,multipleOf
- string
minLength
,maxLength
,pattern
,format
- array
minItems
,maxItems
,uniqueItems
- all
title
,description
,default
,const
,enum
Additional field tags describe JSON schema constraints, please check documentation.
// Declare output port type.
type helloOutput struct {
Now time.Time `header:"X-Now" json:"-"`
Message string `json:"message"`
Sess string `cookie:"sess,httponly,secure,max-age=86400,samesite=lax"`
}
Output data can be located in:
json
for response body withapplication/json
content,header
for values in response header,cookie
for cookie values, cookie fields can have configuration in field tag (same as in actual cookie, but with comma separation).
package main
import (
"fmt"
"log"
"time"
"github.com/fourcels/rest"
"github.com/labstack/echo/v4"
)
func main() {
s := rest.NewService()
s.OpenAPI.Info.WithTitle("Basic Example")
s.GET("/hello/{name}", hello())
// Swagger UI endpoint at /docs.
s.Docs("/docs")
// Start server.
log.Println("http://localhost:1323/docs")
s.Start(":1323")
}
func hello() rest.Interactor {
// Declare input port type.
type input struct {
Name string `path:"name" minLength:"3"` // Field tags define parameter
Locale string `query:"locale" default:"en-US" pattern:"^[a-z]{2}-[A-Z]{2}$" enum:"zh-CN,en-US"`
_ struct{} `title:"My Struct" description:"Holds my data."`
}
// Declare output port type.
type output struct {
Now time.Time `header:"X-Now" json:"-"`
Message string `json:"message"`
}
messages := map[string]string{
"en-US": "Hello, %s!",
"zh-CN": "你好, %s!",
}
return rest.NewHandler(func(c echo.Context, in input, out *output) error {
msg := messages[in.Locale]
out.Now = time.Now()
out.Message = fmt.Sprintf(msg, in.Name)
return nil
})
}