TypeSchema

TypeSchema is a JSON format to describe JSON structures. It helps to build schemas which are optimized for code generation. TypeSchema is compatible with JSON Schema and every TypeSchema is automatically a valid JSON Schema but not vice versa.

Specification Generator

Why

You might question: Why not use JSON Schema?

For code generators it is difficult to work with JSON Schema. In JSON Schema you dont need to provide any keywords i.e. {} is a valid JSON Schema which basically allows every value and the defined keywords are applied based on the actual data. A code generator on the other hand needs to determine a concrete type of a schema without the actual data. Also JSON Schema has many keywords which contain logic like dependencies, not, if/then/else which are basically not needed for code generators and really complicate building them. We have also explained some pitfalls in our migration document.

Because of the need for a better schema specification which is optimized for code generation we have developed TypeSchema. TypeSchema is an alternative to JSON Schema, basically it is a more stricter subset of JSON Schema which allows you to write clean schemas which can be easily turned into code. Every TypeSchema which you write is automatically also a valid JSON Schema bot not vice versa. Since this specification removes and restricts only keywords TypeSchema is compatible down to JSON Schema draft-04. Therefor all your tools will work with a TypeSchema. You can think of TypeSchema is to JSON Schema what TypeScript is to Javascript.

Who

We are developers coming from a classical OOP background. Back in the days we have worked with WSDL/XSD and experienced the advantages of automatically generating client code. We think OpenAPI is a great replacement for WSDL but the schema definition part is not perfect yet. This project is a voice for all tool developers who like to have a more strict schema specification. If you want to support the project or want to provide feedback feel free to visit us on GitHub.

Overview

In TypeSchema you must define a Root schema which must be of type object. This object must contain specific Properties. The Definitions keyword contains a list of schemas which can be reused.

In TypeSchema every schema can be assigned to exactly one specific type based on the used keywords. The following list shows all available types:

Struct

A struct contains a fix set of defined properties.
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string"
    },
    "createDate": {
      "type": "string",
      "format": "date-time"
    }
  }
}

Map

A map contains variable key value entries of a specific type.
{
  "type": "object",
  "additionalProperties": {
    "type": "string"
  }
}

Array

An array contains an ordered list of a specific type.
{
  "type": "array",
  "items": {
    "type": "string"
  }
}

Boolean

Represents a boolean value.
{
  "type": "boolean"
}

Number

Represents a number value (contains also integer).
{
  "type": "number",
  "minimum": 12
}

String

Represents a string value.
{
  "type": "string",
  "minLength": 12
}

Intersection

An intersection type combines multiple schemas into one.
{
  "allOf": [{
    "$ref": "#/definitions/Person"
  }, {
    "$ref": "#/definitions/Student"
  }]
}

Union

An union type can contain one of the provided schemas.
{
  "oneOf": [{
    "$ref": "#/definitions/Car"
  }, {
    "$ref": "#/definitions/Train"
  }]
}

Reference

Represents a reference to another schema.
{
  "$ref": "#/definitions/Car"
}

Generic

Represents a generic type.

**NOTE: This is a TypeSchema specific feature which is not available in JSON Schema so use it only if you use a schema processor which supports TypeSchema**

Through the $generic keyword it is possible to define a schema placeholder. I.e. if you want to reuse a collection schema with different entries:

{
  "type": "object",
  "properties": {
    "totalResults": {
      "type": "integer"
    },
    "itemsPerPage": {
      "type": "integer"
    },
    "entries": {
      "$generic": "T"
    }
  }
}

Through the $template keyword it is possible to insert a concrete schema to the placeholder.

{
  "$ref": "#/definitions/Map",
  "$template": {
    "T": {
      "$ref": "#/definitions/News"
    }
  }
}