Swagger: Reuse schema definition inside object property - swagger

Problem: I want to reuse a definiton. Once directly and once inside an object. The following code works but the validator from http://editor.swagger.io/#/ is saying "Not a valid response definition" and pointing to the line "200".
Do I really have to define Account twice? Or is this an issue form the validator?
* responses:
* 200: <---- ERROR POINTING HERE
* description: Updated account
* schema:
* type: object
* properties:
* data:
* type: object
* properties:
* account:
* schema:
* $ref: '#/definitions/Account'
The definition itself:
"Account" : {
"type" : "object",
"required": [
"id", "username", "lastname", "firstname", "traderid", "customerid", "company", "validated"
],
"properties": {
"id": {
"type": "string"
},
"username" : {
"type": "string"
},
"lastname" : {
"type": "string"
},
"firstname" : {
"type": "string"
},
"traderid" : {
"type": "string"
},
"customerid" : {
"type": "string"
},
"company" : {
"type": "string"
},
"validated" : {
"type": "boolean"
}
},
"example" : {
"id": "57790fdde3fd3ed82681f39c",
"username": "yuhucebafu",
"validated": false,
"customerid": "57790fdce3fd3ed82681f39a"
}
},

The problem is with the use of schema in the account property.
200:
description: Updated account
schema:
type: object
properties:
data:
type: object
properties:
account:
schema: # <-- Problem is here.
$ref: '#/definitions/Account'
Here's the corrected response definition:
200:
description: Updated account
schema:
type: object
properties:
data:
type: object
properties:
account:
$ref: '#/definitions/Account'
The property name "schema" is only used as a top-level property in Swagger's response object, or a parameter object where in is set to "body".
Once you've started specifying your schema, everything within that structure mostly follows standard JSON Schema, which is highly recursive. For example:
Within an object schema, the value of each properties/[propertyName] is a schema.
Within an array schema, the value of items is a schema.
The value of each /definitions/[name] is a schema.
The value of each array element within allOf, anyOf, or oneOf is a schema.
The value of additionalProperties can be a schema (or a boolean value).
...
You get the idea. JSON Schema doesn't use the property name schema for all of these cases, because it would introduce a lot of noise in a language where practically "everything is a schema."

Related

Schema Validation of Rest API Serenity BDD

I am facing a strange issue that I extract a schema of api response and added json file in my serenity project. While validating schema, what ever the schema provided the test was passing, moreover if I changed any type of key like I change the data-type of any key value correct schema( like changed the name data-type from string to integer) then test failed.
Scenario:
My API response:
{
"name":"Alex",
"age" : 20,
"city":"New York"
}
My Schema for this API: Test Passed which is ok
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
},
"city": {
"type": "string"
}
},
"required": [
"name",
"age",
"city"
]
}
If I changed the schema from correct to wrong that is remove any key value pair the test even passed which is not correct
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"city": {
"type": "string"
}
},
"required": [
"name",
"city"
]
}
Moreover if I write only " { } " in the Schema file the test passed
The method I am using for validation is matchesJsonSchemaInClassPath
The schema validation only checks the data-types that are coming for values in JSON are correct by matching with schema. For the data validation there is another method in Serenity BDD that is VerifyResponseData.ofTheresponse(jsonobj)
This works for me

Recursive avro schema type in schema registry

I want to create an Avro schema for schema registry for the following Typescript code:
export type Value = {
[key: string]:
| Value
| Value[]
| string
| number;
};
It's a recursive map type. I know it is possible to create a recursive record like below, but it's a different use case.
export type Node = {
value: number;
leafs: Node[];
}
I tried different approaches, including named types and schema references, but all resulted in validation errors when publishing a schema.
A simplified schema (excluding the recursive array) that is desired but invalid looks like this:
{
"type": "record",
"name": "Value",
"namespace": "com.namespace",
"fields": [
{ "name": "itemValues", "type": { "type": "map", "values": ["string", "int", "itemValues"] } }
]
}
Most of variations of this schema result in an error: org.apache.avro.SchemaParseException: Undefined name: "itemValues"
I could not find examples of similar scenarios and wondered if it's even possible to create one like this? The limitation for that would most likely be the lack of named union and map types in Avro.
Update
An example JSON that I want to achieve:
{
"itemValues": {
"validA": "sth",
"validB": [],
"validC": 8,
"recursiveProperty": {
"anyMap": { "sth": "else" }
}
}
}
The problem with your schema is that your values list is ["string", "int", "itemValues"], but the parser is complaining because you have told it there should be some type itemValues and you haven't defined one. The only type you have defined is Value.
Here's the fixed schema (including adding the array of Value as one of the potential types:
{
"type": "record",
"name": "Value",
"namespace": "com.namespace",
"fields": [
{ "name": "itemValues", "type": { "type": "map", "values": ["string", "int", "Value", {"type": "array", "items": "Value"}] } }
]
}

OpenApi v3: additionalProperties false with referenced schemas

