Chioas is an add-on for the popular Chi router
pronounce Chioas however you like...
but I can't help feeling that it looks a little like "chaos" - the chaos of undocumented APIs that it tries to solve!
Chioas does three things:
- Defines your API as a single (or modular) struct and then builds the Chi routes accordingly
- Produces an OpenApi spec (OAS) of that definition
- Optionally serves an interactive API docs web-page (as part of your service)
With your actual API and OpenAPI spec (OAS) being specified in one place there's no chance of them becoming out of sync! (eliminating having to manually update spec yaml/json to match API or vice versa)
You can even keep your request/response OAS schemas in sync with your request/response structs!
See petstore example
No problem, use chioas.FromJson() or chioas.FromYaml() to read the spec definition.
All you'll need to do is add x-handler tags to each method in the spec.
See From example
You can also unmarshal OAS YAML/JSON directly into a Chioas Definition (but this won't bind handlers)
Chioas supports three different styles of API docs UI:
- Rapidoc (see rapidoc)
- Swagger (see swagger-ui)
- Redoc (see Redocly.redoc and Redoc-try)
Set the desired style using DocOptions.UIStyle (the default is Redoc).
Notes:
- statics for
Swaggerare all served directly from Chioas - statics for
Rapidocare all served directly from Chioas - statics for
Redocare served from CDNs
Chioas also supports serving multiple styles of UI on different docs paths (see DocOptions.AlternateUIDocs and example)
Chioas comes with many bonus features that help in building complete APIs and specs...
- Highly extensible - e.g. if there are parts of the OAS spec that are not directly supported by Chioas, then they can be added using the
Additionalfield on each part - Optionally check that OAS refs (
$ref) are valid (seeDocOptions.CheckRefs) - Optional typed handlers - see typed README
- Optional automatically added
HEADmethods forGETmethods (seeDefinition.AutoHeadMethods) - Optional automatically added
OPTIONSmethods - withAllowheader populated with actual allowed methods (seeDefinition.AutoOptionsMethodsandPath.AutoOptionsMethod) - Optional automatically added Chi
MethodNotAllowedhandler to each path - withAllowheader populated with actual allowed methods (seeDefinition.AutoMethodNotAllowed) - Ref checking (useful for checking existing oas yaml/json)
- Code generation utilities (definitions & http handler stub funcs)
- CLI for code generation
Use get:
go get github.com/go-andiamo/chioas
Get to update to the latest version:
go get -u github.com/go-andiamo/chioas
Install for CLI:
go install github.com/go-andiamo/chioas/cmd/chioas@latest
see CLI docs
package main
import (
"github.com/go-andiamo/chioas"
"github.com/go-chi/chi/v5"
"net/http"
)
func main() {
router := chi.NewRouter()
if err := myApi.SetupRoutes(router, myApi); err != nil {
panic(err)
}
_ = http.ListenAndServe(":8080", router)
}
var myApi = chioas.Definition{
AutoHeadMethods: true,
DocOptions: chioas.DocOptions{
ServeDocs: true,
HideHeadMethods: true,
},
Paths: chioas.Paths{
"/foos": {
Methods: chioas.Methods{
http.MethodGet: {
Handler: getFoos,
Responses: chioas.Responses{
http.StatusOK: {
Description: "List of foos",
IsArray: true,
SchemaRef: "foo",
},
},
},
http.MethodPost: {
Handler: postFoos,
Request: &chioas.Request{
Description: "Foo to create",
SchemaRef: "foo",
},
Responses: chioas.Responses{
http.StatusCreated: {
Description: "New foo",
SchemaRef: "foo",
},
},
},
http.MethodHead: {
Handler: getFoos,
},
},
Paths: chioas.Paths{
"/{fooId}": {
Methods: chioas.Methods{
http.MethodGet: {
Handler: getFoo,
Responses: chioas.Responses{
http.StatusOK: {
Description: "The foo",
SchemaRef: "foo",
},
},
},
http.MethodDelete: {
Handler: deleteFoo,
},
},
},
},
},
},
Components: &chioas.Components{
Schemas: chioas.Schemas{
{
Name: "foo",
RequiredProperties: []string{"name", "address"},
Properties: chioas.Properties{
{
Name: "name",
Type: "string",
},
{
Name: "address",
Type: "string",
},
},
},
},
},
}
func getFoos(writer http.ResponseWriter, request *http.Request) {
}
func postFoos(writer http.ResponseWriter, request *http.Request) {
}
func getFoo(writer http.ResponseWriter, request *http.Request) {
}
func deleteFoo(writer http.ResponseWriter, request *http.Request) {
}Run and then check out http://localhost:8080/docs !
Or simply generate the OpenAPI spec...
package main
import (
"net/http"
"github.com/go-andiamo/chioas"
)
func main() {
data, _ := myApi.AsYaml()
println(string(data))
}
var myApi = chioas.Definition{
AutoHeadMethods: true,
DocOptions: chioas.DocOptions{
ServeDocs: true,
HideHeadMethods: true,
},
Paths: chioas.Paths{
"/foos": {
Methods: chioas.Methods{
http.MethodGet: {
Handler: getFoos,
Responses: chioas.Responses{
http.StatusOK: {
Description: "List of foos",
IsArray: true,
SchemaRef: "foo",
},
},
},
http.MethodPost: {
Handler: postFoos,
Request: &chioas.Request{
Description: "Foo to create",
SchemaRef: "foo",
},
Responses: chioas.Responses{
http.StatusCreated: {
Description: "New foo",
SchemaRef: "foo",
},
},
},
http.MethodHead: {
Handler: getFoos,
},
},
Paths: chioas.Paths{
"/{fooId}": {
Methods: chioas.Methods{
http.MethodGet: {
Handler: getFoo,
Responses: chioas.Responses{
http.StatusOK: {
Description: "The foo",
SchemaRef: "foo",
},
},
},
http.MethodDelete: {
Handler: deleteFoo,
},
},
},
},
},
},
Components: &chioas.Components{
Schemas: chioas.Schemas{
{
Name: "foo",
RequiredProperties: []string{"name", "address"},
Properties: chioas.Properties{
{
Name: "name",
Type: "string",
},
{
Name: "address",
Type: "string",
},
},
},
},
},
}
func getFoos(writer http.ResponseWriter, request *http.Request) {
}
func postFoos(writer http.ResponseWriter, request *http.Request) {
}
func getFoo(writer http.ResponseWriter, request *http.Request) {
}
func deleteFoo(writer http.ResponseWriter, request *http.Request) {
}