Skip to main content

Appendix C: Schema Format Specification

Overview

Hypermodern uses JSON schemas to define API contracts, data models, and service interfaces. This specification defines the complete schema format and validation rules.

Schema Structure

A Hypermodern schema file has the following top-level structure:

{
  "version": "1.0",
  "metadata": {
    "name": "string",
    "description": "string",
    "version": "string",
    "author": "string"
  },
  "models": {},
  "enums": {},
  "endpoints": {},
  "events": {},
  "config": {}
}

Models

Models define data structures with typed fields and validation rules.

Basic Model Definition

{
  "models": {
    "user": {
      "id": "int64",
      "username": "string",
      "email": "string",
      "created_at": "datetime"
    }
  }
}

Field Types

Primitive Types

Type Description Example
string UTF-8 string "hello"
int32 32-bit signed integer 42
int64 64-bit signed integer 9223372036854775807
float32 32-bit floating point 3.14
float64 64-bit floating point 3.141592653589793
bool Boolean value true
datetime ISO 8601 timestamp "2023-10-15T14:30:00Z"
bytes Binary data (base64) "SGVsbG8gV29ybGQ="
any Dynamic type {"key": "value"}

Optional Types

Add ? suffix to make a field optional:

{
  "user": {
    "id": "int64",
    "name": "string",
    "bio": "string?"
  }
}

Collection Types

Arrays:

{
  "tags": ["string"],
  "scores": ["int32"],
  "users": ["@user"]
}

Maps:

{
  "metadata": "map<string, string>",
  "settings": "map<string, any>",
  "user_roles": "map<int64, @role>"
}

Reference Types

Reference other models using @ prefix:

{
  "post": {
    "id": "int64",
    "title": "string",
    "author": "@user",
    "comments": ["@comment"]
  }
}

Advanced Field Definitions

Field with Validation

{
  "user": {
    "username": {
      "type": "string",
      "min_length": 3,
      "max_length": 20,
      "pattern": "^[a-zA-Z0-9_]+$",
      "description": "Unique username"
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "User email address"
    },
    "age": {
      "type": "int32",
      "minimum": 13,
      "maximum": 120,
      "description": "User age in years"
    }
  }
}

Field with Default Value

{
  "user_preferences": {
    "theme": {
      "type": "string",
      "default": "light",
      "enum": ["light", "dark"]
    },
    "notifications_enabled": {
      "type": "bool",
      "default": true
    }
  }
}

Model Inheritance

Models can extend other models:

{
  "models": {
    "base_entity": {
      "id": "int64",
      "created_at": "datetime",
      "updated_at": "datetime"
    },
    "user": {
      "extends": "@base_entity",
      "username": "string",
      "email": "string"
    },
    "post": {
      "extends": "@base_entity",
      "title": "string",
      "content": "string",
      "author_id": "int64"
    }
  }
}

Model Composition

Embed models within other models:

{
  "models": {
    "address": {
      "street": "string",
      "city": "string",
      "country": "string"
    },
    "user": {
      "id": "int64",
      "name": "string",
      "home_address": "@address",
      "work_address": "@address?"
    }
  }
}

Model Annotations

Add metadata to models:

{
  "models": {
    "user": {
      "@annotations": {
        "table_name": "users",
        "indexes": [
          {"fields": ["email"], "unique": true},
          {"fields": ["username"], "unique": true},
          {"fields": ["created_at"]}
        ],
        "constraints": [
          {"type": "check", "expression": "age >= 0"}
        ]
      },
      "id": "int64",
      "username": "string",
      "email": "string",
      "age": "int32"
    }
  }
}

Enumerations

Define constrained string values:

{
  "enums": {
    "user_status": ["active", "inactive", "suspended", "deleted"],
    "order_status": ["pending", "processing", "shipped", "delivered", "cancelled"],
    "priority_level": {
      "values": ["low", "medium", "high", "critical"],
      "default": "medium",
      "description": "Task priority levels"
    }
  }
}

Enum with Numeric Values

{
  "enums": {
    "http_status": {
      "type": "int32",
      "values": {
        "ok": 200,
        "not_found": 404,
        "server_error": 500
      }
    }
  }
}

Endpoints

Define API endpoints with request/response schemas:

