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 a 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": {
"com.acme.api.hello.getMessage": { ... },
},
"definitions": {
"TypeA": { ... },
"TypeB": { ... }
}
}
The operations
keyword contains a map containing Operation objects. The key
represents the global identifier of this operation. In general we recommend to use as prefix for every operation key
the reverse name of your domain (i.e. com.acme.api.myOperation
) which makes it globally unique. The
generated client code always uses the last part of your operation key as method name.
{
"operations": {
"com.acme.api.hello.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 you can map values from the HTTP request to specific 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": {
"com.acme.api.hello.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": {
"com.acme.api.hello.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.
The single source of truth of TypeAPI is the TypeSchema meta schema which describes the TypeAPI specification. You can find the current TypeSchema at our repository. The following section contains a HTML representation which we automatically generate from this schema.
{ "in": String, "schema": typeschema:BooleanType | typeschema:NumberType | typeschema:IntegerType | typeschema:StringType | typeschema:ReferenceType, }
Field | Description |
---|---|
in | String The location where the value can be found either in the path, query, header or body. If you choose path, then your path must have a fitting variable path fragment
|
schema | typeschema:BooleanType | typeschema:NumberType | typeschema:IntegerType | typeschema:StringType | typeschema:ReferenceType |
Map (Argument)
{ "method": String, "path": String, "return": Return, "arguments": Arguments, "throws": Array (Throw), "description": String, "stability": Integer, "security": Array (String), "authorization": Boolean, "tags": Array (String), }
Field | Description |
---|---|
method | String The HTTP method which is associated with this operation, must be a valid HTTP method i.e. GET, POST, PUT etc. |
path | String The HTTP path which is associated with this operation. A path can also include variable path fragments i.e. /my/path/:year then you can map the variable year path fragment to a specific argument |
return | Return The return type of this operation. The return has also an assigned HTTP success status code which is by default 200 |
arguments | Arguments All arguments provided to this operation. Each argument is mapped to a location from the HTTP request |
throws | Array (Throw) All exceptional states which can occur in case the operation fails. Each exception is also assigned to an HTTP error status code |
description | String A short description of this operation. The generated code will include this description at the method so it is recommend to use simple alphanumeric characters and no new lines |
stability | Integer Indicates the stability of this operation. This is based on the stability index from the nodejs project: 0 - Deprecated, 1 - Experimental, 2 - Stable, 3 - Legacy. If not explicit provided the operation is by default experimental.
|
security | Array (String) An array of scopes which are required to access this operation |
authorization | Boolean Indicates whether this operation needs authorization, if set to false the client will not send an authorization header, default it is true |
tags | Array (String) Optional an array of tags to group operations. Those tags are used at the client generator to group operations |
Map (Operation)
{ "code": Integer, "schema": typeschema:ReferenceType, }
Field | Description |
---|---|
code | Integer The associated HTTP response code |
schema | typeschema:ReferenceType |
{ "name": String, "in": String, }
Field | Description |
---|---|
name | String |
in | String |
{ }
Field | Description |
---|
{ }
Field | Description |
---|
{ "tokenUrl": String, "authorizationUrl": String, "scopes": Array (String), }
Field | Description |
---|---|
tokenUrl | String |
authorizationUrl | String |
scopes | Array (String) |
{ "code": Integer, "schema": typeschema:ReferenceType, }
Field | Description |
---|---|
code | Integer The associated HTTP response code |
schema | typeschema:ReferenceType |
{ "$import": typeschema:Import, "baseUrl": String, "security": SecurityHttpBasic | SecurityHttpBearer | SecurityApiKey | SecurityOAuth2, "operations": Operations, "definitions": typeschema:Definitions, }
Field | Description |
---|---|
$import | typeschema:Import |
baseUrl | String Optional the base url of the service, if provided the user does not need to provide a base url for your client |
security | SecurityHttpBasic | SecurityHttpBearer | SecurityApiKey | SecurityOAuth2 |
operations | Operations |
definitions | typeschema:Definitions |