diff --git a/packages/openapi-to-graphql/src/resolver_builder.ts b/packages/openapi-to-graphql/src/resolver_builder.ts index 79dfac13..2f3f7dec 100644 --- a/packages/openapi-to-graphql/src/resolver_builder.ts +++ b/packages/openapi-to-graphql/src/resolver_builder.ts @@ -1370,8 +1370,9 @@ export function extractRequestDataFromArgs( // 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(',') @@ -1382,8 +1383,6 @@ export function extractRequestDataFromArgs( 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] } diff --git a/packages/openapi-to-graphql/test/fixtures/query_arguments.json b/packages/openapi-to-graphql/test/fixtures/query_arguments.json new file mode 100644 index 00000000..adf1ac00 --- /dev/null +++ b/packages/openapi-to-graphql/test/fixtures/query_arguments.json @@ -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 + } + } + } + } + } +} diff --git a/packages/openapi-to-graphql/test/query_arguments.test.ts b/packages/openapi-to-graphql/test/query_arguments.test.ts new file mode 100644 index 00000000..12ca1754 --- /dev/null +++ b/packages/openapi-to-graphql/test/query_arguments.test.ts @@ -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 + + res.send(data.filter((x) => ids.includes(x.id))) + }) + + return new Promise((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((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 + }] + } + }) + }) +})