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

Fix queries with array parameters #475

Open
wants to merge 1 commit into
base: master
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
7 changes: 3 additions & 4 deletions packages/openapi-to-graphql/src/resolver_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1370,8 +1370,9 @@ export function extractRequestDataFromArgs<TSource, TContext, TArgs>(

// Query parameters
case 'query':
// setting param style as form assumes explode is true by default
if (param.style === 'form' && typeof args[saneParamName] === 'object') {
if (Array.isArray(args[saneParamName]) && param.style === 'form' && param.explode !== false) {
qs[param.name] = args[saneParamName].join(',')
} else if (param.style === 'form' && typeof args[saneParamName] === 'object') {
if (param.explode === false) {
qs[param.name] = Object.entries(args[saneParamName]).reduce((acc, val) => {
acc += val.join(',')
Expand All @@ -1382,8 +1383,6 @@ export function extractRequestDataFromArgs<TSource, TContext, TArgs>(
qs[key] = value
})
}
} else if (Array.isArray(args[saneParamName]) && param.style === 'form' && param.explode !== false) {
qs[param.name] = args[saneParamName].join(',')
} else {
qs[param.name] = args[saneParamName]
}
Expand Down
67 changes: 67 additions & 0 deletions packages/openapi-to-graphql/test/fixtures/query_arguments.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"openapi": "3.0.2",
"info": {
"title": "arguments server fixture",
"version": "0.0.0"
},
"servers": [
{
"url": "http://localhost:{port}/",
"description": "The location of the local test server.",
"variables": {
"port": {
"default": "3001"
}
}
}
],
"paths": {
"/todos": {
"get": {
"parameters": [
{
"name": "id__in",
"description": "filter by collection of ids",
"in": "query",
"style": "form",
"explode": true,
"schema": {
"type": "array",
"items": {
"type": "integer"
}
}
}
],
"responses": {
"200": {
"description": "Return list of todos",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Todo"
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Todo": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"readOnly": true
}
}
}
}
}
}
73 changes: 73 additions & 0 deletions packages/openapi-to-graphql/test/query_arguments.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
// Node module: openapi-to-graphql
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

'use strict'

import { afterAll, beforeAll, expect, test } from '@jest/globals'
import { graphql, GraphQLSchema } from 'graphql'

import * as openAPIToGraphQL from '../src/index'
import express from 'express'
import http from 'http'

// Set up the schema first
const oas = require('./fixtures/query_arguments.json')
const PORT = 31002
// Update PORT for this test case:
oas.servers[0].variables.port.default = String(PORT)

async function startServer () {
const app = express()

const data = [
{ id: 1 },
{ id: 2 },
{ id: 3 }
]

app.get('/todos', (req, res) => {
const ids = req.query.id__in as unknown as Array<number>

res.send(data.filter((x) => ids.includes(x.id)))
})

return new Promise<http.Server>((resolve) => {
const server = app.listen(PORT, () => resolve(server))
})
}

let server: http.Server
let createdSchema: GraphQLSchema
beforeAll(async () => {
server = await startServer()

return openAPIToGraphQL
.createGraphQLSchema(oas)
.then(({ schema }) => {
createdSchema = schema
})
})

afterAll(() => new Promise<void>((resolve) => {
server.close(() => resolve())
}))

test('Query Arguments', () => {
const query = `{
todos(idIn: [1]) {
id
}
}`

return graphql(createdSchema, query).then((result) => {
expect(result).toEqual({
data: {
todos: [{
id: 1
}]
}
})
})
})