16

The API for which I'm writing a Swagger 2.0 specification is basically a store for any JSON value.

I want a path to read value and a path to store any JSON values (null, number, integer, string, object, array) of non-predefined depth.

Unfortunately, it seems that Swagger 2.0 is quite strict on schemas for input and output and does not allow the whole set of schemas allowed by JSON Schema. The Swagger editor doesn't allow for example mixed values (for example a property that can be either a boolean or an integer) or loosely defined arrays (the type of items must be strictly defined) and objects.

So I'm trying a workaround by defining a MixedValue schema:

---
swagger: '2.0'
info:
  version: 0.0.1
  title: Data store API
consumes:
- application/json
produces:
- application/json
paths:
  /attributes/{attrId}/value:
    parameters:
    - name: attrId
      in: path
      type: string
      required: true
    get:
      responses:
        '200':
          description: Successful.
          schema:
            $ref: '#/definitions/MixedValue'
    put:
      parameters:
      - name: value
        in: body
        required: true
        schema:
          $ref: '#/definitions/MixedValue'
      responses:
      responses:
        '201':
          description: Successful.
definitions:
  MixedValue:
    type: object
    properties:
      type:
        type: string
        enum:
        - 'null'
        - boolean
        - number
        - integer
        - string
        - object
        - array
      boolean:
        type: boolean
      number:
        type: number
      integer:
        type: integer
      string:
        type: string
      object:
        description: deep JSON object
        type: object
        additionalProperties: true
      array:
        description: deep JSON array
        type: array
    required:
    - type

But the Swagger Editor refuses the loosely defined object and array properties.

Questions: - Is there a way to workaround this issue? - Is it just a Swagger Editor bug or a strong limit of the Swagger 2.0 spec? - Is there a better way (best practice) to specify what I need? - Can I expect some limitations in code produced by swagger for some languages with my API spec?

dolmen
  • 8,126
  • 5
  • 40
  • 42

2 Answers2

30

An arbitrary-type schema can be defined using an empty schema {}:

# swagger: '2.0'
definitions:
  AnyValue: {}

# openapi: 3.0.0
components:
  schemas:
    AnyValue: {}

or if you want a description:

# swagger: '2.0'
definitions:
  AnyValue:
    description: 'Can be anything: string, number, array, object, etc. (except `null`)'

# openapi: 3.0.0
components:
  schemas:
    AnyValue:
      description: 'Can be anything: string, number, array, object, etc., including `null`'

Without a defined type, a schema allows any values. Note that OpenAPI 2.0 Specification does not support null values, but some tools might support nulls nevertheless.

In OpenAPI 3.0, type-less schemas allow null values unless nulls are explicitly disallowed by other constraints (such as an enum).

See this Q&A for more details on how type-less schemas work.


Here's how Swagger Editor 2.0 handles a body parameter with the AnyValue schema:

SwaggerEditor: Testing a PUT request with an arbitrary-type body

I don't know how code generators handle this though.

Helen
  • 87,344
  • 17
  • 243
  • 314
  • 1
    This is exactly the solution I found by myself 1.5 years ago: I've defined a schema called `AnyJSON` to document this in [my spec](http://developers.ijenko.com/api-reference/#!/Functionality/Functionality_value). – dolmen Apr 13 '17 at 07:32
  • 3
    To clarify a little, `{}` is a YAML way of defining a property with an empty value, not something particularly special to this. It's the lack of a `type` property that indicates the arbitrary type schema. – M. Justin Sep 20 '21 at 15:38
0

Maybe this is what your are looking for "Patterned Objects":

Field Pattern: ^x-

Type: Any

Description: Allows extensions to the Swagger Schema. The field name MUST begin with x-, for example, x-internal-id. The value can be null, a primitive, an array or an object. See Vendor Extensions for further details.

Source: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md

David Lopez
  • 2,127
  • 1
  • 10
  • 7
  • 2
    Vendor extensions (properties starting with `x-`) are in the spec just to put anything you want. But most code generators and doc generators will not recognize them. Using vendor extensions is just forking the Swagger spec and requires forking generators, so this reduces the benefit of using Swagger. But this is what I will ulitmately do as there is no pure-Swagger solution. – dolmen Oct 01 '15 at 07:57
  • I don't like it a lot, but I didn't know a better official solution, I'm sorry – David Lopez Oct 01 '15 at 08:27