Convert JSON to JSON Schema draft 4 compatible with Swagger 2.0

I've been given some JSON files generated by a REST API with plenty of properties.

I've created a Swagger 2.0 definition for this API and need to give it the corresponding schema for the response.

The main problem: this JSON file has loads of properties. It would take so much time and I would make many mistakes if I write the schema manually. And it’s not the only API I need to describe.

I know there are some tools to convert JSON to JSON schemas but, if I’m not mistaken, Swagger only has $refs to other objects definitions thus only has one level whereas the tools I’ve found only produce tree structured schemas. My question: is there any tool to convert a JSON (or JSON Schema) to a Swagger 2.0 compatible one ?

Note: I'm working in YAML but I wouldn't be an issue, would it ?

For example, what I need:

  List of Movements:
    type: "array"
    items:
      $ref: "#/definitions/Movement"
  Movement:
    properties:
      dateKey:
        type: "string"
      movement:
        $ref: "#/definitions/Stock"
    additionalProperties: false
  Stock:
    properties:
      stkUnitQty:
        type: "string"
      stkDateTime:
        type: "string"
      stkUnitType:
        type: "string"
      stkOpKey:
        type: "string"
    additionalProperties: false

For my JSON document:

[
  {
    "dateKey": "20161110",
    "stkLvls": [
      {
        "stkOpKey": "0",
        "stkUnitType": "U",
        "stkDateTime": "20161110T235010.240+0100",
        "stkUnitQty": 30
      }
    ]
  },
  {
    "dateKey": "20161111",
    "stkLvls": [
      {
        "stkOpKey": "0",
        "stkUnitType": "U",
        "stkDateTime": "20161111T231245.087+0100",
        "stkUnitQty": 21
      }
    ]
  }
  ]

But, what http://jsonschema.net/#/ gives me:

---
"$schema": http://json-schema.org/draft-04/schema#
type: array
items:
  type: object
  properties:
    dateKey:
      type: string
    stkLvls:
      type: array
      items:
        type: object
        properties:
          stkOpKey:
            type: string
          stkUnitType:
            type: string
          stkDateTime:
            type: string
          stkUnitQty:
            type: integer
        required:
        - stkOpKey
        - stkUnitType
        - stkDateTime
        - stkUnitQty
  required:
  - dateKey
  - stkLvls

I'm new to that, but curious, don't hesitate to explain deeply.

Thank you in advance for your help !

I know there are some tools to convert JSON to JSON schemas but, if I’m not mistaken, Swagger only has $refs to other objects definitions thus only has one level

You are mistaken. Swagger will respect any valid v4 JSON schema, as long as it only uses the supported subset.

The Schema Object...is based on the JSON Schema Specification Draft 4 and uses a predefined subset of it. On top of this subset, there are extensions provided by this specification to allow for more complete documentation.

It goes on to list the parts of JSON schema which are supported, and the bits which are not, and the bits which are extended by swagger.

Make schema object compatible with JSON Schema draft4 · Issue , My question: is there any tool to convert a JSON (or JSON Schema) to a Swagger 2.0 compatible one ? Note: I'm working in YAML but I wouldn't be an issue,  Swagger supports only subset of JSON Schema Draft 4. Specification of Swagger 1.2 and 2.0 states, it supports only subset of JSON Schema Draft 4 (s. here). This means, that: one cannot rely, that each valid JSON Schema can be completely supported by Swagger.

I also needed a converter tool and came across this. So far it seems to work pretty well. It does both JSON and YAML formats.

https://swagger-toolbox.firebaseapp.com/

Given this JSON (their sample):

{
  "id": 1,
  "name": "A green door",
  "price": 12,
  "testBool": false,
  "tags": [
    "home",
    "green"
  ]
}

it generated this:

{
    "required": [
        "id",
        "name",
        "price",
        "testBool",
        "tags"
    ],
    "properties": {
        "id": {
            "type": "number"
        },
        "name": {
            "type": "string"
        },
        "price": {
            "type": "number"
        },
        "testBool": {
            "type": "boolean"
        },
        "tags": {
            "type": "array",
            "items": {
                "type": "string"
            }
        }
    }
}

OpenAPI Specification, Make schema object compatible with JSON Schema draft4 #333. Closed And I didn't found any true Swagger 2.0 validator in the wild. Another problem is that That turn them into specification extensions. Next step is to  IMO Swagger model descriptions should at least use a compatible subset of JSON schema (and ideally support full JSON schema). PS considering code-generation I don't see a problem in allowing "hard" features of JSON schema, since it is already possible to create API for which generic code generation will not work (e.g. returning object with

You can directly goto https://bikcrum.github.io/Swagger-JSON-Schema-In-YAML_webversion/ for online conversion.
I wrote following python script to generate JSON schema in YAML format (preserving key order) that is used in Swagger.
import json

