This document is a proposal of Markdown syntax for JSON & JSON Schema.
MSON is a plain text, human and machine readable, description format for common markup formats such as JSON, XML or YAML.
The aim of this description format is to facilitate the discussion (and thus validation) of data structures. The format, being agnostic to the common markup formats, suites well the "resource & representations" and "content negotiation" scenarios.
In addition this format also offers (limited) serialization functionality.
Similarly to the original Markdown to HTML (markup) conversion the Markdown Syntax for Object Notation (hereafter MSON) enables a conversion to other markup formats.
This format is being developed by @zdne at Apiary as a part of API Blueprint syntax to provide a means for description and validation of HTTP payloads, DRY media-type agnostic resource descriptions and to simplify content-negotiation.
NOTE: While this document focuses primarily on JSON and JSON Schema it MUST be possible to produce an XML or YAML representation from the MSON as well.
{
"id": 1,
"name": "A green door",
"price": 12.50,
"tags": ["home", "green"]
}
- id: 1
- name: A green door
- price: 12.50
- tags: home, green
- id: 1
- name: A green door
- price: 12.50
- tags: home, green
NOTE: Escaping question? Look here.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"id": {
"description": "The unique identifier for a product",
"type": "number"
},
"name": {
"description": "Name of the product",
"type": "string"
},
"price": {
"type": "number"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": ["id", "name", "price"]
}
# Product
A product from Acme's catalog
## Properties
- id: 1 (number, required) - The unique identifier for a product
- name: A green door (string, required) - Name of the product
- price: 12.50 (number, required)
- tags: home, green (array: string)
A product from Acme's catalog
- id: 1 (number, required) - The unique identifier for a product
- name: A green door (string, required) - Name of the product
- price: 12.50 (number, required)
- tags: home, green (array: string)
NOTE: In addition to the above schema the source MSON also captures the serialized data of the original JSON!
NOTE: This proposal covers only basic features of JSON Schema. At this moment it is out of the scope of this syntax to support all the JSON Schema keywords (such as
uniqueItems
,exclusiveMinimum
etc.).
NOTE: Optional is the default for a property. Use
required
for required properties.
- Primitive types
- Composite Types
- Objects & Arrays
- Advanced Objects
- Advanced Arrays
- Escaping
- Mutliline Description
- Variable Property Name
- MSON Entity Definition
- Referencing
- Mixins
Following are the primitive data types of MSON entities:
- bool (boolean)
- number
- string
MSON entity types composed of one or more other types are
-
array
-
object
-
one of
The one of type represent a choice of types for an MSON entity value. The types are mutually exclusive.
- property (one of)
- (number)
- (string)
By default, a Markdown list item is considered to be an object property:
{
"address" : {
"street": null,
"city": null,
"state": null
}
}
- address
- street
- city
- state
If a markdown list items are literals (represent array values), the type of parents property must be explicitly set to array:
{
"address": ["street", "city", "state"]
}
- address (array)
- street
- city
- state
Or, perhaps preferably:
- address: street, city, state (array)
In this case, the type – (array)
– can be omitted.
A Property which value can be of different types is defined of the one of
composite type:
{ "tag": "green" }
or
{ "tag": { "tag_id": 1, "label": "green" } }
- tag (one of)
- green (string)
- (object)
- tag_id: 1
- label: green
- tag (one of)
- green (string)
- (object)
- tag_id: 1
- label: green
By default all properties are optional and can be included in the object (any of). If there is a choice of available properties use the One of
keyword:
{ "a": null, "b1": null, "c": null }
or
{ "a": null, "b2": null, "c": null }
- a
- One of
- b1
- b2
- c
- a
- One of
- b1
- b2
- c
{ "tags": ["hello", 42] }
- tags (array)
- hello (string)
- 42 (number)
- tags (array)
- hello (string)
- 42 (number)
[{ "name": "snow", "description": null }, 42]
- (array)
- (object)
- name: snow (string)
- description (string)
- 42 (number)
- (array)
- (object)
- name: snow (string)
- description (string)
- 42 (number)
- (object)
[[1, 2, 3, 4]]
- (array)
- 1, 2, 3, 4 (array: number)
- (array)
- 1, 2, 3, 4 (array: number)
Markdown code span element syntax (` `
) is used to escape properties and literals when needed. The use of code span is optional unless needed.
Element values and property names and values with reserved characters or containing keywords MUST be escaped.
:
, (
,)
, <
, >
, {
, }
, [
, ]
, _
, *
, -
, `
Keywords are case insensitive:
Element
, Elements
, Property
, Properties
, Choice
, Choices
One of
, Include
Following keywords are reserved for future use:
Trait
, Traits
, Parameter
, Parameters
, Attribute
, Attributes
, Filter
, Validation
- `id`: `1`
- `name`: `A green door`
- `price`: `12.50`
- `tags`: `home`, `green`
id
:1
name
:A green door
price
:12.50
tags
:home
,green
In the case where one-liner description is not enough a mutli-paragraph list item is the way to go.
- id: 1 (required, number) - The unique identifier for a product
- name: A green door (required, string)
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed sed lacus a arcu vehicula ultricies sed vel nibh. Mauris id cursus felis.
Interdum et malesuada fames ac ante ipsum primis in faucibus.
- unus
- duo
- tres
- quattuor
- price: 12.50 (required, number)
- tags: home, green (array)
For multi-line description of an array or object the Elements
or Properties
keyword is needed to avoid any possible clash with potential description list items:
- tags (array)
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed sed lacus a arcu vehicula ultricies sed vel nibh. Mauris id cursus felis.
Interdum et malesuada fames ac ante ipsum primis in faucibus.
- unus
- duo
- tres
- quattuor
- Elements
- home
- green
Variable property name (key) is defined using braces {}
. Note a variable property can't be required.
{
"_links" {
"self": {
"href": "an uri"
}
}
}
- _links
- {self}
- href: an uri
- _links
- {self}
- href: an uri
- {self}
Additionally a variable property name can specify its key type:
{
"1": "1",
"2": "2",
"3": "Fizz",
"4": "4",
"5": "Buzz"
}
- {(number)} (string) - FizzBuzz number & answer pair
- {(number)} (string) - FizzBuzz number & answer pair
Top-level, MSON entity definition that can be referenced, is defined using a Markdown header. A form of markdown headed is also used for entity-level keywords:
# Address (object)
Description is here! Properties to follow.
## Properties
- street
- state
- zip
The same entity defined as a content of the Address
property:
- Address (object)
Description is here! Properties to follow.
- Properties
- street
- state
- zip
Anywhere a type is expected, a top-level MSON entity can be referenced. At its simplest an MSON entity is referenced by its name only.
Consider following JSON:
{
"fist_name": null,
"last_name": null,
"address": {
"street": null,
"city": null,
"state": null,
"zip": null
}
}
# Address (object)
- street
- city
- state
- zip
# User (object)
- fist_name
- last_name
- address (Address)
- street
- city
- state
- zip
- fist_name
- last_name
- address (Address)
However both []()
and [][]
Markdown syntax are supported:
# User (object)
- fist_name
- last_name
- address ([Address](#address-object))
# User (object)
- fist_name
- last_name
- address ([Address][])
To include (mixin) object properties in another object use the Include
keyword followed by a reference to the object MSON entity.
{
"fist_name": null,
"last_name": null,
"street": null,
"city": null,
"state": null,
"zip": null
}
# Address Object
- street
- city
- state
- zip
# User Object
- fist_name
- last_name
- Include [Address]()
- street
- city
- state
- zip
- fist_name
- last_name
- Include Address