This document describes the TypeAPI specification. The TypeAPI specification defines a JSON format to describe REST APIs for type-safe code generation.
x-www-form-urlencoded
For a long time the OpenAPI community was divided into two communities, one building documentation tools and the other trying to build code generation tools. Building documentation tools has very different requirements than building code generation tools. For a documentation tool you can simply render and show all defined endpoints and constraints, a code generation tool on the other side needs to understand the structure and relations of your model.
The OpenAPI specification has moved more and more to the documentation community by directly integrating JSON Schema into the specification. The problem with JSON Schema and code generation is, that JSON Schema is a constraint system, based on such constraints it is very difficult or impossible to build a clean code generator since the constraints only define what is not allowed. For a code generator you like to have a schema which explicit models your data structure.
With TypeAPI we want build a new home for the code generation community. Conceptual the main difference is that with OpenAPI you describe routes and all aspects of a route, at TypeAPI we describe operations, an operation has arguments and those arguments are mapped to values from the HTTP request. Every operation returns a response and can throw exceptions which are also mapped to an HTTP response. An operation basically represents a method or function in a programming language. This approach makes it really easy to generate complete type safe code.
Every TypeAPI has a Root definition. The
Root must contain at least the operations
and definitions
keyword i.e.:
{
"operations": {
"getMessage": { ... },
},
"definitions": {
"TypeA": { ... },
"TypeB": { ... }
}
}
The operations
keyword contains a map containing Operation
objects. The key represents the identifier of this operation, through the dot notation i.e. user.getMessage
you can group your
operations into logical units.
{
"operations": {
"getMessage": {
"description": "Returns a hello world message",
"method": "GET",
"path": "/hello/world",
"return": {
"schema": {
"$ref": "Hello_World"
}
}
}
},
"definitions": {
"Hello_World": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
Every operation can define a return type. In the above example the operation simply returns a Hello_World
object.
Through arguments
keywords you can map values from the HTTP request to specific method arguments. In
the following example we have an argument status
which maps to a query parameter and an argument
payload
which contains the request payload.
{
"operations": {
"insertMessage": {
"description": "Inserts and returns a hello world message",
"method": "POST",
"path": "/hello/world",
"arguments": {
"status": {
"in": "query",
"schema": {
"type": "integer"
}
},
"payload": {
"in": "body",
"schema": {
"$ref": "Hello_World"
}
}
},
"return": {
"schema": {
"$ref": "Hello_World"
}
}
}
},
"definitions": {
"Hello_World": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
This would map to the following HTTP request.
POST https://api.acme.com/hello/world?status=2
Content-Type: application/json
{
"message": "Hello"
}
Besides the return type an operation can return multiple exceptional states in case an error occurred. Every
exceptional state is then mapped to a specific status code i.e. 404
or 500
. The generated
client SDK will then throw a fitting exception containing the JSON payload in case the server returns such an error
response code. The client will either return the success response or throw an exception. This greatly simplifies error
handling at your client code.
{
"operations": {
"getMessage": {
"description": "Returns a hello world message",
"method": "POST",
"path": "/hello/world",
"return": {
"schema": {
"$ref": "Hello_World"
}
},
"throws": [{
"code": 404,
"schema": {
"$ref": "Error"
}
}, {
"code": 500,
"schema": {
"$ref": "Error"
}
}]
}
},
"definitions": {
"Hello_World": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
},
"Error": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
}
}
The definitions
keyword maps to the TypeSchema
specification and represents a map containing Struct,
Map and Reference
types. Those types are then used to describe incoming and outgoing JSON payloads.