Describe a multiple range parameter with Swagger - swagger

I want to describe in Swagger 2.0 a parameter defined as follows :
The parameter takes a valid value in the intervals : -20 < parameter < -10 or 0 < parameter < 30
The parameter is invalid if : -10 ≤ parameter ≤ 0
This means that it has two valid intervals and thus two max and mins values to define.
Does Swagger specification support that kind of definitions?

This cannot be described in OpenAPI/Swagger 2.0, but can be described in OpenAPI 3.x using oneOf.
OpenAPI 3.0
type: integer
oneOf:
- minimum: -20
maximum: -10
exclusiveMinimum: true
exclusiveMaximum: true
- minimum: 0
maximum: 30
exclusiveMinimum: true
exclusiveMaximum: true
OpenAPI 3.1
type: integer
oneOf:
- exclusiveMinimum: -20
exclusiveMaximum: -10
- exclusiveMinimum: 0
exclusiveMaximum: 30
exclusiveM* keywords were changed from boolean to numbers in JSON Schema Draft 6. OAS 3.1 uses JSON Schema 2020-12 by default.

Related

What's the maximum number for float on Rails validation?

I have the following validation:
class Metrics
validates :verbs_count, allow_nil: true, numericality: { greater_than_or_equal_to: 1, less_than_or_equal_to: ? }
end
I would like to know what would be the maximum value of a float without losing precision. I know it seems like a question that should be easy to find an answer, but I'm not finding it.
As per the docs (which are not in https://api.rubyonrails.org/ pages, but in the code in master):
Validates whether the value of the specified attribute is numeric by
trying to convert it to a float with Kernel.Float (if only_integer
is false) or applying it to the regular expression /\A[\+\-]?\d+\z/
(if only_integer is set to true).
Precision of Kernel.Float values are guaranteed up to 15 digits.
The answer you're looking for is maybe here: "Precision of Kernel.Float values are guaranteed up to 15 digits" - as there's not a maximum number, then you can use whatever you want, just having in mind that greather numbers will loose precision.

How to use common schema with different descriptions in OpenAPI 3.0? [duplicate]

I'm trying to build a Swagger model for a time interval, using a simple string to store the time (I know that there is also datetime):
definitions:
Time:
type: string
description: Time in 24 hour format "hh:mm".
TimeInterval:
type: object
properties:
lowerBound:
$ref: "#/definitions/Time"
description: Lower bound on the time interval.
default: "00:00"
upperBound:
$ref: "#/definitions/Time"
description: Upper bound on the time interval.
default: "24:00"
For some reason the generated HTML does not show the lowerBound and upperBound "description", but only the original Time "description". This makes me think I'm not doing this correctly.
So the question is if using a model as a type can in fact be done as I'm trying to do.
TL;DR: $ref siblings are supported (to an extent) in OpenAPI 3.1. In previous OpenAPI versions, any keywords alongside $ref are ignored.
OpenAPI 3.1
Your definition will work as expected when migrated to OpenAPI 3.1. This new version is fully compatible with JSON Schema 2020-12, which allows $ref siblings in schemas.
openapi: 3.1.0
...
components:
schemas:
Time:
type: string
description: Time in 24 hour format "hh:mm".
TimeInterval:
type: object
properties:
lowerBound:
# ------- This will work in OAS 3.1 ------- #
$ref: "#/components/schemas/Time"
description: Lower bound on the time interval.
default: "00:00"
upperBound:
# ------- This will work in OAS 3.1 ------- #
$ref: "#/components/schemas/Time"
description: Upper bound on the time interval.
default: "24:00"
Outside of schemas - for example, in responses or parameters - $refs only allow sibling summary and description keywords. Any other keywords alongside these $refs will be ignored.
# openapi: 3.1.0
# This is supported
parameters:
- $ref: '#/components/parameters/id'
description: Entity ID
# This is NOT supported
parameters:
- $ref: '#/components/parameters/id'
required: true
Here're some OpenAPI feature requests about non-schema $ref siblings that you can track/upvote:
Allow sibling elements with $ref that overrides the references definition
Allow required as sibling of $ref (like summary/description)
Extend/override properties of a parameter
OpenAPI 2.0 and 3.0.x
In these versions, $ref works by replacing itself and all of its sibling elements with the definition it is pointing at. That is why
lowerBound:
$ref: "#/definitions/Time"
description: Lower bound on the time interval.
default: "00:00"
becomes
lowerBound:
type: string
description: Time in 24 hour format "hh:mm".
A possible workaround is to wrap $ref into allOf - this can be used to "add" attributes to a $ref but not override existing attributes.
lowerBound:
allOf:
- $ref: "#/definitions/Time"
description: Lower bound on the time interval.
default: "00:00"
Another way is to use replace the $ref with an inline definition.
definitions:
TimeInterval:
type: object
properties:
lowerBound:
type: string # <------
description: Lower bound on the time interval, using 24 hour format "hh:mm".
default: "00:00"
upperBound:
type: string # <------
description: Upper bound on the time interval, using 24 hour format "hh:mm".
default: "24:00"

How to model decimal type in RAML

I am modelling a REST API using RAML. The response body of an endpoint (JSON format) is a financial transactions list. Each transactions contains an amount of money: currency and numeric value. The following is the snippet of my RAML file, please note the property amount in the Transaction type:
# %RAML 1.0
title: Trading details API
version: v1
mediaType: application/json
baseUri: http://my.host.io/api/trading/v1/
types:
Transactions:
type: Transaction[]
minItems: 1
Transaction:
type: object
properties:
refNum:
type: string
amount:
type: ????
currency:
type: string
minLength: 2
maxLength: 3
/trades
get:
description: Get details for a given trade
queryParameters:
userId:
type: integer
required: true
responses:
200:
body:
application/json:
type: Transactions
Unfortunately RAML has no Built-in decimal type, and the other numeric types (integer, float or double) are not suitable for this scope, mainly because I need to specify the number of digits after the . .
So question is: in RAML how do I correctly model the type amount?
I need to provide an exact definition of the type for each response body values, because this file will be the contract between the backend and frontend (developed by 2 different teams).
Any helps is welcomed.
Please note that I made some research on SO, and the closest question to mine is: How to define money amounts in an API
. But it is not related to RAML modelling, and the answers are not helping to me.
RAML has a similar construct to the one in JSON Schema. You'll want to use type: number in combination with multipleOf to describe decimal precision.
#%RAML 1.0 DataType
type: number
multipleOf: 0.01
After months I come back to share my experience.
The way I worked around it was by using the type string and a pattern. I am aware of the many concerns around changing the data type from number to string, but this approach is elegant, robust, flexible and still simple to test and understand.
The API consumers are forced to format the amount in the correct way and the messages coming in and out of the API are consistent, consistency cannot be guaranteed by using multiplyOf 0.0001 (where 25 and 25.0000 are both accepted).
I reused over and over this solution with great results. Therefore I am sharing this with the community.
Solution:
[...]
amount:
type: string
pattern: "^(([1-9][0-9]*)|[0])[.]([0-9]{4})$"
currency:
type: string
...
The pattern accepts 4 digits on the decimal part, forces to use a . and the amount cannot starts with 0, with the exception of 0.xxxx family of numbers.
The following is an examples list of accepted numbers:
1.0000
54.0000
23456.1234
1.9800
0.0000
0.0001
Instead the following is an example list of rejected:
0123.3453
12.12
1.1
000
01.0000
1.0
1.00
4.000
Moreover, you can specify the max number of digits on the left side (in this example 10):
pattern: "^(([1-9][0-9]{0,9})|[0])[.]([0-9]{4})$"
Example of accepted numbers:
1234567890.1234
3.5555
0.1234
Example of rejected numbers:
12345678901.1234
123456789012.1234

In swagger, is there a recommended way to document a number field with a length limit?

We have some numeric fields, that for legacy reasons have implicit length limits.
Given a number field with a length limit of 5, the obvious route is to set the max to 99999, but then is there any way to specify that 1.111 is ok, and 1.1111 is not, in the swagger spec?
For example:
numberField:
type: number
format: float
minimum: 0
maximum: 99999
Yes, you have to use the property maxLength
numberField:
type: number
format: float
maxLength: 5

Length validation on Rails - which one is the best?

I am coding the validation of my app and want to know if there's any difference (security and/or speed) between the use of
length: { minimum: 5, maximum: 30 } and length: 5..30, for example.
Sorry if this had already been asked...
Thank you!
There's no difference in performance because they mean the same thing. The range syntax
length: 5..30
is simply shorthand for an array containing the numbers 5 through 30
length: [5,6,7,...30].to_a
You can also use the minimum and maximum attributes to declare a range.
length: { minimum: 5, maximum: 30 }
Check out the documentation here
http://guides.rubyonrails.org/active_record_validations.html#length
:minimum - The attribute cannot have less than the specified length.
:in (or :within) - The attribute length must be included in a given interval. The value for this option must be a range.
It comes down to preference. The range syntax saves you keystrokes. But there's no difference in performance. You can see for yourself with benchmark.

Resources