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:

{
  "models": {},
  "enums": {},
  "endpoints": {},
  "config": {}
}

Service-Based Organization

Hypermodern organizes endpoints into logical services:

{
  "endpoints": {
    "user": {
      "$meta": {
        "description": "User management service"
      },
      "get_user_profile": {
        "method": "GET",
        "path": "/users/profile",
        "request": "@get_user_profile_request",
        "response": "@user",
        "transports": ["http", "ws", "tcp"]
      },
      "update_user_profile": {
        "method": "PUT", 
        "path": "/users/profile",
        "request": "@update_user_profile_request",
        "response": "@user",
        "transports": ["http", "ws", "tcp"]
      }
    },
    "post": {
      "$meta": {
        "description": "Blog post management service"
      },
      "create_post": {
        "method": "POST",
        "path": "/posts",
        "request": "@create_post_request",
        "response": "@post",
        "transports": ["http", "ws", "tcp"]
      },
      "list_posts": {
        "method": "GET",
        "path": "/posts",
        "request": "@list_posts_request",
        "response": "[@post]",
        "transports": ["http", "ws", "tcp"]
      }
    }
  }
}

Model Metadata

All model metadata uses the $meta block:

{
  "models": {
    "user": {
      "$meta": {
        "table_name": "users",
        "description": "User account model",
        "indexes": [
          {"fields": ["email"], "unique": true},
          {"fields": ["username"], "unique": true}
        ]
      },
      "id": "int64",
      "username": "string",
      "email": "string"
    }
  }
}

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"
    }
  }
}

Collection Syntax Guide

Hypermodern supports three collection types with intuitive syntax:

Collection Schema Syntax Dart Type Example
Arrays [type] List<Type> [1, 2, 3]
Sets {type} Set<Type> {1, 2, 3}
Maps <keyType, valueType> Map<KeyType, ValueType> {'key': 'value'}

Array Examples

Schema:

{
  "models": {
    "blog_post": {
      "id": "int64",
      "title": "string",
      "tags": "[string]",
      "comments": "[@comment]"
    }
  }
}

Generated Dart:

class BlogPost {
  final int id;
  final String title;
  final List<String> tags;
  final List<Comment> comments;
}

Set Examples

Schema:

{
  "models": {
    "user": {
      "id": "int64",
      "username": "string", 
      "roles": "{@role}",
      "permissions": "{string}"
    }
  }
}

Generated Dart:

class User {
  final int id;
  final String username;
  final Set<Role> roles;
  final Set<String> permissions;
}

Map Examples

Schema:

{
  "models": {
    "configuration": {
      "name": "string",
      "settings": "<string, string>",
      "metadata": "<string, @metadata_value>"
    }
  }
}

Generated Dart:

class Configuration {
  final String name;
  final Map<String, String> settings;
  final Map<String, MetadataValue> metadata;
}

Nested Collections

Collections can be nested for complex data structures:

{
  "models": {
    "complex_data": {
      "matrix": "[[int]]",
      "user_groups": "<string, {string}>",
      "category_items": "<string, [@item]>"
    }
  }
}

Generated Dart:

class ComplexData {
  final List<List<int>> matrix;
  final Map<String, Set<String>> userGroups;
  final Map<String, List<Item>> categoryItems;
}

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="
uuid UUID v4 identifier "550e8400-e29b-41d4-a716-446655440000"
uuid_v7 Time-ordered UUID v7 "018c2b5c-8d20-7000-8000-123456789abc"
vector High-dimensional vector [1.0, 2.0, 3.0]
any Dynamic type {"key": "value"}

Advanced Data Types

UUID v7 (Time-Ordered UUIDs):

UUID v7 provides time-ordered identifiers that are optimized for database performance:

{
  "models": {
    "document": {
      "id": "uuid_v7",
      "title": "string",
      "created_at": "datetime"
    }
  }
}

Benefits of UUID v7:

  • Time-ordered for better B-tree performance
  • Sortable by creation time
  • Reduced index fragmentation
  • Better database clustering

Vector Types for AI/ML:

Vector types support high-dimensional data for machine learning applications:

{
  "models": {
    "document": {
      "id": "uuid_v7",
      "title": "string",
      "content": "string",
      "embedding": {
        "type": "vector",
        "dimensions": 1536,
        "description": "OpenAI text embedding"
      }
    }
  }
}

Vector field options:

  • dimensions: Number of vector dimensions (required)
  • distance_function: Similarity metric (cosine, l2, inner_product)
  • index_type: Index type for similarity search (hnsw, ivfflat)

Vector with Custom Configuration:

{
  "embedding": {
    "type": "vector",
    "dimensions": 768,
    "distance_function": "cosine",
    "index_type": "hnsw",
    "index_options": {
      "m": 16,
      "ef_construction": 64
    },
    "description": "BERT sentence embedding"
  }
}

Optional Types

Add ? suffix to make a field optional:

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

Collection Types

Hypermodern supports three collection types with syntax that mirrors Dart literals:

Arrays (Lists):

{
  "tags": "[string]",        // List<String> - like [1, 2, 3]
  "scores": "[int32]",       // List<int>
  "users": "[@user]"         // List<User>
}

Sets:

{
  "unique_tags": "{string}",     // Set<String> - like {1, 2, 3}
  "permissions": "{@permission}", // Set<Permission>
  "categories": "{int32}"        // Set<int>
}

Maps:

{
  "metadata": "<string, string>",    // Map<String, String> - like <String, int>{}
  "settings": "<string, any>",       // Map<String, dynamic>
  "user_roles": "<int64, @role>",    // Map<int, Role>
  "scores": "<string, float64>"      // Map<String, double>
}

