Contractscargo-axonyx 0.2.16

API contracts

Axonyx can inspect backend `.ax` routes and export their input and response contracts. The source of truth stays in Axonyx, while tools can read `.ax` schema output or OpenAPI JSON.

Declare the contract once

Use `.ax type` declarations for public shapes, then attach the return contract to routes, loaders, or actions with `-> Type`.

Code
ax
export type Post {
  title: String
  summary?: String
}

route GET "/api/posts" -> Post[] {
  return json(posts)
}

route POST "/api/posts" -> Post {
  input {
    title: String
    summary?: String = ""
  }

  return json(post)
}

Page data contracts

Loader return types flow into page data bindings. This keeps the authoring syntax short while preserving a machine-readable type and its source in the generated contract report.

Code
ax
// app/posts/loader.ax
query loadPosts() -> Post[] {
  return db.posts.all()
}

// app/posts/page.asx
page Posts() {
  data posts = loadPosts()
  return ASX { <Each items={posts} as="post">...</Each> }
}
Code
json
{
  "name": "posts",
  "type": "List<Post>",
  "type_source": "loader"
}

Check before build

`cargo ax check` validates return contract syntax and verifies custom named return types when it runs from an app root.

Valid contracts

Named types, array shorthand, List type wrappers, and Optional type wrappers are accepted forms.

Unknown types

A Post array return contract fails if no parsed Post type exists in the project.

Code
ax
cargo ax check
cargo ax melt --check

Axonyx schema output

Use schema output when you want a compact, Axonyx-native view of API request and response contracts.

Code
ax
cargo ax api --schema

Current contracts also expose helper response metadata such as `notFound()`, `noContent()`, `redirect(...)`, and signed-session auth guards so API reports and OpenAPI exports describe more than just the happy-path `200` response.

Code
ax
// GET /api/posts
// response: List<Post>
type GetApiPostsRequest {
  // no input body
}

// POST /api/posts
// response: Post
type PostApiPostsRequest {
  title: String
  summary?: String = ""
}

OpenAPI export

Use OpenAPI when external tools need to read the API surface. Axonyx still owns the contract; OpenAPI is an export format.

Code
ax
cargo ax api --openapi
cargo ax api --openapi --out public/openapi.json
Code
ax
{
  "openapi": "3.1.0",
  "paths": {
    "/api/posts": {
      "get": {
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Post" }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Post": {
        "type": "object",
        "properties": {
          "title": { "type": "string" },
          "summary": { "type": "string" }
        },
        "required": ["title"]
      }
    }
  }
}

Why this matters

Humans see the app

`cargo ax api` makes backend routes visible before wiring a frontend or deploying.

AI gets safer context

Typed contracts help AI agents understand route inputs and response shapes without guessing.

External tools can join

OpenAPI export keeps compatibility with existing docs, QA, and integration tooling.

Axonyx stays source of truth

The backend `.ax` route and type declarations remain the canonical contract.