Resource Schema Structure

kind: <string>                    # Required
apiVersion: <string>              # Required
metadata:                         # Optional
  description: <string>
  version: <string>
  version_in_path: <boolean>
methods:                          # Required
  resource: [<http-methods>]
  instance: [<http-methods>]
descriptions:                     # Optional
  resource: {<method>: <string>}
  instance: {<method>: <string>}
schema:                           # Required
  type: array                     # Must be "array"
  key:                            # Required for instance methods
    name: <string>
    description: <string>
    schema: <json-schema>
  query_params: [...]             # Optional
  items:                          # Required
    type: object                  # Usually "object"
    properties: {...}
    required: [...]
default_query_params: [...]       # Optional
security:                         # Optional
  scheme: {...}
  resource: [<methods>]
  instance: [<methods>]
asyncapi:                         # Optional
  publish: <boolean>
  subscribe: <boolean>

Top-Level Fields

kind (Required)

Type: String Description: Resource name used in API paths URL Format: /{kind} and /{kind}/{id}

Rules:

  • ✅ Lowercase
  • ✅ Plural nouns recommended
  • ✅ Alphanumeric + hyphens/underscores
  • ❌ No spaces or special characters

Examples:

kind: users              # → /users, /users/{user_id}
kind: blog-posts         # → /blog-posts, /blog-posts/{post_id}
kind: product_categories # → /product_categories, /product_categories/{category_id}

apiVersion (Required)

Type: String Description: Resource definition version Current: Always "v1"

apiVersion: v1  # Required, always "v1" currently

metadata (Optional)

Type: Object Description: Resource-level metadata

Fields:

FieldTypeRequiredDescription
descriptionstringNoHuman-readable description
versionstringNoSemantic version (e.g., "1.0.0")
version_in_pathbooleanNoInclude version in URL path

Example:

metadata:
  description: User account management
  version: "2.1.0"
  version_in_path: false  # → /users (not /v2.1.0/users)

methods (Required)

Type: Object Description: HTTP methods to expose

Structure:

methods:
  resource: [<methods>]   # Collection endpoint: /{kind}
  instance: [<methods>]   # Instance endpoint: /{kind}/{id}

Valid HTTP Methods:

  • get - Retrieve resources
  • post - Create resource
  • put - Replace resource
  • patch - Update resource
  • delete - Delete resource

Examples:

# Full CRUD
methods:
  resource: [get, post]
  instance: [get, put, delete]

# Read-only
methods:
  resource: [get]
  instance: [get]

# Create-only
methods:
  resource: [post]
  instance: []

# Custom operations
methods:
  resource: [get, post]
  instance: [get, patch]  # PATCH instead of PUT

descriptions (Optional)

Type: Object Description: Human-readable operation descriptions

Structure:

descriptions:
  resource:
    get: "Description for GET /{kind}"
    post: "Description for POST /{kind}"
  instance:
    get: "Description for GET /{kind}/{id}"
    put: "Description for PUT /{kind}/{id}"
    delete: "Description for DELETE /{kind}/{id}"

Example:

descriptions:
  resource:
    get: List all users with optional filtering
    post: Create a new user account
  instance:
    get: Retrieve detailed user information
    put: Update user account
    delete: Permanently delete user account

schema (Required)

Type: Object Description: JSON Schema definition for the resource

schema.type (Required)

Must be: "array"

schema:
  type: array  # Always "array"

schema.key (Required for instance methods)

Type: Object Description: Identifier field for instance endpoints

Fields:

FieldTypeRequiredDescription
namestring✅ YesKey field name
descriptionstringNoKey description
schemaobject✅ YesJSON Schema for key

Examples:

# UUID key
key:
  name: user_id
  description: Unique user identifier
  schema:
    type: string
    format: uuid

# Integer key
key:
  name: id
  schema:
    type: integer
    minimum: 1

# String slug
key:
  name: slug
  schema:
    type: string
    pattern: '^[a-z0-9-]+$'
    minLength: 3
    maxLength: 50

