Every webservice should have an API nowadays. That’s easier said than done, as designing an API is by far a trivial task. This article introduces JSON Schema, as a base for building webservices. I have been struggling with API’s for about 10 years. The following list show points to consider in API building. By using JSON-Schema, I finally found a descend answer to most of these:

  • Documentation
  • Changes
  • Data normalisation
  • Limits & Throttling
  • Error handling
  • Example code
  • Test environments
  • Client libraries x-language
  • Authorization / Authentication

Detailed answers and HowTo’s for each of the above will be covered in separate articles.

So what is JSON Schema?

Plain said, it describes API’s in terms of data and link structures. To quote json-schema IE draft

JSON Schema is a JSON based format for defining the structure of JSON data. JSON schema provides a contract for what JSON data is required for a given application and how to interact with it. JSON Schema is intended to define validation, documentation, hyperlink navigation, and interaction control of JSON data.

Those who struggled with XML and SOAP based web-services, know the concept of WSDL(Web Service Description Language). So the idea of structured descriptions for web-services isn’t new. But WSDL, besides it’s good concept, has not made its way into developer toolboxes. For me, beeing a medium talented programmer, it was due to complexity. A lot of different tools and KnowHow are needed and of course you screw up. I once struggled 4 days with a SOAP seat-reservation-service, before the first successful call was made .. This horrible experience taught me to stay away from SOAP based services and WSDL parsers that generate horrible code.

JSON-Schema’s innovation is simplicity. It can be read by humans, is easy to parse and does not fill books with its specification. Following a shortened example of a client object.

{
„type“:“object“,
„title“: „client“
„properties“:{ „last_name“:{ „type“:“string“,“maxLength“: 50 } },
„links“:[ { „rel“: „self“,“href“: „clients/{id}“ } ]
}

Most important is the clear division of object-properties and links, descibes in the following sections.

What are links for?

Links tells us about available actions like create, read, delete objects and can also mirror relations e.g. links to nested URL’s( nested client links examples). Links are in-depth descriptions for web-request by defining request method (POST), content type(enctype) and URL parameters.  The following link goes to a clients list with an optional search parameter ‚q‘:

{
„rel“: „instances“,
„href“: „clients“,
„method“: „GET“
„properties“ : { „q“:{ „type“:“string“ }
}
=> /clients?q=search

Links don’t care about the request body, which is good because transferred data should comply with the object definition. This ensures consistency, so whether you get a list, a single or create a client, data will always align with declared in properties.

The meat: object properties

Properties tell us about the object attributes. The client above only has „last_name“, a 50 character string. Normally there are more properties(see our client schema), even nested ones (client.addresses) referring other schemas and you will define readonly or required values. Such property descriptors are needed to overcome the restrictions of JSON, in terms of loose typing.

JSON Schema has type and format options to further describe values. For example: JSON does not know date-time values. A field, like „created_at“, is therefore declared as string with format: date-time.

„created_at“:{
„format“:“date-time“,
„type“:“string“,
„readonly“: true
}

Type describes the primitive class(string, int, number, boolean,..), format the internal markup. Both options can be extended with own classifications. Additionally you can define length, min, max or list values, giving you mostly what you need in everyday situations.

Extend to the max

Instead of defining every tiny aspect, JSON Schema leaves a lot of room for custom   definitions. A good example is a „deprecated“  flag for properties. When discussed by the community, I was favoring its standardization, but on second thought discarded it. Just think about the value of such a descriptor. Should it be a boolean (Yes its deprecated), a date(kicked after this) or a string (Why) …  It simply depends. I would even prefer multiple fields:

„created_at“:{
„deprecated_at“:“2012-05-26″
„deprecated“: „Use created_on instead“,
}

To validate a schema with custom keys, you must define them in an own schema and let other schema’s inherit it. A side note: JSON Schema itself is described by a Schema.

Extending/Inheriting is done by using the „extends“ key.

{
„title“:“my-custom-schema“,
„properties“:{„deprecated_at“:{„type“: „string“, „format“: „date“}},
„extends“:“http://json-schema.org/draft-03/schema“
}

This extension derives from the base schema but it can also inherit from multiple schema’s. Following a client schema, inheriting properties from a person and our custom definition.

{
„description“:“a client“,
„properties“:{„age“:{„minimum“: 21}},
„extends“: [„my-custom-schema“, „person“]
}

Enough theoretical Bla Bla?

You have probably seen some of the links to SalesKing’s API schema. Another good example is found in NerdPursuit -TrivialPursuit for Nerds. We define the questions in a schema and use it to validate new submissions.
While i am working on further articles, also take a look at our API-Explorer, which is simply reading our schema’s.