# input file containing json file
with open('data.json') as f:
    json_data = json.load(f)

# json schema in yaml format
out = open('out.yaml','w')

def gettype(type):
    for i in ['string','boolean','integer']:
        if type in i:
            return i
    return type

def write(string):
    print(string)
    out.write(string+'\n')
    out.flush()

def parser(json_data,indent):
    if type(json_data) is dict:
        write(indent + 'type: object')
        if len(json_data) > 0:
            write(indent + 'properties:')
        for key in json_data:
            write(indent + '  %s:' % key)
            parser(json_data[key], indent+'    ')
    elif type(json_data) is list:
        write(indent + 'type: array')
        write(indent + 'items:')
        if len(json_data) != 0:
            parser(json_data[0], indent+'  ')
        else:
            write(indent + '  type: object')
    else:
        write(indent + 'type: %s' % gettype(type(json_data).__name__))

parser(json_data,'')
Update: If you want YAML with sorted keys (which is by default) use YAML library
import json
import yaml

# input file containing json file
with open('data.json') as f:
    json_data = json.load(f)

# json schema in yaml format

def gettype(type):
    for i in ['string','boolean','integer']:
        if type in i:
            return i
    return type   

def parser(json_data):
    d = {}
    if type(json_data) is dict:
        d['type'] = 'object'
        for key in json_data:
            d[key] = parser(json_data[key])
        return d
    elif type(json_data) is list:
        d['type'] = 'array'
        if len(json_data) != 0:
            d['items'] = parser(json_data[0])
        else:
            d['items'] = 'object'
        return d
    else:
        d['type'] = gettype(type(json_data).__name__)
        return d

p = parser(json_data)
with open('out.yaml','w') as outfile:
    yaml.dump(p,outfile, default_flow_style=False)

A Guide to JSON-LD for Beginners, json . Data Types. Primitive data types in the Swagger Specification are based on the types supported by the JSON-Schema Draft 4. Models are described using  By convention, the Swagger specification file is named swagger.json. Primitive data types in the Swagger Specification are based on the types supported by the JSON-Schema Draft 4. Models are described using the Schema Object which is a subset of JSON Schema Draft 4. An additional primitive data type "file" is used by the Parameter Object and

Validating JSON with JSON Schema, -LD is within the <body> section. Google can also grasp dynamically generated tags in the DOM. JSON Schema draft 4 has patternProperties which is not supported by Swagger 2.0. patternProperties allows to have loosely defined objects where the list of keys is not fixed in the spec (like additionalProperties allows in Swagger 2.0), but the format of the keys is restricted with a regexp (contrary to additionalProperties where keys are not

A Media Type for Describing JSON Documents, How do I check if a JSON schema is valid? I am using JSON.NET Schema library to run over our assembly and create swagger schemas in json format. These are then manually referenced from our main swagger.json file. I've had 2 results:

OpenAPI Specification, For example, a valid OpenAPI 3.0.2 document, upon changing its openapi property (OAS 2.0 documents contain a top-level version field named swagger and value "2.0" .) Tags MUST be limited to those allowed by the JSON Schema ruleset. on the types supported by the JSON Schema Specification Wright Draft 00. Uses the sample JSON document to infer a JSON schema. Download Free Liquid Studio Community Edition Now! Sample JSON Document. /* Add JSON Data */ /* Add JSON Data */ Allow Anything List Validation Tuple Typing. defaultAdditionalItems. #N#defaultAdditionalProperties. #N#Infer enum values. #N#Indent character. #N#Quote character.

Comments
  • Hi Tom & thank you for the answer. On github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/… I can see that there is only one level at the definition mark. When there is a need to use other types, they make a $ref: '#/definitions/Activity' to the other type. But in JSON Schema v4, it is not compulsory. Any solution ?
  • I assume you intended to use indent instead of intend. In my experience it is better to use an integer for indentation level and at the latest possible moment do ' ' * indent (that is a string of two spaces). That way there is only one place to change if you want four space indentation. (And if you would use a YAML library, you would not have to keep track of indentation levels in the first place). Why is pprint imported? Consider using isinstance(var, dict) instead of type(var) is dict.
  • @Authon Thanks for the suggestion. I have put update where YAML library is used to convert from JSON to YAML but will not preserve key order. If it's important to preserve key order consider the first block of code where manually indenting is implemented.
  • If you need to preserve the order of keys use ruamel.yaml.(I am the author of that package): Instead of import yaml do import ruamel.yaml. Instead of d = {} do d = ruamel.yaml.comments.CommentedMap() and change the dump(...) line to two lines: yaml = ruamel.yaml.YAML() and yaml.dump(p, outfile). That should keep the ordering and blocks style. If you can't get that to work post a question here on SO and tag it yaml ruamel.yaml, then I will see it
  • That link is exactly what I was looking for! Almost 2000 lines of Swagger code later. Wish I had found it sooner :( But thanks so much!