Today we’re making an important piece of Platform API tooling available: A machine-readable JSON schema that describes what resources are available via the API, what their URLs are, how they are represented and what operations they support. The schema opens up many interesting use cases, both for users and for us at Heroku working on improving and extending the API. A few examples are:
- Auto-creating client libraries for your favorite programming language
- Generating up-to-date reference docs
- Writing automatic acceptance and integration tests
We are already using the schema to maintain the API reference documentation on Dev Center and to generate several v3 client libraries:
- Heroics for Ruby
- node-heroku-client
- heroku.scala
- and heroku-go
Of these, Heroics is officially supported by Heroku and the other three are community projects created by Heroku engineers. If you find bugs or have suggestions for enhancements, please send a pull request. We’re interested in having even more client libraries and hope hackers in the Heroku community will start building libs for other languages, either auto-generated ones using JSON Schema or hand-written ones.
How to use the Schema
The API serves up its own JSON-formatted schema using HTTP:
$ curl https://api.heroku.com/schema -H "Accept: application/vnd.heroku+json; version=3"
{
"description": "The platform API empowers developers to automate, extend and combine Heroku with other services.",
"definitions": {
…
}
}
Let’s take a closer look at the schema definition for the app object (edited for brevity):
"app": {
"description": "An app represents the program that you would like to deploy and run on Heroku.",
...
"definitions": {
"name": {
"description": "unique name of app",
"example": "example",
"pattern": "^[a-z][a-z0-9-]{3,30}$",
"type": [
"string"
]
}
},
"links": [
{
"description": "Create a new app.",
"href": "/apps",
"method": "POST",
"rel": "create",
"schema": {
"properties": {
"name": {
"$ref": "#/definitions/app/definitions/name"
}
}
},
"title": "Create"
}
],
"properties": {
"name": {
"$ref": "#/definitions/app/definitions/name"
}
}
}
From the schema, we can surmise that the app object has a name
property of type string
. We even get a regex describing acceptable values for the name property.
The “links” element describes the methods available on the app object. The sample above only includes the POST
method used to create a new app. The link object includes a schema
property that shows that specifying a name
property is optional when creating an app.
Feel free to explore the full schema to see what other information is available and check out the Heroics README and source code for ideas on how to use it.
JSON Schema
When deciding on a format to describe and document the API, we had the following requirements:
- JSON-based, like the rest of the content served by the API
- Clean and simple enough to allow human perusal
- Expressive enough to facilitate generating documentation and client libraries
As much as possible, we also wanted the format to be based on open standards to allow re-use of existing code and tooling.
WSDL and its cousin WADL are probably the most well-known mechanisms for describing web services. They weren’t appropriate for Heroku’s API, however: WSDL is XML-based, complicated and rather verbose.
Instead, we settled on JSON Schema for the base format. Combined with the draft Validation and Hypertext extensions, we had the expressiveness required to meet our design objectives with a JSON format.
As a bonus, both Swagger and the Google API discovery service are built on JSON Schema and it’s a fairly well-established standard with lots of tooling and other resources already available.
Summary
Publishing a machine-readable schema for your API is good practice: It makes keeping docs up to date easier and it greatly simplifies maintenance of up-to-date client libraries. We think JSON Schema is a solid foundation for describing APIs and we will continue to invest in the format and it’s extensions and in relevant tooling that make using APIs easier.
We also hope the Heroku community will take advantage of the API schema to build and contribute to clients and tools in addition to the ones we release today. Our goal is to make the Platform API easy to consume from a wide variety of languages and frameworks.
If you come up with something cool and want to tell us about it then drop us a line on api-feedback@heroku.com.