I'm trying to specify my API data types in swagger 2.0 using yaml, but I'm getting a reference error (see error details at the bottom).
I'm using a nested structure, where the parent object (InvoiceConfigData) contains an array of child objects (ProviderVariantsData). This is the hierarchy of yaml files:
.api/swagger/cfg/InvoiceConfigData.yaml:
required:
- providerName
- providerVariants
properties:
providerName:
type: string
providerVariants:
type: array
items:
$ref: "#/definitions/ProviderVariantsData"
.api/swagger/cfg/ProviderVariantsData.yaml:
properties:
displayName:
type: string
cif:
type: string
availableTemplates:
type: array
items:
type: string
.api/swagger/definitions.yaml:
ProviderVariantsData:
$ref: ./cfg/ProviderVariantsData.yaml
InvoiceConfigData:
$ref: ./cfg/InvoiceConfigData.yaml
But I get the following errors:
API Errors:
#/definitions/InvoiceConfigData/$ref: Reference could not be resolved: ./cfg/InvoiceConfigData.yaml
#/definitions/ProviderVariantsData/$ref: Reference could not be resolved: ./cfg/ProviderVariantsData.yaml
API Warnings:
#/definitions/ProviderVariantsData: Definition is defined but is not used: #/definitions/ProviderVariantsData
There's something wrong in the way I reference the ProviderVariantsData, but I can't find what's causing the error. I've tried to flip the order in "definitions.yaml" (InvoiceConfigData above ProviderVariansData) without success.
swagger 2.0 doesn't support multiple YAML files.
Related
I am trying to add multiple examples for an Object property.
The Swagger-Ui and Editor version that I am using are
'{"swaggerEditor":"3.6.31/g10642b3c-dirty","swaggerUi":{"version":"3.23.0","gitRevision":"g23d7260f","gitDirty":true,"buildTimestamp":"Sat, 29 Jun 2019 19:42:59 GMT","machine":"jenins-swagger-oss"}}'
Based on OpenAPI doc, this version of swagger UI and editor have support for multiple examples but I still see this error:
Structural error at components.schemas.MainObject.allOf.3.properties.partitionProperty
should NOT have additional properties
additionalProperty: examples
Jump to line 3016
This is how I have added the examples in the property:
MainObject:
allOf:
- $ref: '#/components/schemas/MainObjectLite'
- type: object
description: foobar.
readOnly: true
required:
- fooRequired
properties:
fooRequired:
type: string
description: system only field used for table data indexing
partitionProperty:
type: string
description: foobar
examples:
sampleExample:
value: 2016-03-04T03:00:00
summary: sample partition
OpenAPI 3.0
Multiple examples are only supported at the media type level and are not supported inside schemas. Schemas and properties can only have a single example, e.g.
partitionProperty:
type: string
example: '2016-03-04T03:00:00'
In other words, this won't work:
MainObject:
type: object
properties:
..
examples: # <--- Won't work
minimal:
summary: Minimal example
value:
foo: bar
full:
summary: Example with all properties
value:
foo: bar
baz: xyzzy
If you want multiple examples, you need to use request examples or response examples instead:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/MainObject'
examples:
minimal:
summary: Minimal example
value:
foo: bar
full:
summary: Example with all properties
value:
foo: bar
baz: xyzzy
OpenAPI 3.1
OAS 3.1 uses a newer version of JSON Schema which supports multiple examples in schemas and properties. Unlike media type examples which is a map of named Example Objects, schema-level and property-level examples is a plain list of example values.
MyObject:
type: object
properties:
prop1:
type: string
# Property-level examples
examples:
- foo
- bar
prop2:
type: integer
# Object-level examples
examples:
- prop1: hello
prop2: 5
- prop1: world
prop2: 0
I'd like to provide a series of custom codes and message for my error 400 but can't find any way to do so.
Ideally something like:
Error:
type: object
enum:
- [E01, 'Error1']
- [E02, 'Error2']
And so on
So I'm not sure that enums here can help you.
If you take a look over official documentation Enums are just strings, not object https://swagger.io/docs/specification/data-models/enums/ .
So my proposal is to use :
ErrorType:
type: object
properties:
code:
type: integer
name:
type: string
example: # Sample object
code: 10
name: Custom Error
Error:
type: object
properties:
errors:
oneOf:
- $ref '#/ErrorType'
- etc...
or directly without properties
Error:
type: object
oneOf:
- $ref '#/ErrorType'
- etc...
You can take a look for more examples on the official page https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
You can check out how Twitter has described it with $oneOf ( https://api.twitter.com/labs/2/openapi.json ) but unfortunately this convention is not easy nor supported by code generation tools like openapi-generator.
Until OpenApi supports enum descriptions (proposal is pending), one of the easiest ways are to:
define enum with all possible error codes
in the top level description: section of the spec define an inner section (with markdown notation #Error codes) that lists all error codes along with description.
Automated tool should check if the enum and description is consistent.
I have a problem with the imports of the generated code of the openapi-generator for Java and Kotlin.
Let's say I have a root.yaml/child1.yaml/child2.yaml with the following content:
components:
schemas:
Transfer:
type: object
allOf:
- $ref: "child1.yaml#/components/schemas/Pet1"
- $ref: "child2.yaml#/components/schemas/Pet2"
child1.yaml:
components:
schemas:
Pet1:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
child2.yaml:
components:
schemas:
Pet2:
type: object
required:
- id2
- name2
properties:
id2:
type: integer
format: int64
name2:
type: string
tag2:
type: string
In this case, I do not care for the entities in child1/child2 and I only want the Transfer-object to be build, so I fill the the modelsToGenerate-setting with Transfer only. My problem is that the generated Transfer class always contains imports for the childs, even when they are not needed. For example:
import com.model.Pet1
import com.model.Pet2
data class Transfer (
val id: kotlin.Long,
val name: kotlin.String,
val id2: kotlin.Long,
val name2: kotlin.String,
val tag: kotlin.String? = null,
val tag2: kotlin.String? = null
)
The generated class is not dependend on the childs, but the imports are always generated. Is there a setting or a workaround that I missed? The unnecessary imports also appear when Pet1 and Pet2 are generated, but Transfer is still not dependend on the childs.
My use case is that I do have some very large models in the spec and I would like to split them into multiple files to reduce clutter/duplication without a public class for every single child.
Thanks in advance.
Found the answer myself. You have to run a formatter like Google Java formatter after the classes are generated.
Swagger documentation explains how to define arrays that contain mixed types, such as ["foo", 5, -2, "bar"]. But, how can I define that an array must contain either one type of items (strings, ["foo", "bar"]) or another (integers, [5, -2])?
I've tried this, but Swagger UI can't render it, so I guess that it's wrong:
oneOf:
- items:
- $ref: '#/components/schemas/SchemaA'
- items:
- $ref: '#/components/schemas/SchemaB'
First of all, remember that oneOf is only supported in OpenAPI 3.0 (openapi: 3.0.0) but not in OpenAPI 2.0 (swagger: '2.0').
Your scenario can be defined using oneOf like so:
oneOf:
- type: array
items:
type: string
- type: array
items:
type: integer
- type: array
items:
$ref: '#/components/schemas/SchemaA'
In vanilla JSON Schema, type: array can be moved out of oneOf and placed alongside oneOf but I'm not sure if OpenAPI allows this (the OpenAPI Specification is unclear on this).
type: array
oneOf:
- items:
type: string
- items:
type: integer
- items:
$ref: '#/components/schemas/SchemaA'
I've tried this, but Swagger UI can't render it
Currently, Swagger UI does not automatically generate examples for oneOf and anyOf schemas (see this issue). The workaround is to add an example alongside oneOf manually:
example: [1, 2, 3] # <------
oneOf:
- type: array
items:
type: string
- type: array
items:
type: integer
- type: array
items:
$ref: '#/components/schemas/SchemaA'
I want to add a description to an object property that his definition is referenced. Something like that:
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
$ref: "#/definitions/PhoneNumber"
But the editor warns that the description property will be skipped:
Extra JSON Reference properties will be ignored: description
I have found a less elegant workaround that works for the editor, but not for the Swagger UI (not sure that is may due to the recent update to 3.0.2 version of the Swagger UI)
newCreditCard:
type: object
properties:
billingPhone:
description: Phone number of the card holder
allOf:
- $ref: "#/definitions/PhoneNumber"
How do you do it in your Swaggers specification?
Thanks for the help!
If you add anything to the same level of $ref it will be ignored .
json $ref definition https://datatracker.ietf.org/doc/html/draft-pbryan-zyp-json-ref-03#section-3
correct way is to provide the description in the referenced object.
You could simply move the description property to the definition of PhoneNumber. Your original post does not show how you have defined PhoneNumber, but this snippet validates without warnings:
definitions:
phoneNumber:
type: string
description: Phone number of the card holder
newCreditCard:
type: object
properties:
billingPhone:
$ref: "#/definitions/phoneNumber"
If this answer is not what you are looking for, please restate the question. We need to know what you are trying to accomplish.
although it is not according to JSON standards.
if you are using Swashbuckle to generate your swagger.
i took advantage over the "Extensions" property of schema.
and managed to create a swagger JSON, with $ref and extended properties.
var refSchema = new OpenApiSchema
{
//Reference = new OpenApiReference { ExternalResource = referenceLink, Type = ReferenceType.Link }, this wont work and omit all your other properties
Extensions = new Dictionary<string, IOpenApiExtension>
{
{ "$ref" , new OpenApiString(referenceLink) } // adding ref as extension cause according to JSON standards $ref shouldnt have any other properties
},
Description = prop.Value.Description,
ReadOnly = prop.Value.ReadOnly,
Required = prop.Value.Required,
Type = prop.Value.Type,
Example = prop.Value.Example,
};
For anyone using Swashbuckle with ASP.NET, you can use the following code to have the $ref construct put under the allOf (just like the :
// do this wherever you are calling AddSwaggerGen()
ArgBuilder.Services.AddSwaggerGen(opts => {
opts.UseAllOfToExtendReferenceSchemas(); // add this line.
});
Now if you have a model with two properties of the same type, the individual descriptions for each field will show up in Swagger UI (e.g. below, both FooHeader and BarHeader are properties of type HttpHeader and their descriptions show up):