There is some questions around this topic, but I dind't find the right way to do it.
What I want is to define all parameters in a single place and reuse it with no need to write it again. I already get that by using "allOf", but this limited the use of "additionalProperties".
My schema has this structure:
SchemaBase:
type: object
properties:
foo:
type: string
SchemaFull:
allOf:
- $ref: '#/components/schemas/SchemaBase'
- type: object
properties:
bar:
type: string
I tried using using definitions but it seems is not anymore in OpenApi version 3.
Here is a solution but its not what I'm looking for, becasue that is for properties, not the entire schema.
You need to use components like this:
openapi: 3.0.1
info:
title: OAS 3
version: 1.0.0
tags:
- name: example
paths:
/exe:
post:
requestBody:
content:
application/json:
schema:
additionalProperties: false
allOf:
- $ref: '#/components/schemas/SchemaBase'
- type: object
properties:
bar:
type: string
responses:
200:
description: Foo
content: {}
components:
schemas:
SchemaBase:
type: object
properties:
foo:
type: string
You may see and play with this here: https://editor.swagger.io/
JSON schema mapped:
{
"additionalProperties": false,
"allOf": [
{ "$ref": "#/definitions/SchemaBase" },
{
"type": "object",
"properties": {
"foo": {
"type": "string"
}
}
}
],
"definitions": {
"SchemaBase": {
"type": "object",
"properties": {
"foo": {
"type": "string"
}
}
}
}
}

Combining defintions in Swagger docs

I'm documenting an API with Swagger docs. I have several endpoints that share a common set of base properties. I'd like to use $ref to refer to that base set of properties and then extend those properties with additional properties that are unique to each endpoint. I imagined that it would work something like this, but this is invalid:
"properties": {
"$ref": "#/definitions/baseProperties",
unique_thing": {
"type": "string"
},
"another_unique_thing": {
"type": "string"
}
}
Indeed, the example you give here is invalid because $ref can't co-exist with other properties in the same object. $ref is a JSON Reference, and by definition, will cause the other properties to be ignored.
From your question, I assume you're looking for basic composition (rather than inheritance). This is achievable using the allOf keyword.
So, with the example you provided, you would have something like this:
{
"baseProperties": {
"type": "object",
"properties": {
...
}
},
"complexModel": {
"allOf": [
{
"$ref": "#/definitions/baseProperties"
},
{
"type": "object",
"properties": {
"unique_thing": {
"type": "string"
},
"another_unique_thing": {
"type": "string"
}
}
}
]
}
}
YAML version:
definitions:
baseProperties:
type: object
properties:
...
complexModel:
allOf:
- $ref: '#/definitions/baseProperties'
- type: object
properties:
unique_thing:
type: string
another_unique_thing:
type: string
You can also check out the example in the spec.

How to define an enum in OpenAPI (Swagger)?

Does anyone know how to define possible enum values in an OpenAPI 2.0 definition so that they will be displayed in the Model tab of Swagger UI? Example here has an enum option for the status property. How to do define such an enum in OpenAPI 2.0?
"enum" works like this in OpenAPI 2.0:
{
"in": "query",
"name": "sample",
"description": "a sample parameter with an enum value",
"type": "string",
"enum": [ "1", "2"],
"required": true
}
and in OpenAPI 3.0:
{
"in": "query",
"name": "sample",
"description": "a sample parameter with an enum value",
"schema": {
"type": "string",
"enum": [ "1", "2"]
},
"required": true
}
As you can see, there's a query parameter called sample of type string, and has an enum stating two possible values. In this case, the sample states the parameter is required, so the UI will not show an empty value as an option.
For a minimal working sample, try this:
{
"swagger": "2.0",
"info": {
"title": "title",
"description": "descriptor",
"version": "0.1"
},
"paths": {
"/sample": {
"post": {
"description": "sample",
"parameters": [
{
"in": "query",
"name": "sample",
"description": "a sample parameter with an enum value",
"type": "string",
"enum": [
"1",
"2"
],
"required": true
}
],
"responses": {
"200": {
"description": "Successful request."
}
}
}
}
}
}
To test it locally, you can declare a variable (for example spec) in your javascript, and pass it into the SwaggerUi object.
var spec = { ... };
window.swaggerUi = new SwaggerUi({
url: url,
spec: spec,
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
...
The url parameter will be ignored in this case.
Eventually, the output looks like this:
Updating this with YAML syntax.
OpenAPI 2.0:
parameters:
- in: query
name: sample
description: a sample parameter with an enum value
type: string
enum:
- 1
- 2
required: true
OpenAPI 3.0:
parameters:
- in: query
name: sample
description: a sample parameter with an enum value
schema:
type: string
enum:
- 1
- 2
required: true
This should work:
{
"name": "bookingType",
"in": "path",
"type": "array",
"items": {
"enum": [
"packages", "accommodations"
]
},
"description": "lorem ipsum"
}
Reference https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#itemsObject
This isn't the exact answer, but it might work for you until they add this functionality.
Simply declare the property like so
"MyObject":{
"properties":{
"MyEnum":{
"type":"Value1 or Value2 or Value3"
}
}
}
Your ModelSchema will show {}, but The Model will show MyEnum(Value1 or Value2 or Value3, optional)

Resources