Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add description to request and response and version to the API. #27

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 39 additions & 12 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
)

type APIOpts func(*API)
type RouteOpts func(*Route)

// WithApplyCustomSchemaToType enables customisation of types in the OpenAPI specification.
// Apply customisation to a specific type by checking the t parameter.
Expand Down Expand Up @@ -121,6 +122,8 @@ type Pattern string
type API struct {
// Name of the API.
Name string
// Version of the API.
Version string
// Routes of the API.
// From patterns, to methods, to route.
Routes map[Pattern]MethodToRoute
Expand Down Expand Up @@ -161,7 +164,7 @@ func (api *API) Merge(r Route) {
toUpdate := api.Route(string(r.Method), string(r.Pattern))
mergeMap(toUpdate.Params.Path, r.Params.Path)
mergeMap(toUpdate.Params.Query, r.Params.Query)
if toUpdate.Models.Request.Type == nil {
if toUpdate.Models.Request.Content.Type == nil {
toUpdate.Models.Request = r.Models.Request
}
mergeMap(toUpdate.Models.Responses, r.Models.Responses)
Expand All @@ -176,6 +179,12 @@ func mergeMap[TKey comparable, TValue any](into, from map[TKey]TValue) {
}
}

// WithVersion sets the API version
func (api *API) WithVersion(version string) *API {
api.Version = version
return api
}

// Spec creates an OpenAPI 3.0 specification document for the API.
func (api *API) Spec() (spec *openapi3.T, err error) {
spec, err = api.createOpenAPI()
Expand All @@ -198,7 +207,7 @@ func (api *API) Route(method, pattern string) (r *Route) {
Method: Method(method),
Pattern: Pattern(pattern),
Models: Models{
Responses: make(map[int]Model),
Responses: make(map[int]Response),
},
Params: Params{
Path: make(map[string]PathParam),
Expand Down Expand Up @@ -259,17 +268,25 @@ func (api *API) Trace(pattern string) (r *Route) {
// Example:
//
// api.Get("/user").HasResponseModel(http.StatusOK, rest.ModelOf[User]())
func (rm *Route) HasResponseModel(status int, response Model) *Route {
rm.Models.Responses[status] = response
func (rm *Route) HasResponseModel(status int, resp Model, opts ...RouteOpts) *Route {
rm.Models.Responses[status] = Response{
Content: resp,
}
for _, o := range opts {
o(rm)
}
return rm
}

// HasResponseModel configures the request model of the route.
// Example:
//
// api.Post("/user").HasRequestModel(http.StatusOK, rest.ModelOf[User]())
func (rm *Route) HasRequestModel(request Model) *Route {
rm.Models.Request = request
// HasRequestModel configures the request model of the route.
// Example: api.Post("/user").HasRequestModel(http.StatusOK, rest.ModelOf[User]())
func (rm *Route) HasRequestModel(request Model, opts ...RouteOpts) *Route {
rm.Models.Request = Request{
Content: request,
}
for _, o := range opts {
o(rm)
}
return rm
}

Expand Down Expand Up @@ -303,10 +320,20 @@ func (rm *Route) HasDescription(description string) *Route {
return rm
}

type Request struct {
Description string
Content Model
}

type Response struct {
Description string
Content Model
}

// Models defines the models used by a route.
type Models struct {
Request Model
Responses map[int]Model
Request Request
Responses map[int]Response
}

// ModelOf creates a model of type T.
Expand Down
5 changes: 3 additions & 2 deletions chiadapter/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"net/http"
"testing"

"github.com/a-h/rest"
"github.com/a-h/rest/chiadapter"
"github.com/go-chi/chi/v5"
"github.com/google/go-cmp/cmp"

"github.com/a-h/rest"
"github.com/a-h/rest/chiadapter"
)

func TestMerge(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions examples/chiexample/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ require (
require (
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/invopop/yaml v0.3.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/tools v0.20.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions examples/chiexample/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand All @@ -38,6 +39,7 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
Expand Down
13 changes: 10 additions & 3 deletions examples/chiexample/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import (
"net/http"

"github.com/a-h/respond"
"github.com/getkin/kin-openapi/openapi3"
"github.com/go-chi/chi/v5"

"github.com/a-h/rest"
"github.com/a-h/rest/chiadapter"
"github.com/a-h/rest/examples/chiexample/models"
"github.com/a-h/rest/swaggerui"
"github.com/getkin/kin-openapi/openapi3"
"github.com/go-chi/chi/v5"
)

func main() {
Expand Down Expand Up @@ -55,7 +56,10 @@ func main() {

// Create the routes and parameters of the Router in the REST API definition with an
// adapter, or do it manually.
chiadapter.Merge(api, router)
err := chiadapter.Merge(api, router)
if err != nil {
log.Fatalf("failed to create routes: %v", err)
}

// Because this example is all in the main package, we can strip the `main_` namespace from
// the types.
Expand All @@ -66,6 +70,9 @@ func main() {
status := s.Properties["statusCode"]
status.Value.WithMin(100).WithMax(600)
})
if err != nil {
log.Fatalf("failed to register model: %v", err)
}

// Document the routes.
api.Get("/topic/{id}").
Expand Down
4 changes: 2 additions & 2 deletions examples/offline/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ require (
require (
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/invopop/yaml v0.3.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/tools v0.20.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions examples/offline/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand All @@ -36,6 +37,7 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
Expand Down
3 changes: 2 additions & 1 deletion examples/offline/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
"os"

"github.com/a-h/respond"
"github.com/getkin/kin-openapi/openapi3"

"github.com/a-h/rest"
"github.com/a-h/rest/examples/offline/models"
"github.com/getkin/kin-openapi/openapi3"
)

func main() {
Expand Down
4 changes: 2 additions & 2 deletions examples/stdlib/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ require (
require (
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/invopop/yaml v0.3.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/tools v0.20.0 // indirect
Expand Down
9 changes: 4 additions & 5 deletions examples/stdlib/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
Expand All @@ -34,8 +34,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8=
golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc=
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
Expand All @@ -47,6 +47,5 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3 changes: 2 additions & 1 deletion examples/stdlib/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"net/http"

"github.com/a-h/respond"
"github.com/getkin/kin-openapi/openapi3"

"github.com/a-h/rest"
"github.com/a-h/rest/examples/stdlib/handlers/topic/post"
"github.com/a-h/rest/examples/stdlib/handlers/topics/get"
"github.com/a-h/rest/swaggerui"
"github.com/getkin/kin-openapi/openapi3"
)

func main() {
Expand Down
10 changes: 6 additions & 4 deletions examples/stdlib/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package models

// Topic of a thread.
type Topic struct {
Namespace string `json:"namespace"`
Topic string `json:"topic"`
Private bool `json:"private"`
ViewCount int64 `json:"viewCount"`
Namespace string `json:"namespace" validate:"required"`
Topic string `json:"topic" validate:"omitempty,oneof=general politics health"`
Private bool `json:"private"`
ViewCount int64 `json:"viewCount"`
Roles []string `json:"roles" validate:"gt=0,dive,oneof=admin user staff"`
CreatedAt string `json:"createdAt" validate:"datetime=2006-01-02T15:04:05Z07:00"`
}
Loading