Templates
Templates eliminate duplication in api.json by letting you define models and resources once, then reuse them across multiple concrete types. Templates are syntactic sugar — they require no changes to code generators, since templates are fully expanded before the service specification is produced.
1 The Problem
When multiple models share the same fields and resources share the same operations, your api.json accumulates duplication with no way to guarantee consistency.
For example, two account types with identical fields:
client_account:
fields:
- id: string
- currency: string
partner_account:
fields:
- id: string
- currency: string Each exposed as a resource with the same operations:
client_account:
GET /client/accounts
GET /client/accounts/:id
partner_account:
GET /partner/accounts
GET /partner/accounts/:id2 Define a Template
Extract the common spec into a top-level templates node. Define both model fields and resource operations in one place.
"templates": {
"models": {
"account": {
"fields": [
{ "name": "id", "type": "string", "example": "xxxx-1234" },
{ "name": "currency", "type": "string" }
]
}
},
"resources": {
"account": {
"operations": [
{
"method": "GET",
"parameters": [
{ "name": "id", "type": "[string]", "required": false, "maximum": 100 }
],
"responses": {
"200": { "type": "[account]" },
"401": { "type": "unit" },
"404": { "type": "unit" }
}
},
{
"method": "GET",
"path": "/:id",
"responses": {
"200": { "type": "account" },
"401": { "type": "unit" },
"404": { "type": "unit" }
}
}
]
}
}
}3 Apply to Models
Reference the template by name. Each model inherits all template fields, and API Builder automatically creates an interface so the models share a common type.
"models": {
"partner_account": {
"templates": [{ "name": "account" }]
},
"client_account": {
"templates": [{ "name": "account" }]
}
}4 Apply to Resources
Same pattern for resources — reference the template and specify the unique path.
"resources": {
"partner_account": {
"templates": [{ "name": "account" }],
"path": "/partner/accounts"
},
"client_account": {
"templates": [{ "name": "account" }],
"path": "/client/accounts"
}
}! Merge Behavior
- Override by default — Anything you specify in the model or resource takes precedence over the template. Add a field to just one model by declaring it there.
- Type specialization — Template types are automatically specialized. A template referencing account becomes client_account or partner_account in the final service specification.
- Auto-interfaces — API Builder creates an interface from the template name, with each consuming model extending it.
Resources
- Complete template example — Full api.json with model and resource templates
- Live example in API Builder — See the expanded result in the UI
Ready to reduce duplication in your API spec?
View api.json Format