schema.items (Required)

Type: Object Description: JSON Schema for resource objects

Common Structure:

items:
  type: object
  properties:
    field_name:
      type: <type>
      description: <description>
      # ... validation rules
  required: [list, of, required, fields]

Example:

items:
  type: object
  properties:
    name:
      type: string
      minLength: 1
      maxLength: 100
      description: User's full name

    email:
      type: string
      format: email
      maxLength: 254
      description: Email address

    age:
      type: integer
      minimum: 0
      maximum: 150
      description: User's age

    is_active:
      type: boolean
      default: true
      description: Account status

  required: [name, email]

schema.query_params (Optional)

Type: Array of objects Description: Query parameters for filtering/pagination

Structure:

query_params:
  - name: <param_name>
    description: <description>
    required: <boolean>
    schema: <json-schema>
    methods: [<http-methods>]

Example:

query_params:
  - name: status
    description: Filter by status
    required: false
    schema:
      type: string
      enum: [active, inactive, pending]
    methods: [get]

  - name: limit
    description: Number of results
    required: false
    schema:
      type: integer
      minimum: 1
      maximum: 100
      default: 20
    methods: [get]

  - name: offset
    description: Pagination offset
    required: false
    schema:
      type: integer
      minimum: 0
      default: 0
    methods: [get]

default_query_params (Optional)

Type: Array of objects Description: Query parameters added to all GET requests

Example:

default_query_params:
  - name: limit
    schema:
      type: integer
      default: 20

  - name: offset
    schema:
      type: integer
      default: 0

security (Optional)

Type: Object Description: Security scheme definitions and requirements

Structure:

security:
  scheme:
    <scheme_name>:
      type: <type>
      # ... scheme-specific fields
  resource: [<methods>]   # Methods requiring auth on /{kind}
  instance: [<methods>]   # Methods requiring auth on /{kind}/{id}

Security Scheme Types:

HTTP Bearer (JWT)

security:
  scheme:
    bearer_auth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  resource: [post]
  instance: [put, delete]

API Key

security:
  scheme:
    api_key:
      type: apiKey
      in: header
      name: X-API-Key
  resource: [get, post]
  instance: [get, put, delete]

OAuth2

security:
  scheme:
    oauth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.example.com/oauth/authorize
          tokenUrl: https://auth.example.com/oauth/token
          scopes:
            read: Read access
            write: Write access
  resource: [get, post]
  instance: [get, put, delete]

Multiple Schemes

security:
  scheme:
    bearer_auth:
      type: http
      scheme: bearer
    api_key:
      type: apiKey
      in: header
      name: X-API-Key
  resource: [post]  # Either bearer OR api_key required
  instance: [put, delete]

asyncapi (Optional)

Type: Object Description: AsyncAPI-specific configuration

Fields:

FieldTypeDefaultDescription
publishbooleanfalseEnable publish operations
subscribebooleanfalseEnable subscribe operations

Example:

asyncapi:
  publish: true    # Clients can publish to this resource
  subscribe: true  # Clients can subscribe to updates

JSON Schema Types

Common JSON Schema types used in schema.items.properties:

String

field_name:
  type: string
  minLength: 1           # Optional
  maxLength: 100         # Optional
  pattern: '^[a-z]+$'    # Optional regex
  format: email          # Optional format
  enum: [val1, val2]     # Optional enumeration
  default: "value"       # Optional default

Common Formats:

  • email - Email address
  • uri - URI/URL
  • uuid - UUID
  • date - ISO 8601 date (YYYY-MM-DD)
  • date-time - ISO 8601 datetime
  • ipv4 - IPv4 address
  • ipv6 - IPv6 address

Number / Integer

field_name:
  type: integer       # or "number" for floats
  minimum: 0          # Optional
  maximum: 100        # Optional
  multipleOf: 5       # Optional
  exclusiveMinimum: 0 # Optional
  default: 10         # Optional

