-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Description
I would like to use an OpenAPI schema with a discriminator, then validate some input againts the schema. Thought this would be really easy-- there are so many validators out there that say they have discriminator support... and none of them I've tried so far worked! Seems like a fundamental task that anyone working with OpenAPI would need to perform, so maybe there's obvious and easy solution and I'm just not seeing it or I'm doing something wrong (maybe the spec I am using is flawed?)
In particular, I would like to do the following:
- Given an OpenAPI spec that includes a POST request body using a schema with a discriminator, start a localhost web server on any port
- Send a POST request using curl to the above service, and receive an accept/reject response based on whether the POSTed data conformed to the request body schema
I have tried the following, and in each case, I got the same result: validation worked fine in general, but failed to throw an error when the mapped schema and the discriminator value did not match (see specific example below)
The specific test case I used is as follows:
- the spec describes a polymorphic object called Object, which has two subclasses: "obj1" and "obj2", each with a corresponding "properties" object that contains "property1a" & "property1b" in the case of "obj1", and "property2a" & "property2b" in the case of "obj2"
- the test cases are i) a valid object, and ii) an invalid object that contains type "obj2" but properties corresponding to the obj1 subclass properties schema
Test Case 1 (valid data):
{
"id": "hi",
"type": "obj1",
"properties": {
"property1a": 1,
"property1b": 2
}
}
curl command:
curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj1","properties":{"property1a":1,"property1b":2}}'
Test Case 2 (invalid data, validator properly rejects):
{
"id": "hi",
"type": "obj1",
"properties": {
"nonexistent_property": 1,
"property1b": 2
}
}
Notice that nonexistent_property
is invalid. All of the validators I tried correctly reject this
curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj2","properties":{"nonexistent_property":1,"property1b":2}}'
Test Case 3 (validator should throw an error, but does not!):
{
"id": "hi",
"type": "obj2",
"properties": {
"property1a": 1,
"property1b": 2
}
}
Notice that the type is obj2 but the properties are those corresponding to obj1. None of the validators reject this-- but they should, right?
curl command:
curl -X POST -k 'http://localhost:3000/v1/object/hi' -H 'Content-type: application/json' --data '{"id":"hi","type":"obj2","properties":{"property1a":1,"property1b":2}}'
YAML:
openapi: "3.0.0"
info:
version: "1.0.0"
title: "Discriminator example"
license:
name: "MIT"
servers:
- url: "http://localhost/v1"
components:
schemas:
Error:
type: "object"
required:
- "code"
- "message"
properties:
code:
type: "integer"
format: "int32"
message:
type: "string"
Object1Properties:
type: "object"
required:
- "property1a"
- "property1b"
properties:
property1a:
type: "string"
property1b:
type: "string"
Object2Properties:
type: "object"
required:
- "property2a"
- "property2b"
properties:
property2a:
type: "string"
property2b:
type: "string"
Object:
type: "object"
required:
- "id"
- "type"
- "properties"
properties:
id:
type: "string"
type:
type: "string"
enum:
- "obj1"
- "obj2"
properties:
oneOf:
-
$ref: "#/components/schemas/Object1Properties"
-
$ref: "#/components/schemas/Object2Properties"
discriminator:
propertyName: "type"
mapping:
obj1: "#/components/schemas/Object1Properties"
obj2: "#/components/schemas/Object2Properties"
requestBodies:
Object:
description: "Object schema in request body"
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
parameters:
objectId:
name: "objectId"
in: "path"
required: true
description: "Id of the object"
schema:
type: "string"
responses:
defaultError:
description: "Unexpected error"
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
paths:
/object/{objectId}:
post:
summary: "Create an object"
operationId: "createObject"
parameters:
-
$ref: "#/components/parameters/objectId"
tags:
- "objects"
requestBody:
$ref: "#/components/requestBodies/Object"
responses:
201:
description: "Object created"
content:
application/json:
schema:
$ref: "#/components/schemas/Object"
default:
$ref: "#/components/responses/defaultError"
Example of validator server using express-openapi-validator is attached.
validation_server.zip
Any help is much appreciated!