Repository: swaggest/openapi-go
Pull request #17 (2020-10-26 10:33:47)

Use deepObject serialization for object in query

codecov[bot]: # [Codecov](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=h1) Report
> Merging [#17](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=desc) into [master](https://codecov.io/gh/swaggest/openapi-go/commit/1571c5f1c6b6aa421d10ab21a566b690d9da0176?el=desc) will **decrease** coverage by `0.00%`.
> The diff coverage is `50.00%`.

[![Impacted file tree graph](https://codecov.io/gh/swaggest/openapi-go/pull/17/graphs/tree.svg?width=650&height=150&src=pr&token=3uETjeijpQ)](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #17      +/-   ##
==========================================
- Coverage   37.20%   37.20%   -0.01%     
==========================================
  Files           5        5              
  Lines        3470     3473       +3     
==========================================
+ Hits         1291     1292       +1     
- Misses       1895     1896       +1     
- Partials      284      285       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| #unittests | `37.20% <50.00%> (-0.01%)` | :arrow_down: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [openapi3/reflect.go](https://codecov.io/gh/swaggest/openapi-go/pull/17/diff?src=pr&el=tree#diff-b3BlbmFwaTMvcmVmbGVjdC5nbw==) | `84.83% <50.00%> (-0.75%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=footer). Last update [1571c5f...84fda67](https://codecov.io/gh/swaggest/openapi-go/pull/17?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml
index 0b20362..cb79f56 100644
--- a/.github/workflows/golangci-lint.yml
+++ b/.github/workflows/golangci-lint.yml
@@ -5,6 +5,7 @@ on:
       - v*
     branches:
       - master
+      - main
   pull_request:
 jobs:
   golangci:
@@ -13,7 +14,7 @@ jobs:
     steps:
       - uses: actions/checkout@v2
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v2.2.0
+        uses: golangci/golangci-lint-action@v2.2.1
         with:
           # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
           version: v1.31
@@ -25,4 +26,4 @@ jobs:
           # The secret `GITHUB_TOKEN` is automatically created by GitHub,
           # no need to create it manually.
           # https://help.github.com/en/actions/configuring-and-managing-workflows/authenticating-with-the-github_token#about-the-github_token-secret
-          github-token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+          github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/README.md b/README.md
index fa8e1e1..18197a6 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@ This library provides Go structures to marshal/unmarshal and reflect [OpenAPI Sc
 [![Build Status](https://github.com/swaggest/openapi-go/workflows/test/badge.svg)](https://github.com/swaggest/openapi-go/actions?query=branch%3Amaster+workflow%3Atest)
 [![Coverage Status](https://codecov.io/gh/swaggest/openapi-go/branch/master/graph/badge.svg)](https://codecov.io/gh/swaggest/openapi-go)
 [![GoDevDoc](https://img.shields.io/badge/dev-doc-00ADD8?logo=go)](https://pkg.go.dev/github.com/swaggest/openapi-go)
+[![time tracker](https://wakatime.com/badge/github/swaggest/openapi-go.svg)](https://wakatime.com/badge/github/swaggest/openapi-go)
 ![Code lines](https://sloc.xyz/github/swaggest/openapi-go/?category=code)
 ![Comments](https://sloc.xyz/github/swaggest/openapi-go/?category=comments)
 
diff --git a/go.mod b/go.mod
index d0b7a4b..0653e53 100644
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,11 @@ module github.com/swaggest/openapi-go
 go 1.13
 
 require (
-	github.com/bool64/dev v0.1.0
+	github.com/bool64/dev v0.1.5
 	github.com/stretchr/testify v1.6.1
 	github.com/swaggest/assertjson v1.3.0
-	github.com/swaggest/jsonschema-go v0.3.8
-	github.com/swaggest/refl v0.1.3
+	github.com/swaggest/jsonschema-go v0.3.11
+	github.com/swaggest/refl v0.1.5
 	github.com/swaggest/swgen v0.6.23
 	gopkg.in/yaml.v2 v2.3.0
 )
diff --git a/go.sum b/go.sum
index ca0e603..d773c9a 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,8 @@
 github.com/bool64/dev v0.1.0 h1:erHyUcwsuvZU8YvydZuZDCPR6CeQXALfiVl4lx7TW7o=
 github.com/bool64/dev v0.1.0/go.mod h1:pn52JC52uSgpazChx9CeXyG+S3sW2V36HHoLNBbscdg=
+github.com/bool64/dev v0.1.2/go.mod h1:pn52JC52uSgpazChx9CeXyG+S3sW2V36HHoLNBbscdg=
+github.com/bool64/dev v0.1.5 h1:35/UOPpbQE2ol+amR3UCb9GtKgjbjPLGNX8Kpa5nqpQ=
+github.com/bool64/dev v0.1.5/go.mod h1:pn52JC52uSgpazChx9CeXyG+S3sW2V36HHoLNBbscdg=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -66,8 +69,8 @@ github.com/swaggest/assertjson v1.3.0/go.mod h1:VR1/jzZHtROewu/SBEdFrBOBuNm1FO9L
 github.com/swaggest/jsonschema-go v0.2.1 h1:SVg+zXQ46w6ewR7jZDRVbpKKC+V7Y6Xn/teC2pRS2bM=
 github.com/swaggest/jsonschema-go v0.2.1/go.mod h1:QFauBdPTrU1UltwocM5FzOWnVjVVtcWkJWG3NlK9sV0=
 github.com/swaggest/jsonschema-go v0.2.4/go.mod h1:m4VV88Gbi7lCrt9ckJzigK1rMlEeFjdZUkJr1o5MnDE=
-github.com/swaggest/jsonschema-go v0.3.8 h1:QkRQXoO1jp9otq5i0blji6T2gVbsF0OfdiMHFuKeUwM=
-github.com/swaggest/jsonschema-go v0.3.8/go.mod h1:AQijowS82ZcUId9RStqvyGTxyhzYUiVDxelwQxEdOy8=
+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/refl v0.1.0 h1:mz3skba8ewcPmxDryM9rETv4fSuAX4GqNxTuDfPyUM0=
 github.com/swaggest/refl v0.1.0/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
@@ -75,6 +78,8 @@ github.com/swaggest/refl v0.1.2 h1:BfxmzI4FabeaSHijDEObFB1qaDPevcDsRetAYxg30yw=
 github.com/swaggest/refl v0.1.2/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
 github.com/swaggest/refl v0.1.3 h1:cnzEBcCNhYeLPG8Yy9JQixUkxMDsF0mo0GyzblLWrjE=
 github.com/swaggest/refl v0.1.3/go.mod h1:kmYWhxNEvjfRDdMRqpaR/vLULk/SotJs9HFUCIVMK8o=
+github.com/swaggest/refl v0.1.5 h1:dsIhZmcVkNqsnnc4SZO7ezp7j8cTn+N/i8ND+0WxA/I=
+github.com/swaggest/refl v0.1.5/go.mod h1:qeng4aRKeRt8NYAuLpag+FY9A/pDMkSwe7zhXn6/LW4=
 github.com/swaggest/swgen v0.6.20 h1:mGg20AJQu18lkx5NfqCJ9rRpAZjMc4QlXVOIS3JB1Ck=
 github.com/swaggest/swgen v0.6.20/go.mod h1:ipkZNfwztgRfbOWUllLZawfmxXprT8flqNJO9XhoMwM=
 github.com/swaggest/swgen v0.6.23 h1:9COrDC1o34xJS0NeQ2js7qGfo/Rgs16xWT0pQRvGNyY=
diff --git a/openapi3/reflect.go b/openapi3/reflect.go
index 3d257f1..860e6f5 100644
--- a/openapi3/reflect.go
+++ b/openapi3/reflect.go
@@ -241,8 +241,14 @@ func (r *Reflector) parseParametersIn(
 				p.WithStyle(string(QueryParameterStyleForm)).WithExplode(true)
 			}
 
+			// Check if query parameter is an object.
 			if in == ParameterInQuery {
-				if propertySchema.HasType(jsonschema.Object) {
+				ps, err := r.Reflect(reflect.New(field.Type).Interface(), jsonschema.InlineRefs)
+				if err != nil {
+					return err
+				}
+
+				if ps.HasType(jsonschema.Object) {
 					p.WithStyle(string(QueryParameterStyleDeepObject)).WithExplode(true)
 				}
 			}


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 38bc06d..f598cc7 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -5,6 +5,7 @@ on:
       - v*
     branches:
       - master
+      - main
   pull_request:
 env:
   GO111MODULE: "on"
@@ -12,7 +13,7 @@ jobs:
   test:
     strategy:
       matrix:
-        go-version: [ 1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x ]
+        go-version: [ 1.13.x, 1.14.x, 1.15.x ]
     runs-on: ubuntu-latest
     steps:
       - name: Install Go
@@ -36,4 +37,4 @@ jobs:
         uses: codecov/codecov-action@v1
         with:
           file: ./unit.coverprofile
-          flags: unittests
\ No newline at end of file
+          flags: unittests
diff --git a/openapi3/reflect_test.go b/openapi3/reflect_test.go
index 036dc83..a72c78c 100644
--- a/openapi3/reflect_test.go
+++ b/openapi3/reflect_test.go
@@ -490,3 +490,50 @@ func TestReflector_SetupRequest_queryObject(t *testing.T) {
 
 	assertjson.Equal(t, expected, b, string(b))
 }
+
+type namedType struct {
+	InQuery labels `query:"in_query"`
+}
+
+type labels map[int]float64
+
+func TestReflector_SetupRequest_queryNamedObject(t *testing.T) {
+	reflector := openapi3.Reflector{}
+	op := openapi3.Operation{}
+
+	s := reflector.SpecEns()
+	s.Info.Title = apiName
+	s.Info.Version = apiVersion
+
+	require.NoError(t, reflector.SetupRequest(openapi3.OperationContext{
+		Operation:  &op,
+		HTTPMethod: http.MethodGet,
+		Input:      new(namedType),
+	}))
+	require.NoError(t, s.AddOperation(http.MethodPost, "/somewhere", op))
+
+	b, err := assertjson.MarshalIndentCompact(s, "", " ", 100)
+	assert.NoError(t, err)
+
+	expected := []byte(`{
+	 "openapi":"3.0.2","info":{"title":"SampleAPI","version":"1.2.3"},
+	 "paths":{
+	  "/somewhere":{
+	   "post":{
+		"parameters":[
+		 {
+		  "name":"in_query","in":"query","style":"deepObject","explode":true,
+		  "schema":{"$ref":"#/components/schemas/Openapi3TestLabels"}
+		 }
+		],
+		"responses":{"204":{"description":"No Content"}}
+	   }
+	  }
+	 },
+	 "components":{
+	  "schemas":{"Openapi3TestLabels":{"type":"object","additionalProperties":{"type":"number"},"nullable":true}}
+	 }
+	}`)
+
+	assertjson.Equal(t, expected, b, string(b))
+}