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`.
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.
// 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> }
}{
"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.
cargo ax check
cargo ax melt --checkAxonyx schema output
Use schema output when you want a compact, Axonyx-native view of API request and response contracts.
cargo ax api --schemaCurrent 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.
// 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.
cargo ax api --openapi
cargo ax api --openapi --out public/openapi.json{
"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.