{
  "endpoints": {
    "get_user": {
      "method": "GET",
      "path": "/users/{id}",
      "description": "Retrieve a user by ID",
      "request": {
        "id": "int64"
      },
      "response": "@user",
      "errors": ["not_found", "unauthorized"],
      "transports": ["http", "websocket", "tcp"],
      "auth_required": true,
      "rate_limit": {
        "requests": 100,
        "window": "1m"
      }
    }
  }
}

Endpoint Types

Request-Response Endpoint

{
  "create_user": {
    "method": "POST",
    "path": "/users",
    "request": {
      "username": "string",
      "email": "string",
      "password": "string"
    },
    "response": "@user",
    "transports": ["http", "websocket"]
  }
}

Streaming Endpoint

{
  "watch_users": {
    "type": "stream",
    "description": "Stream user updates",
    "request": {
      "user_ids": ["int64"]
    },
    "response": "@user_update_event",
    "transports": ["websocket", "tcp"]
  }
}

Bidirectional Streaming

{
  "chat_messages": {
    "type": "bidirectional_stream",
    "description": "Real-time chat messaging",
    "request": "@chat_message",
    "response": "@chat_message",
    "transports": ["websocket", "tcp"]
  }
}

Request/Response Schemas

Simple Request

{
  "request": {
    "user_id": "int64",
    "include_profile": "bool?"
  }
}

Complex Request with Nested Objects

{
  "request": {
    "user_data": {
      "username": "string",
      "email": "string",
      "profile": {
        "first_name": "string",
        "last_name": "string",
        "bio": "string?"
      }
    },
    "options": {
      "send_welcome_email": "bool",
      "auto_follow": ["int64"]
    }
  }
}

Response with Multiple Types

{
  "response": {
    "oneOf": [
      {
        "type": "success",
        "user": "@user"
      },
      {
        "type": "error",
        "error_code": "string",
        "message": "string"
      }
    ]
  }
}

Error Definitions

Define custom error types:

{
  "errors": {
    "not_found": {
      "code": 404,
      "message": "Resource not found",
      "fields": {
        "resource_type": "string",
        "resource_id": "string"
      }
    },
    "validation_error": {
      "code": 400,
      "message": "Validation failed",
      "fields": {
        "field_errors": "map<string, string>"
      }
    }
  }
}

Events

Define domain events for event-driven architecture:

{
  "events": {
    "user_created": {
      "description": "Fired when a new user is created",
      "payload": {
        "user_id": "int64",
        "username": "string",
        "email": "string",
        "created_at": "datetime"
      },
      "metadata": {
        "version": "int32",
        "correlation_id": "string",
        "causation_id": "string?"
      }
    },
    "user_updated": {
      "description": "Fired when user data is updated",
      "payload": {
        "user_id": "int64",
        "changes": "map<string, any>",
        "updated_at": "datetime"
      }
    }
  }
}

Configuration Schema

Define configuration options for modules:

{
  "config": {
    "database": {
      "url": {
        "type": "string",
        "required": true,
        "description": "Database connection URL",
        "format": "uri"
      },
      "pool_size": {
        "type": "int32",
        "default": 10,
        "minimum": 1,
        "maximum": 100,
        "description": "Connection pool size"
      }
    },
    "auth": {
      "jwt_secret": {
        "type": "string",
        "required": true,
        "min_length": 32,
        "description": "JWT signing secret"
      },
      "token_expiry": {
        "type": "duration",
        "default": "24h",
        "description": "Token expiration time"
      }
    }
  }
}

Validation Rules

String Validation

{
  "username": {
    "type": "string",
    "min_length": 3,
    "max_length": 20,
    "pattern": "^[a-zA-Z0-9_]+$",
    "format": "username"
  },
  "email": {
    "type": "string",
    "format": "email"
  },
  "url": {
    "type": "string",
    "format": "uri"
  }
}

Numeric Validation

{
  "age": {
    "type": "int32",
    "minimum": 0,
    "maximum": 150
  },
  "price": {
    "type": "float64",
    "minimum": 0.0,
    "exclusive_minimum": true
  },
  "rating": {
    "type": "float32",
    "minimum": 1.0,
    "maximum": 5.0
  }
}

