Skip to content

Commit 9fa3593

Browse files
pnoebauerdhmlau
authored andcommitted
fix: illustrate the discriminator bug and fix in loopback rest request-body-validator
Signed-off-by: Philip Noebauer <[email protected]>
1 parent cb51b42 commit 9fa3593

File tree

7 files changed

+146
-3
lines changed

7 files changed

+146
-3
lines changed

examples/validation-app/src/application.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import {BootMixin} from '@loopback/boot';
77
import {ApplicationConfig, createBindingFromClass} from '@loopback/core';
88
import {RepositoryMixin} from '@loopback/repository';
9-
import {RestApplication} from '@loopback/rest';
9+
import {RestApplication, RestBindings} from '@loopback/rest';
1010
import {
1111
RestExplorerBindings,
1212
RestExplorerComponent,
@@ -32,6 +32,12 @@ export class ValidationApplication extends BootMixin(
3232
// Set up default home page
3333
this.static('/', path.join(__dirname, '../public'));
3434

35+
this.bind(RestBindings.REQUEST_BODY_PARSER_OPTIONS).to({
36+
validation: {
37+
discriminator: true,
38+
},
39+
});
40+
3541
// Customize @loopback/rest-explorer configuration here
3642
this.configure(RestExplorerBindings.COMPONENT).to({
3743
path: '/explorer',

examples/validation-app/src/controllers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
// License text available at https://opensource.org/licenses/MIT
55

66
export * from './coffee-shop.controller';
7+
export * from './pet.controller';
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright IBM Corp. and LoopBack contributors 2020. All Rights Reserved.
2+
// Node module: @loopback/example-validation-app
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
import {post, requestBody} from '@loopback/rest';
7+
import {Cat, Dog, Pet} from '../models';
8+
9+
export class PetController {
10+
constructor() {}
11+
12+
@post('/pets', {
13+
responses: {
14+
'200': {
15+
description: 'Pet model instance',
16+
content: {
17+
'application/json': {
18+
schema: {'x-ts-type': Pet},
19+
},
20+
},
21+
},
22+
},
23+
})
24+
async create(
25+
@requestBody({
26+
content: {
27+
'application/json': {
28+
schema: {
29+
required: ['kind'],
30+
discriminator: {
31+
propertyName: 'kind',
32+
},
33+
oneOf: [{'x-ts-type': Cat}, {'x-ts-type': Dog}],
34+
},
35+
},
36+
},
37+
})
38+
request: Pet,
39+
): Promise<Pet> {
40+
return request;
41+
}
42+
}

examples/validation-app/src/middleware/validation-error.middleware.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ export class ValidationErrorMiddlewareProvider implements Provider<Middleware> {
5454
err: HttpErrors.HttpError,
5555
): Response | undefined {
5656
// 2. customize error for particular endpoint
57-
if (context.request.url === '/coffee-shops') {
57+
if (
58+
context.request.url === '/coffee-shops' ||
59+
context.request.url === '/pets'
60+
) {
5861
// if this is a validation error from the PATCH method, customize it
5962
// for other validation errors, the default AJV error object will be sent
6063
if (err.statusCode === 422 && context.request.method === 'PATCH') {

examples/validation-app/src/models/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
// License text available at https://opensource.org/licenses/MIT
55

66
export * from './coffee-shop.model';
7+
export * from './pet.model';
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {Model, model, property} from '@loopback/repository';
2+
3+
@model()
4+
export class CatProperties extends Model {
5+
@property({
6+
type: String,
7+
required: true,
8+
})
9+
color: string;
10+
11+
@property({
12+
type: Number,
13+
required: false,
14+
})
15+
whiskerLength?: number;
16+
}
17+
18+
@model()
19+
export class DogProperties extends Model {
20+
@property({
21+
type: String,
22+
required: true,
23+
})
24+
breed: string;
25+
26+
@property({
27+
type: Number,
28+
required: false,
29+
})
30+
barkVolume?: number;
31+
}
32+
33+
@model()
34+
export class Pet extends Model {
35+
@property({
36+
type: String,
37+
required: true,
38+
})
39+
name: string;
40+
41+
@property({
42+
type: Number,
43+
required: false,
44+
})
45+
weight?: number;
46+
47+
kind: string;
48+
49+
animalProperties: CatProperties | DogProperties;
50+
}
51+
52+
@model()
53+
export class Dog extends Pet {
54+
@property({
55+
type: String,
56+
jsonSchema: {
57+
enum: ['Dog'],
58+
},
59+
required: true,
60+
})
61+
kind: string;
62+
63+
@property({
64+
type: DogProperties,
65+
required: true,
66+
})
67+
animalProperties: DogProperties;
68+
}
69+
70+
@model()
71+
export class Cat extends Pet {
72+
@property({
73+
type: String,
74+
jsonSchema: {
75+
enum: ['Cat'],
76+
},
77+
required: true,
78+
})
79+
kind: string;
80+
81+
@property({
82+
type: CatProperties,
83+
required: true,
84+
})
85+
animalProperties: CatProperties;
86+
}

packages/rest/src/validation/request-body.validator.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,11 @@ export async function validateRequestBody(
8484
* @param openapiSchema - The OpenAPI schema to convert.
8585
*/
8686
function convertToJsonSchema(openapiSchema: SchemaObject) {
87-
const jsonSchema = toJsonSchema(openapiSchema);
87+
// const jsonSchema = toJsonSchema(openapiSchema);
88+
const jsonSchema = toJsonSchema(openapiSchema, {
89+
keepNotSupported: ['discriminator'],
90+
});
91+
8892
delete jsonSchema['$schema'];
8993
/* istanbul ignore if */
9094
if (debug.enabled) {

0 commit comments

Comments
 (0)