It's possible to define a parameter into the parameters section, under components section into an OPEN API sheet.
At the same time it's possible to reference that parameter into a path, under the responses section.
What I want to do, it's E.G. having a parameter "include" of type array override only the section enum of the schema part, from the paths section referencing the one in the components one.
It seems the allOf directive it's not allowed in that context, is there a way to do that?
Probably I just need an example.
Example:
In the components.parameters section:
- name: include
in: query
description: relationships to include
type: array
style: form
explode: true
schema:
type: array
items:
type: string
In the paths. .. parameters section:
- name: include
in: query
description: relationships to include
type: array
style: form
explode: true
schema:
type: array
items:
type: string
enum: [legs, owner]
I would like to redefine only the enum section and not
Related
We are looking at using CloudEvents as a message envelope for events generated in our system, and defining those messages using AsyncAPI.
We are using the CloudEvents type property to identify each event type, with a different data property schema for each type. Whilst I have worked out how to define the individual event structures using AsyncAPI, I can't identify how to set the type property to the value required for that event type.
What would seem a mis-use of the enum keyword is the only way so far that I've been able to associated the event type to the property, as shown in the example below. Is there an accepted pattern for achieving the definition of these fixed properties within the AsyncAPI specification?
channels:
user:
subscribe:
message:
payload:
$ref: '#/components/schemas/firstEventPayload'
components:
schemas:
firstEventPayload:
type: object
allOf:
- $ref: 'https://raw.githubusercontent.com/cloudevents/spec/v1.0.1/spec.json'
properties:
type:
type: string
enum: [test.cloud.event.new-user]
data:
type: object
properties:
userId:
type: string
format: uuid
email:
type: string
format: email
Credit to developers.redhat.com for the cloudevent/spec $ref
In JSON Schema (AsyncAPI Schema is a superset of it) you can also use const like:
type:
type: string
const: test.cloud.event.new-user
Is there any way to name a custom property 'type', given that there already exists a special 'type' property which is a reserved keyword.
components:
schemas:
element:
type: object
properties:
name:
type: string #type here is the keyword
type: #type here is the actual name of the property!
type: string
enum:
- radiogroup
- checkbox
The back-end system which produces the JSON messages cannot be modified to rename the property.
Thanks.
Reserved keywords can be used as property/parameter names in all OpenAPI versions.
The only issue with your example is that YAML indentation is off, other than that your object and property definitions are perfectly valid.
components:
schemas:
element:
type: object
properties:
name:
type: string
type: # <----- yes, property name can be "type"
type: string
enum:
- radiogroup
- checkbox
I use kotlin + Jersey and swagger documentation generator with the approach code first.
I have two DTO
enum class DataType {
FIRST, SECOND;
}
data class Data1(type: DataType)
data class Data2(type: DataType)
gradle dependency
implementation("io.swagger.core.v3:swagger-jaxrs2-jakarta:2.2.6")
Expected result for documentation:
components:
schemas:
DataType:
type: string
enum: [ FIRST, SECOND ]
Data1:
type: object
properties:
type:
$ref: '#/components/schemas/DataType'
Data2:
type: object
properties:
type:
$ref: '#/components/schemas/DataType'
Actual result
components:
schemas:
Data1:
type: object
properties:
type:
type: string
enum: [ FIRST, SECOND ]
Data2:
type: object
properties:
type:
type: string
enum: [ FIRST, SECOND ]
The problem is, that if any client reuses schema to generate classes for his own app, he gets two separate enum classes for the type property.
Q: How to make generator to detect that it is the same enum and extract it to separate type reference?
Ok, I found one approach myself
import io.swagger.v3.core.jackson.ModelResolver.SET_PROPERTY_OF_ENUMS_AS_REF
init {
System.setProperty(SET_PROPERTY_OF_ENUMS_AS_REF, "any value")
}
The other way is to implement a custom ModelResolver, but the class implementation looks quite complicated
UDPATE
Just noticed, that public static boolean enumsAsRef = System.getProperty("enums-as-ref") != null; in ModelResolver is not final. So we can do even simpler
init {
io.swagger.v3.core.jackson.ModelResolver.enumsAsRef = true
}
I have an API where I post a set of object to the server, differentiated by type, where each type has some different parameters. The commands are structured like so:
{
"type": <command-name>,
"args": {
<command-specific args>
}
}
For example, these may be two possible commands:
{
"type": "Flooblinate",
"args": {
"intensity": "High",
"frequency": "Every blue moon"
}
}
{
"type": "Blagostrate",
"args": {
"temperature": 34.5,
"darkMatter": true
}
}
How can I specify this in Swagger? I can specify an enum for "type", but how do I say ""args" is one of these possible objects"?
I've checked out the docs but nothing stands out. The most promising one was allOf because it displayed nicely in the editor (pastebin, paste into the online editor):
definitions:
Product:
type: object
allOf:
- type: object
title: Flooblinate
properties:
intensity:
type: string
frequency:
type: string
- type: object
title: Blagostrate
properties:
temperature:
type: number
darkMatter:
type: boolean
Which looks like this:
However, this isn't semantically what I need, and, not surprisingly, in the online viewer (that one's not set up for my test case, not sure how to link up a local file easily), they are presented as if all the fields appear at the same time, which is of course what allOf means:
What's the proper way to represent this with Swagger?
According to input from Ron on the google group, what I want is to use the discriminator property:
definitions:
Product:
type: object
discriminator: type
properties:
type: string
required: [type]
Flooblinate:
allOf:
- $ref: '#/definitions/Product'
- type: object
properties:
intensity:
type: string
frequency:
type: string
Blagostrate:
allOf:
- $ref: '#/definitions/Product'
- type: object
properties:
temperature:
type: number
darkMatter:
type: boolean
Semantically this means what I want it to mean. I should specify $ref: '#/definitions/Product' wherever the API accepts or returns any one of Flooblinate or Blagostrate. Note this requires a field (called type here) on the objects to act as the discriminator.
I thought this may be the approach, but the tools didn't show what I expected. However:
That's because the tools are not 100% in support of the discriminator yet - however, that's the right way to describe your use case.
Once you define the discriminator in the top level model, anything that 'allOf's it will be considered a viable option, and indeed you're refer to the top level model for usage.
I was wondering: Why is the alias of new widgets we define always defined as "widget.myxtype" - what is the significance of the "widget" in that?
Alias property was newly introduced in ExtJs4 and is a substitute for "xtype" in previous versions.The "widget" specified in alias do have two significance that I can think of:
Make use of the shorthand
Code readability and understanding
You can make use of the shorthand to create a widget. For example, if you have a widget named widget.myview, you can create an instance of it as follows:
var view = Ext.widget('myview');
If you don't prefix the "widget" in alias, you can instantiate only through:
var view = Ext.create('xyz.myview');
Also, the create method can be used to create an instance of any class that has been defined using Ext.define().
when you prefix "widget", you are sure they will deal with UI. This helps in better understanding and reading of the code (when you see Ext.widget('abc'), you know its a window,button or some UI component).
Update:
alias property is used by other classes that are not UI component. But, you will see "widget" for UI components only hence denoting it as an view or UI (that is why they have the shorthand for widget alone). Other ExtJS classes also have alias. For example, all the Proxy classes will have "proxy" prefix. But for now, the only significance for the "proxy" prefix is readability.
I think it's a kind of namespace : you can also define aliases for proxies, readers and writers, which respectively need to be prefixed with 'proxy.', 'reader.' and 'writer.' :
Ext.define('App.proxy.MyProxy', {
extend: 'Ext.data.proxy.Rest',
alias: ['proxy.my_proxy'],
Ext.define('App.reader.MyReader', {
extend: 'Ext.data.reader.Json',
alias: ['reader.my_reader'],
Ext.define('App.reader.MyWriter', {
extend: 'Ext.data.writer.Json',
alias: ['writer.my_writer'],
Then you can reference them with :
proxy: {
type: 'my_proxy',
url: '/data/library_store.json',
reader: {
type: 'my_reader',
...
},
writer: 'my_writer'