API Specification

API Specification Format

api.vision uses a powerful yet simple specification format based on the Pretendo library to define your APIs. This document explains the core components and how to structure your API definition.

Overview

The api.vision specification is a structured format that defines your API's resources, relationships, and behavior. It can be written in JSON or YAML and is designed to be both human-readable and machine-processable.

Using this specification, you can define:

  • Resources (entities like users, products, posts)
  • Fields for each resource (properties like id, name, price)
  • Relationships between resources (one-to-one, one-to-many, etc.)
  • Validation rules and constraints
  • Default values and data generation options

Basic Structure

At its core, an api.vision specification consists of a collection of resources and their definitions. Here's a simple example:

{
  "resources": [
    {
      "name": "users",
      "fields": [
        {
          "name": "id",
          "type": "number"
        },
        {
          "name": "username",
          "type": "string",
          "required": true,
          "minLength": 3
        },
        {
          "name": "email",
          "type": "string",
          "required": true
        },
        {
          "name": "role",
          "type": "string",
          "enum": ["user", "admin"],
          "defaultValue": "user"
        }
      ],
      "relationships": [
        {
          "type": "hasMany",
          "resource": "posts",
          "foreignKey": "userId"
        }
      ]
    },
    {
      "name": "posts",
      "fields": [
        {
          "name": "id",
          "type": "number"
        },
        {
          "name": "title",
          "type": "string",
          "required": true
        },
        {
          "name": "content",
          "type": "string"
        },
        {
          "name": "userId",
          "type": "number",
          "required": true
        }
      ],
      "relationships": [
        {
          "type": "belongsTo",
          "resource": "users",
          "foreignKey": "userId"
        }
      ]
    }
  ]
}

Key Components

Resources

Resources represent the entities in your API. Each resource has a name (usually plural) and a collection of fields that define its structure.

{
  "name": "products",
  "fields": [...]
}

Fields

Fields define the properties of a resource. Each field has a name, type, and optional constraints.

{
  "name": "price",
  "type": "number",
  "required": true,
  "min": 0
}

Relationships

Relationships define how resources connect to each other. api.vision supports various relationship types.

{
  "type": "hasMany",
  "resource": "comments",
  "foreignKey": "postId"
}

Validation Rules

You can add constraints to fields to validate data. These ensure your API behaves consistently.

{
  "name": "email",
  "type": "string",
  "required": true,
  "pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
}

Field Types

api.vision supports a variety of field types to model your data accurately:

string

Text values. Can have constraints like minLength, maxLength, pattern, etc.

number

Numeric values. Can have constraints like min, max, etc.

boolean

True/false values.

date

Date and datetime values. Supports ISO 8601 format.

object

Nested object structures with their own properties.

array

Lists of values. Can specify item types and constraints.

Special Values

api.vision provides special placeholders for dynamic value generation:

PlaceholderDescriptionExample Usage
$uuidGenerates a unique UUID v4"defaultValue": "$uuid"
$incrementAuto-incrementing number"defaultValue": "$increment"
$nowCurrent timestamp"defaultValue": "$now"
$futureFuture timestamp"defaultValue": "$future"
$pastPast timestamp"defaultValue": "$past"
$randomRandom number within constraints"defaultValue": "$random"
$emailRandom email address"defaultValue": "$email"
$nameRandom person name"defaultValue": "$name"

Complete Example

Here's a more comprehensive example of an api.vision specification for a blog API:

{
  "resources": [
    {
      "name": "users",
      "fields": [
        {
          "name": "id",
          "type": "number",
          "defaultValue": "$increment"
        },
        {
          "name": "username",
          "type": "string",
          "required": true,
          "minLength": 3,
          "maxLength": 50
        },
        {
          "name": "email",
          "type": "string",
          "required": true,
          "defaultValue": "$email"
        },
        {
          "name": "role",
          "type": "string",
          "enum": ["user", "editor", "admin"],
          "defaultValue": "user"
        },
        {
          "name": "createdAt",
          "type": "date",
          "defaultValue": "$now"
        },
        {
          "name": "profile",
          "type": "object",
          "properties": {
            "firstName": { "type": "string" },
            "lastName": { "type": "string" },
            "bio": { "type": "string" }
          }
        }
      ],
      "relationships": [
        {
          "type": "hasMany",
          "resource": "posts",
          "foreignKey": "userId"
        },
        {
          "type": "hasMany",
          "resource": "comments",
          "foreignKey": "userId"
        }
      ]
    },
    {
      "name": "posts",
      "fields": [
        {
          "name": "id",
          "type": "number",
          "defaultValue": "$increment"
        },
        {
          "name": "title",
          "type": "string",
          "required": true,
          "minLength": 5
        },
        {
          "name": "content",
          "type": "string",
          "required": true
        },
        {
          "name": "userId",
          "type": "number",
          "required": true
        },
        {
          "name": "status",
          "type": "string",
          "enum": ["draft", "published", "archived"],
          "defaultValue": "draft"
        },
        {
          "name": "tags",
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        {
          "name": "createdAt",
          "type": "date",
          "defaultValue": "$now"
        },
        {
          "name": "updatedAt",
          "type": "date",
          "defaultValue": "$now"
        }
      ],
      "relationships": [
        {
          "type": "belongsTo",
          "resource": "users",
          "foreignKey": "userId"
        },
        {
          "type": "hasMany",
          "resource": "comments",
          "foreignKey": "postId"
        }
      ]
    },
    {
      "name": "comments",
      "fields": [
        {
          "name": "id",
          "type": "number",
          "defaultValue": "$increment"
        },
        {
          "name": "content",
          "type": "string",
          "required": true
        },
        {
          "name": "userId",
          "type": "number",
          "required": true
        },
        {
          "name": "postId",
          "type": "number",
          "required": true
        },
        {
          "name": "createdAt",
          "type": "date",
          "defaultValue": "$now"
        }
      ],
      "relationships": [
        {
          "type": "belongsTo",
          "resource": "users",
          "foreignKey": "userId"
        },
        {
          "type": "belongsTo",
          "resource": "posts",
          "foreignKey": "postId"
        }
      ]
    }
  ]
}

Next Steps

Now that you understand the basic structure of the api.vision specification, you can:

Tip: Using the Visual Editor

While you can write specifications manually, api.vision also provides a visual editor in the dashboard that makes it easy to define your API structure without writing JSON or YAML directly.