Swagger Definition of primitive types - rest

Is it possible to define a swagger definition/model for a primitive type? For instance, consider the following
definitions:
program_name:
type: string
description: Unique string id
However, the above example comes back with many errors (swagger expects a properties field for example) and no examples employ any definition that is not of type: object.
The intention is to use this as a subcomponent to another model as well as a parameter -- to reuse the already defined component in some way.
Think of this as a swagger typedef
EDIT: According to the spec, a definition object is the same as a schema object http://swagger.io/specification/#schemaObject, which states that it can accept primitive types.
Also, assuming that primitive types can exist in the definitions section, could simple parameter types (query, path etc.) reference primitive definition types?

A primitive schema as in your example is valid and can be used in whenever a Schema object is expected, for example, as a subcomponent of another schema:
definitions:
Program:
type: object
properties:
program_name:
$ref: "#/definitions/program_name"
# This becomes:
# type: object
# properties:
# program_name:
# type: string
# description: Unique string id
or as an operation body parameter or response schema:
paths:
/something:
post:
summary: POSTs and returns a string
parameters:
- in: body
name: program_name
schema:
$ref: "#/definitions/program_name"
responses:
"200":
description: OK
schema:
$ref: "#/definitions/program_name"
However, simple parameters - path, query, header and form - do not use the schema keyword (they use type instead) and so they cannot reference schemas from definitions.
This will be changed in the next version, OpenAPI 3.0, where schema will be used for all parameter types.

Related

How to create Crystal language Hash where values can be any type?

I'm working on representing an API where a response contains a hash where the keys are of type String and the values can be of any type. Is there a way to represent this in Crystal?
I did not see a way to represent this looking through Crystal docs on types:
https://crystal-lang.org/reference/1.6/syntax_and_semantics/literals/index.html
https://crystal-lang.org/reference/1.6/syntax_and_semantics/literals/hash.html
In OpenAPI Spec, this is described as a free-form object:
https://swagger.io/docs/specification/data-models/dictionaries/#free-form
Free-Form Objects
If the dictionary values can be of any type (aka free-form object), use additionalProperties: true:
type: object
additionalProperties: true
This is equivalent to:
type: object
additionalProperties: {}
In Go, this would be represented as map[string]any or map[string]interface{}.
Given that everything is an object in Crystal, the following compiles for me:
Hash(String, Object)
Everything is an object
In Crystal everything is an object. The definition of an object boils down to these points:
It has a type
It can respond to some methods
This is everything you can know about an object: its type and whether it responds to some method.
An object's internal state, if any, can only be queried by invoking methods.
Ref: https://crystal-lang.org/reference/1.6/syntax_and_semantics/everything_is_an_object.html

In OpenAPI, can I use a regular schema component as a parameter?

I have an endpoint defined in my API that takes a path parameter.
The valid values for that parameter are already expressed as an enum, which I've defined as a schema component and used in a response.
Two questions:
If you can just use a reference to that schema component as the parameter, why ever set up dedicated parameter components instead of using a generic schema component that you can re-use anywhere?
If you should use parameters instead of generic schemas, can you create a parameter component that refers to a schema component? I can't find any syntax to do this that passes validation.
I'd paste my definitions here but I can't find any formatting option that doesn't make a hideous mess.
If you can just use a reference to that schema component as the parameter, why ever set up dedicated parameter components instead of using a generic schema component that you can re-use anywhere?
Parameter definitions have additional attributes not present in schemas, such as the parameter location in the request (in: path, in: query, etc.), serialization method for array and object values, and others. A schema is just one of the parameter attributes, but a schema alone does not provide enough information to effectively describe a parameter.
can you create a parameter component that refers to a schema component?
Yes. Parameters have a schema, it can be an inline schema or a $ref:
paths:
/something/{role}:
get:
parameters:
- $ref: '#/components/parameters/role'
...
components:
parameters:
role:
in: path
name: role
required: true
schema:
$ref: '#/components/schemas/UserRole' # <-----
schemas:
UserRole:
type: string
enum: [user, admin]

Define array in Swagger OpenAPI annotation

I`m using Swagger Editor with OpenAPI 3.0, and I installed swagger-php library. Now I have a php function with one of its parameter as array, such as:
array[(1,2),(2,3),(6,9)]
How do I write up the annotation of this array in order to call this function.
There are different solutions. I would suggest to implement it with with arrays of objects as it stands in documentation.
arrayOfObjects
description: 'basic array of objects in OpenAPI'
type: array
items:
type: object
properties:
num:
type: integer
More info please find here:
Data Types - Arrays

Which is the correct way to restrict openapi type in properties?

I have the following so far:
Links:
description: Must contain links objects
type: object
properties:
$ref: "#/components/schemas/Link"
ErrorLinks:
allOf:
- $ref: "#/components/schemas/Links"
- properties:
about:
$ref: "#/components/schemas/Link"
In Links, I don't care what the names of any properties are, just that they are all Link objects. In ErrorLinks, I expect there to be an about property, which is also an Link object.
Is this the correct way to define that, or am I saying (in Links) that I expect the properties node itself to be a Link object?
I find the openapi documentation a little lacking in helpful examples and the above validates, so I am not entirely sure.
In Links, I don't care what the names of any properties are, just that they are all Link objects.
Links is a dictionary (hashmap) then. Dictionaries are defined using additionalProperties, as explained in this answer:
Links:
description: Must contain links objects
type: object
additionalProperties:
$ref: "#/components/schemas/Link"
In ErrorLinks, I expect there to be an about property, which is also an Link object.
You are almost there. There's no need for allOf, you just need a simple object schema:
ErrorLinks:
type: object
properties:
about:
$ref: "#/components/schemas/Link"
required:
- about

Alternate fields in HTTP POST request body

I've been looking for the best way to specify a body type for an HTTP POST request that has two fields that are mutually exclusive.
I'm using swagger for the API specification, and I have one request that must have either field_A or field_B, but not both.
Right now I am setting both fields as optional, describing the behaviour in the spec (when to set one field or the other), and validating the input on the server. If none of the fields is filled I am returning a 400-Bad-request.
My question is whether or not this is the correct approach (would it be more RESTful if I specify an extra content-type?), or if there is something in Swagger that allows me to make this behaviour more obvious.
I came across an API that solved my issue.
For a given field, the type for that field is extensible (like a base class, and multiple extending classes). To distinguish between the different sub-types there is a discriminator field.
For example (YAML in swagger format), type Foo is extensible and has subtypes FooA and FooB. The discriminator is a type field:
definitions:
Foo:
type: object
properties:
type: string
x-extensible-enum:
- FOO_A
- FOO_B
discriminator: type
required:
- type
FOO_A:
allOf:
- $ref: '#/definitions/Foo'
- type: object
properties:
field_a:
type: string
required:
- field_a
FOO_B:
allOf:
- $ref: '#/definitions/Foo'
- type: object
properties:
field_b:
type: integer
format: int32
required:
- field_b
This makes deserialisation more complex, but it's a quite interesting approach and very flexible.