Boolean

field_name:
  type: boolean
  default: false  # Optional

Array

field_name:
  type: array
  items:
    type: string       # or object, number, etc.
  minItems: 0          # Optional
  maxItems: 10         # Optional
  uniqueItems: true    # Optional

Object

field_name:
  type: object
  properties:
    nested_field:
      type: string
  required: [nested_field]
  additionalProperties: false  # Optional

Null / Optional

# Nullable field
field_name:
  type: [string, "null"]

# Optional field (not in required array)
properties:
  optional_field:
    type: string
required: []  # optional_field not listed

Validation Keywords

Common JSON Schema validation keywords:

KeywordTypesDescriptionExample
minLengthstringMinimum lengthminLength: 1
maxLengthstringMaximum lengthmaxLength: 100
patternstringRegex patternpattern: '^[A-Z]'
formatstringString formatformat: email
enumanyFixed valuesenum: [a, b, c]
minimumnumberMinimum valueminimum: 0
maximumnumberMaximum valuemaximum: 100
exclusiveMinimumnumberExclusive minexclusiveMinimum: 0
exclusiveMaximumnumberExclusive maxexclusiveMaximum: 100
multipleOfnumberMultiple ofmultipleOf: 10
minItemsarrayMin array lengthminItems: 1
maxItemsarrayMax array lengthmaxItems: 10
uniqueItemsarrayUnique itemsuniqueItems: true
requiredobjectRequired fieldsrequired: [name]
additionalPropertiesobjectAllow extra propsadditionalProperties: false

Complete Example

kind: users
apiVersion: v1

metadata:
  description: User account management API
  version: "1.0.0"
  version_in_path: false

methods:
  resource: [get, post]
  instance: [get, put, delete]

descriptions:
  resource:
    get: List all users with optional filtering
    post: Create a new user account
  instance:
    get: Get user details
    put: Update user account
    delete: Delete user account

schema:
  type: array

  key:
    name: user_id
    description: Unique user identifier
    schema:
      type: string
      format: uuid

  query_params:
    - name: status
      description: Filter by account status
      required: false
      schema:
        type: string
        enum: [active, inactive, pending]
      methods: [get]

    - name: limit
      description: Number of results to return
      required: false
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
      methods: [get]

  items:
    type: object
    properties:
      name:
        type: string
        minLength: 1
        maxLength: 100
        description: User's full name

      email:
        type: string
        format: email
        maxLength: 254
        description: Email address

      status:
        type: string
        enum: [active, inactive, pending]
        default: pending
        description: Account status

      age:
        type: integer
        minimum: 0
        maximum: 150
        description: User's age in years

      tags:
        type: array
        items:
          type: string
          minLength: 1
          maxLength: 50
        maxItems: 10
        uniqueItems: true
        description: User tags

    required: [name, email, status]

security:
  scheme:
    bearer_auth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  resource: [post]
  instance: [put, delete]

asyncapi:
  publish: false
  subscribe: true

Common Patterns

UUID Primary Key

key:
  name: id
  schema:
    type: string
    format: uuid

Integer Auto-Increment Key

key:
  name: id
  schema:
    type: integer
    minimum: 1

Slug/Handle Key

key:
  name: slug
  schema:
    type: string
    pattern: '^[a-z0-9-]+$'
    minLength: 3
    maxLength: 50

Timestamps

created_at:
  type: string
  format: date-time
  description: Creation timestamp

updated_at:
  type: string
  format: date-time
  description: Last update timestamp

Nested Address

address:
  type: object
  properties:
    street: {type: string}
    city: {type: string}
    state: {type: string, pattern: '^[A-Z]{2}$'}
    postal_code: {type: string, pattern: '^\d{5}(-\d{4})?$'}
  required: [street, city, postal_code]

Enum with Description

status:
  type: string
  enum: [draft, published, archived]
  description: |
    Publication status:
    - draft: Not yet published
    - published: Publicly visible
    - archived: No longer active

See Also