Skip to content

Commit

Permalink
Use deepObject serialization for objects in query (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Oct 26, 2020
1 parent 920dec6 commit 3538975
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 7 deletions.
21 changes: 21 additions & 0 deletions _examples/advanced/_testdata/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,23 @@
}
}
},
"/query-object":{
"get":{
"summary":"Request With Object As Query Parameter","description":"","operationId":"",
"parameters":[
{
"name":"in_query","in":"query","description":"Object value in query.","style":"deepObject","explode":true,
"schema":{"type":"object","additionalProperties":{"type":"number"},"description":"Object value in query."}
}
],
"responses":{
"200":{
"description":"OK",
"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdvancedOutputQueryObject"}}}
}
}
}
},
"/req-resp-mapping":{
"post":{
"summary":"Request Response Mapping",
Expand Down Expand Up @@ -315,6 +332,10 @@
"required":["data"],"type":"object",
"properties":{"data":{"type":"object","properties":{"value":{"maxLength":7,"type":"string"}}}}
},
"AdvancedOutputQueryObject":{
"type":"object",
"properties":{"inQuery":{"type":"object","additionalProperties":{"type":"number"},"nullable":true}}
},
"AdvancedOutputWithJSON":{
"type":"object",
"properties":{
Expand Down
42 changes: 42 additions & 0 deletions _examples/advanced/query_object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"context"

"github.com/swaggest/usecase"
)

func queryObject() usecase.Interactor {
u := struct {
usecase.Interactor
usecase.Info
usecase.WithInput
usecase.WithOutput
}{}

u.SetTitle("Request With Object As Query Parameter")

type inputQueryObject struct {
Query map[int]float64 `query:"in_query" description:"Object value in query."`
}

type outputQueryObject struct {
Query map[int]float64 `json:"inQuery"`
}

u.Input = new(inputQueryObject)
u.Output = new(outputQueryObject)

u.Interactor = usecase.Interact(func(ctx context.Context, input, output interface{}) (err error) {
var (
in = input.(*inputQueryObject)
out = output.(*outputQueryObject)
)

out.Query = in.Query

return nil
})

return u
}
2 changes: 2 additions & 0 deletions _examples/advanced/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func NewRouter() http.Handler {
return nil
})

r.Method(http.MethodGet, "/query-object", nethttp.NewHandler(queryObject()))

r.Method(http.MethodPost, "/file-upload", nethttp.NewHandler(fileUploader()))
r.Method(http.MethodPost, "/json-body/{in-path}", nethttp.NewHandler(jsonBody()))
r.Method(http.MethodPost, "/json-body-validation/{in-path}", nethttp.NewHandler(jsonBodyValidation()))
Expand Down
4 changes: 2 additions & 2 deletions _examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ require (
github.com/stretchr/testify v1.6.1
github.com/swaggest/assertjson v1.3.0
github.com/swaggest/jsonschema-go v0.3.11
github.com/swaggest/openapi-go v0.2.1
github.com/swaggest/rest v0.0.0-20201021182107-c25bd05be4b6
github.com/swaggest/openapi-go v0.2.2
github.com/swaggest/rest v0.0.0-20201021182948-25d31f7f38d4
github.com/swaggest/swgui v1.0.9
github.com/swaggest/usecase v0.0.0-20200928062416-27f47131b0f8
github.com/valyala/fasthttp v1.16.0
Expand Down
4 changes: 2 additions & 2 deletions _examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ github.com/swaggest/jsonschema-go v0.3.8/go.mod h1:AQijowS82ZcUId9RStqvyGTxyhzYU
github.com/swaggest/jsonschema-go v0.3.11 h1:rbYBJhAV2Uz1PB4iJyKbvzGO+o1FsdX60aLi+o67IHU=
github.com/swaggest/jsonschema-go v0.3.11/go.mod h1:lJUbAc2E3OpGrrUGvayONeRBXsFJeedWTpm23jhOtKs=
github.com/swaggest/openapi-go v0.1.3/go.mod h1:Zx4ZgJ7XvlFH9wCOHE7u8RAjLfiHAnCHeaD5kUDujVM=
github.com/swaggest/openapi-go v0.2.1 h1:dZaR+vzBm34r/9706lbO7oqLWzD2SFP87qrjh9SPtlE=
github.com/swaggest/openapi-go v0.2.1/go.mod h1:GyvI08XD7gnTZxFteI2/Rnk6hgmcSufqG8wVBz/yzqo=
github.com/swaggest/openapi-go v0.2.2 h1:ZV6tjpR/W97sIOknkaOAt/U2FpqoEptRZrYiksfNKkY=
github.com/swaggest/openapi-go v0.2.2/go.mod h1:GyvI08XD7gnTZxFteI2/Rnk6hgmcSufqG8wVBz/yzqo=
github.com/swaggest/refl v0.1.0/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
github.com/swaggest/refl v0.1.2/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
github.com/swaggest/refl v0.1.3 h1:cnzEBcCNhYeLPG8Yy9JQixUkxMDsF0mo0GyzblLWrjE=
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/swaggest/assertjson v1.3.0
github.com/swaggest/form v3.6.4+incompatible
github.com/swaggest/jsonschema-go v0.3.11 // indirect
github.com/swaggest/openapi-go v0.2.1
github.com/swaggest/openapi-go v0.2.2
github.com/swaggest/refl v0.1.5
github.com/swaggest/usecase v0.0.0-20200928062416-27f47131b0f8
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ github.com/swaggest/jsonschema-go v0.3.8/go.mod h1:AQijowS82ZcUId9RStqvyGTxyhzYU
github.com/swaggest/jsonschema-go v0.3.11 h1:rbYBJhAV2Uz1PB4iJyKbvzGO+o1FsdX60aLi+o67IHU=
github.com/swaggest/jsonschema-go v0.3.11/go.mod h1:lJUbAc2E3OpGrrUGvayONeRBXsFJeedWTpm23jhOtKs=
github.com/swaggest/openapi-go v0.1.3/go.mod h1:Zx4ZgJ7XvlFH9wCOHE7u8RAjLfiHAnCHeaD5kUDujVM=
github.com/swaggest/openapi-go v0.2.1 h1:dZaR+vzBm34r/9706lbO7oqLWzD2SFP87qrjh9SPtlE=
github.com/swaggest/openapi-go v0.2.1/go.mod h1:GyvI08XD7gnTZxFteI2/Rnk6hgmcSufqG8wVBz/yzqo=
github.com/swaggest/openapi-go v0.2.2 h1:ZV6tjpR/W97sIOknkaOAt/U2FpqoEptRZrYiksfNKkY=
github.com/swaggest/openapi-go v0.2.2/go.mod h1:GyvI08XD7gnTZxFteI2/Rnk6hgmcSufqG8wVBz/yzqo=
github.com/swaggest/refl v0.1.0/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
github.com/swaggest/refl v0.1.2/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
github.com/swaggest/refl v0.1.3 h1:cnzEBcCNhYeLPG8Yy9JQixUkxMDsF0mo0GyzblLWrjE=
Expand Down
7 changes: 7 additions & 0 deletions nethttp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ func SuccessfulResponseContentType(contentType string) func(h *Handler) {
}
}

// SuccessStatus sets status code of successful response.
func SuccessStatus(status int) func(h *Handler) {
return func(h *Handler) {
h.SuccessStatus = status
}
}

// RequestMapping creates rest.RequestMapping from struct tags.
//
// This can be used to decouple mapping from usecase input with additional struct.
Expand Down
26 changes: 26 additions & 0 deletions request/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,29 @@ func TestDecoder_Decode_json(t *testing.T) {
assert.Error(t, err)
assert.Equal(t, rest.ValidationErrors{"body": []string{"#/bodyTwo: minimum 2 items allowed, but found 1 items"}}, err)
}

func TestDecoder_Decode_queryObject(t *testing.T) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet,
"/?in_query[1]=1.0&in_query[2]=2.1&in_query[3]=0", nil)
assert.NoError(t, err)

df := request.NewDecoderFactory()

input := new(struct {
InQuery map[int]float64 `query:"in_query"`
})
dec := df.MakeDecoder(http.MethodGet, input, nil)

assert.NoError(t, dec.Decode(req, input, nil))
assert.Equal(t, map[int]float64{1: 1, 2: 2.1, 3: 0}, input.InQuery)

req, err = http.NewRequestWithContext(context.Background(), http.MethodGet,
"/?in_query[1]=1.0&in_query[2]=2.1&in_query[c]=0", nil)
assert.NoError(t, err)

err = dec.Decode(req, input, nil)
assert.Error(t, err)
assert.Equal(t, rest.RequestErrors{"query:in_query": []string{
"#: Invalid Integer Value 'c' Type 'int' Namespace 'in_query'",
}}, err)
}

0 comments on commit 3538975

Please sign in to comment.