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/:id

2 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

Ready to reduce duplication in your API spec?

View api.json Format