Array Validation

{
  "tags": {
    "type": ["string"],
    "min_items": 1,
    "max_items": 10,
    "unique_items": true
  },
  "coordinates": {
    "type": ["float64"],
    "min_items": 2,
    "max_items": 2
  }
}

Object Validation

{
  "metadata": {
    "type": "map<string, any>",
    "min_properties": 1,
    "max_properties": 20,
    "additional_properties": false
  }
}

Built-in Formats

String Formats

  • email: Email address validation
  • uri: URI validation
  • uuid: UUID validation
  • date: Date in YYYY-MM-DD format
  • time: Time in HH:MM:SS format
  • datetime: ISO 8601 datetime
  • hostname: Hostname validation
  • ipv4: IPv4 address
  • ipv6: IPv6 address
  • regex: Regular expression

Custom Formats

Define custom validation formats:

{
  "config": {
    "formats": {
      "phone_number": {
        "pattern": "^\\+?[1-9]\\d{1,14}$",
        "description": "International phone number"
      },
      "credit_card": {
        "pattern": "^\\d{4}[- ]?\\d{4}[- ]?\\d{4}[- ]?\\d{4}$",
        "description": "Credit card number"
      }
    }
  }
}

Schema Composition

Importing Schemas

{
  "imports": [
    "./common/base_types.json",
    "./auth/auth_models.json"
  ],
  "models": {
    "user": {
      "extends": "@base_entity",
      "username": "string"
    }
  }
}

Schema References

Reference external schemas:

{
  "models": {
    "order": {
      "id": "int64",
      "customer": "@customer",
      "items": ["@order_item"],
      "billing_address": "@common.address",
      "shipping_address": "@common.address"
    }
  }
}

Conditional Schemas

Discriminated Unions

{
  "models": {
    "notification": {
      "discriminator": "type",
      "oneOf": [
        {
          "type": "email",
          "recipient": "string",
          "subject": "string",
          "body": "string"
        },
        {
          "type": "sms",
          "phone_number": "string",
          "message": "string"
        },
        {
          "type": "push",
          "device_token": "string",
          "title": "string",
          "body": "string"
        }
      ]
    }
  }
}

Conditional Fields

{
  "models": {
    "payment": {
      "amount": "float64",
      "currency": "string",
      "method": "@payment_method",
      "if": {
        "properties": {"method": {"const": "credit_card"}},
        "then": {
          "required": ["card_number", "expiry_date", "cvv"],
          "properties": {
            "card_number": "string",
            "expiry_date": "string",
            "cvv": "string"
          }
        }
      }
    }
  }
}

Schema Versioning

Version Declaration

{
  "version": "2.1.0",
  "compatibility": {
    "min_version": "2.0.0",
    "max_version": "3.0.0"
  },
  "changelog": [
    {
      "version": "2.1.0",
      "changes": ["Added optional bio field to user model"],
      "breaking": false
    },
    {
      "version": "2.0.0",
      "changes": ["Renamed user_name to username"],
      "breaking": true
    }
  ]
}

Deprecated Fields

{
  "models": {
    "user": {
      "id": "int64",
      "username": "string",
      "user_name": {
        "type": "string",
        "deprecated": true,
        "deprecation_message": "Use 'username' instead",
        "removed_in_version": "3.0.0"
      }
    }
  }
}

Schema Validation

Validation Rules

  1. Model names must be valid identifiers (alphanumeric + underscore)
  2. Field names must be valid identifiers
  3. Type references must exist in the schema
  4. Circular references are not allowed in model inheritance
  5. Enum values must be unique within each enum
  6. Endpoint paths must be valid URL patterns

Example Validation Errors

{
  "errors": [
    {
      "type": "invalid_reference",
      "message": "Model '@unknown_model' not found",
      "location": "models.user.profile"
    },
    {
      "type": "circular_reference",
      "message": "Circular inheritance detected",
      "location": "models.user extends models.profile extends models.user"
    },
    {
      "type": "invalid_pattern",
      "message": "Invalid regex pattern",
      "location": "models.user.username.pattern"
    }
  ]
}

This schema format provides a comprehensive way to define APIs, data models, and service contracts in Hypermodern applications while maintaining type safety and enabling code generation.