Skip to content

Commit baf8677

Browse files
committed
Adds query string serialization optimization
Respects the `explode` attribute. When defined the actual serialization includes a duplication of the parameter. Otherwise arrays will be serialized in a comma-separated way. Signed-off-by: André König <[email protected]>
1 parent 97e37f7 commit baf8677

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

packages/openapi-to-graphql/src/oas_3_tools.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,19 @@ export function instantiatePathAndGetQuery(
388388

389389
// Query parameters
390390
case 'query':
391-
query[param.name] = args[sanitizedParamName]
391+
//
392+
// Spec-compliant query string serialization:
393+
// http://spec.openapis.org/oas/v3.0.3#style-examples
394+
//
395+
// Whenever the query string value is an array, we check if it
396+
// should be `exploded`. In this case, we don't serialize anything.
397+
// Otherwise, the array will be joined in comma-separated fashion.
398+
//
399+
//
400+
const arg = args[sanitizedParamName]
401+
const shouldBeCommaSeparated = Array.isArray(arg) && !param.explode
402+
403+
query[param.name] = shouldBeCommaSeparated ? arg.join(",") : arg
392404
break
393405

394406
// Header parameters

packages/openapi-to-graphql/src/resolver_builder.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,14 @@ export function getResolver({
339339
)
340340

341341
return new Promise((resolve, reject) => {
342-
NodeRequest(options, (err, response, body) => {
342+
NodeRequest({...options,
343+
//
344+
// Use `native` querystring library to avoid `foo[0]=bar&foo[1]=baz`
345+
// which is not spec compliant. See https://github.com/request/request#requestoptions-callback
346+
// for further information.
347+
//
348+
useQuerystring: true,
349+
}, (err, response, body) => {
343350
if (err) {
344351
httpLog(err)
345352
reject(err)

packages/openapi-to-graphql/test/example_api2.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ test('Querying the two operations', () => {
7575
user {
7676
name
7777
}
78+
getRobots(types: ["Droid", "Bot"]) {
79+
name
80+
}
7881
}`
7982
return graphql(createdSchema, query).then(result => {
8083
expect(result).toEqual({
@@ -84,6 +87,9 @@ test('Querying the two operations', () => {
8487
},
8588
user: {
8689
name: 'William B Ropp'
90+
},
91+
getRobots: {
92+
name: "Nkiru Gwendoline"
8793
}
8894
}
8995
})

packages/openapi-to-graphql/test/example_api2_server.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ function startServer(PORT) {
3131
})
3232
})
3333

34+
app.get('/api/robots', (req, res) => {
35+
console.log(req.method, req.path)
36+
res.send({
37+
name: "Nkiru Gwendoline"
38+
})
39+
})
40+
3441
return new Promise(resolve => {
3542
server = app.listen(PORT, () => {
3643
console.log(`Example API accessible on port ${PORT}`)

packages/openapi-to-graphql/test/fixtures/example_oas2.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,36 @@
7373
}
7474
}
7575
}
76+
},
77+
"/robots": {
78+
"get": {
79+
"description": "",
80+
"parameters": [
81+
{
82+
"in": "query",
83+
"name": "types",
84+
"required": true,
85+
"schema": {
86+
"type": "array",
87+
"items": {
88+
"type": "string"
89+
}
90+
}
91+
}
92+
],
93+
"responses": {
94+
"200": {
95+
"description": "",
96+
"content": {
97+
"application/json": {
98+
"schema": {
99+
"$ref": "#/components/schemas/robot"
100+
}
101+
}
102+
}
103+
}
104+
}
105+
}
76106
}
77107
},
78108
"components": {
@@ -86,6 +116,16 @@
86116
"description": "The legal name of a user"
87117
}
88118
}
119+
},
120+
"robot": {
121+
"type": "object",
122+
"description": "A robot represents a not so natural person",
123+
"properties": {
124+
"name": {
125+
"type": "string",
126+
"description": "The legal name of a robot"
127+
}
128+
}
89129
}
90130
}
91131
},

0 commit comments

Comments
 (0)