Collection Syntax Summary:

  • Arrays: [type]List<Type>
  • Sets: {type}Set<Type>
  • Maps: <key, value>Map<Key, Value>

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 using $meta:

{
  "models": {
    "base_entity": {
      "$meta": {
        "description": "Base entity with common fields"
      },
      "id": "int64",
      "created_at": "datetime",
      "updated_at": "datetime"
    },
    "user": {
      "$meta": {
        "extends": "@base_entity",
        "table_name": "users"
      },
      "username": "string",
      "email": "string"
    },
    "post": {
      "$meta": {
        "extends": "@base_entity",
        "table_name": "posts"
      },
      "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 Instructions

Hypermodern uses a consistent "$" prefix for all model instructions and configuration to clearly distinguish them from field definitions.

Model Metadata

Add database metadata to models using $meta:

{
  "models": {
    "user": {
      "$meta": {
        "table_name": "users",
        "indexes": [
          {"fields": ["email"], "unique": true},
          {"fields": ["username"], "unique": true},
          {"fields": ["created_at"]}
        ]
      },
      "id": "int64",
      "username": "string",
      "email": "string",
      "age": "int32"
    }
  }
}

Model Inheritance

Use extends within $meta to inherit from base models:

{
  "models": {
    "base_entity": {
      "$meta": {
        "primary_key": {
          "field": "id",
          "type": "uuid_v7",
          "default": "generate_uuid_v7()"
        }
      },
      "id": "uuid_v7",
      "created_at": "datetime",
      "updated_at": "datetime"
    },
    "user": {
      "$meta": {
        "extends": "@base_entity",
        "table_name": "users"
      },
      "username": "string",
      "email": "string"
    }
  }
}

Model Configuration

All configuration goes in the $meta block:

{
  "models": {
    "user": {
      "$meta": {
        "table_name": "users",
        "description": "User account information"
      },
      "id": "int64",
      "username": "string",
      "email": "string",
      "password_hash": "string"
    }
  }
}

Advanced Metadata for UUID v7 and Vector Types:

{
  "models": {
    "document": {
      "$meta": {
        "table_name": "documents",
        "requires_extensions": ["uuid-ossp", "pgcrypto", "vector"],
        "indexes": [
          {
            "fields": ["embedding"],
            "type": "hnsw",
            "options": {
              "distance_function": "vector_cosine_ops",
              "m": 16,
              "ef_construction": 64
            }
          },
          {"fields": ["created_at"], "type": "btree"}
        ],
        "primary_key": {
          "field": "id",
          "type": "uuid_v7",
          "default": "generate_uuid_v7()"
        }
      },
      "id": "uuid_v7",
      "title": "string",
      "content": "string",
      "embedding": {
        "type": "vector",
        "dimensions": 1536
      },
      "created_at": "datetime"
    }
  }
}

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
  }
}

Collection Validation

Array Validation:

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

Set Validation:

{
  "permissions": {
    "type": "{string}",
    "min_items": 1,
    "max_items": 20
  },
  "categories": {
    "type": "{@category}",
    "min_items": 1
  }
}

Map Validation:

{
  "metadata": {
    "type": "<string, string>",
    "min_properties": 1,
    "max_properties": 50
  },
  "scores": {
    "type": "<string, float64>",
    "additional_properties": false
  }
}

Database-Specific Features

PostgreSQL Extensions

Hypermodern supports PostgreSQL extensions for advanced data types:

{
  "config": {
    "database": {
      "extensions": [
        "uuid-ossp",
        "pgcrypto", 
        "vector"
      ]
    }
  },
  "models": {
    "ai_document": {
      "$annotations": {
        "requires_extensions": ["vector", "uuid-ossp"]
      },
      "id": {
        "type": "uuid_v7",
        "default": "generate_uuid_v7()",
        "primary_key": true
      },
      "title": "string",
      "embedding": {
        "type": "vector",
        "dimensions": 1536,
        "index": {
          "type": "hnsw",
          "distance_function": "cosine",
          "m": 16,
          "ef_construction": 64
        }
      }
    }
  }
}

Vector Similarity Queries

Define endpoints for vector similarity search:

{
  "endpoints": {
    "find_similar_documents": {
      "method": "POST",
      "path": "/documents/similar",
      "request": {
        "query_vector": {
          "type": "vector",
          "dimensions": 1536
        },
        "limit": {
          "type": "int32",
          "default": 10,
          "maximum": 100
        },
        "threshold": {
          "type": "float64",
          "minimum": 0.0,
          "maximum": 1.0,
          "default": 0.7
        }
      },
      "response": {
        "documents": [{
          "document": "@ai_document",
          "similarity_score": "float64"
        }]
      }
    }
  }
}

Migration Requirements

Specify migration requirements for new data types:

{
  "models": {
    "user": {
      "$meta": {
        "requires_extensions": ["uuid-ossp", "pgcrypto", "vector"]
      },
      "id": "uuid_v7",
      "profile_embedding": {
        "type": "vector", 
        "dimensions": 384
      }
    }
  }
}

Built-in Formats

String Formats

  • email: Email address validation
  • uri: URI validation
  • uuid: UUID v4 validation
  • uuid_v7: UUID v7 validation (time-ordered)
  • 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

Vector Formats

  • vector: High-dimensional vector for ML/AI applications
  • embedding: Alias for vector with semantic meaning
  • coordinates: 2D/3D coordinate vector

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": {
      "$meta": {
        "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.