From cd3b772c8d94d57c00b091ce1acfc47a17115eb9 Mon Sep 17 00:00:00 2001 From: DEEPAK RAJAMOHAN Date: Mon, 30 Dec 2019 12:22:15 +0530 Subject: [PATCH] fix: suport complex objects for query params in api explorer issue: https://github.com/strongloop/loopback-next/issues/2208 BREAKING CHANGE --- .../param/param-query.decorator.unit.ts | 34 +++++++++---------- .../src/decorators/parameter.decorator.ts | 15 +++++--- .../rest/src/coercion/coerce-parameter.ts | 11 ++++-- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/openapi-v3/src/__tests__/unit/decorators/param/param-query.decorator.unit.ts b/packages/openapi-v3/src/__tests__/unit/decorators/param/param-query.decorator.unit.ts index 34e8ee0f7720..85d2f50a7b09 100644 --- a/packages/openapi-v3/src/__tests__/unit/decorators/param/param-query.decorator.unit.ts +++ b/packages/openapi-v3/src/__tests__/unit/decorators/param/param-query.decorator.unit.ts @@ -229,11 +229,10 @@ describe('Routing metadata for parameters', () => { const expectedParamSpec = { name: 'filter', in: 'query', - style: 'deepObject', - explode: true, - schema: { - type: 'object', - additionalProperties: true, + content: { + 'application/json': { + schema: {type: 'object', additionalProperties: true}, + }, }, }; expectSpecToBeEqual(MyController, expectedParamSpec); @@ -256,13 +255,15 @@ describe('Routing metadata for parameters', () => { const expectedParamSpec: ParameterObject = { name: 'filter', in: 'query', - style: 'deepObject', - explode: true, - schema: { - type: 'object', - properties: { - where: {type: 'object', additionalProperties: true}, - limit: {type: 'number'}, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + where: {type: 'object', additionalProperties: true}, + limit: {type: 'number'}, + }, + }, }, }, }; @@ -300,11 +301,10 @@ describe('Routing metadata for parameters', () => { name: 'filter', in: 'query', description: 'Search criteria', - style: 'deepObject', - explode: true, - schema: { - type: 'object', - additionalProperties: true, + content: { + 'application/json': { + schema: {type: 'object', additionalProperties: true}, + }, }, }; expectSpecToBeEqual(MyController, expectedParamSpec); diff --git a/packages/openapi-v3/src/decorators/parameter.decorator.ts b/packages/openapi-v3/src/decorators/parameter.decorator.ts index afda71d78644..40bb3ecb52e2 100644 --- a/packages/openapi-v3/src/decorators/parameter.decorator.ts +++ b/packages/openapi-v3/src/decorators/parameter.decorator.ts @@ -50,8 +50,11 @@ export function param(paramSpec: ParameterObject) { // generate schema if `paramSpec` has `schema` but without `type` (isSchemaObject(paramSpec.schema) && !paramSpec.schema.type) ) { - // please note `resolveSchema` only adds `type` and `format` for `schema` - paramSpec.schema = resolveSchema(paramType, paramSpec.schema); + // If content explicitly mentioned do not resolve schema + if (!paramSpec.content) { + // please note `resolveSchema` only adds `type` and `format` for `schema` + paramSpec.schema = resolveSchema(paramType, paramSpec.schema); + } } } @@ -212,9 +215,11 @@ export namespace param { return param({ name, in: 'query', - style: 'deepObject', - explode: true, - schema, + content: { + 'application/json': { + schema, + }, + }, ...spec, }); }, diff --git a/packages/rest/src/coercion/coerce-parameter.ts b/packages/rest/src/coercion/coerce-parameter.ts index 36121d035cab..8ea60a0ebe2c 100644 --- a/packages/rest/src/coercion/coerce-parameter.ts +++ b/packages/rest/src/coercion/coerce-parameter.ts @@ -32,7 +32,14 @@ export function coerceParameter( data: string | undefined | object, spec: ParameterObject, ) { - const schema = spec.schema; + let schema = spec.schema; + + if (!schema && spec.content) { + const content = spec.content; + const jsonSpec = content['application/json']; + schema = jsonSpec.schema; + } + if (!schema || isReferenceObject(schema)) { debug( 'The parameter with schema %s is not coerced since schema' + @@ -172,7 +179,7 @@ function parseJsonIfNeeded( ): string | object | undefined { if (typeof data !== 'string') return data; - if (spec.in !== 'query' || spec.style !== 'deepObject') { + if (spec.in !== 'query' || (spec.style !== 'deepObject' && !spec.content)) { debug( 'Skipping JSON.parse, argument %s is not in:query style:deepObject', spec.name,