Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API Generation Architecture

This document describes how Torc's HTTP API contract and generated clients are produced.

Overview

Torc uses a Rust-owned OpenAPI workflow:

  • The HTTP contract is defined in Rust by src/openapi_spec.rs, live handlers in src/server/live_router.rs, and src/models.rs.
  • The checked-in OpenAPI artifacts are api/openapi.yaml and api/openapi.codegen.yaml.
  • The live server transport is implemented in Rust under src/server/http_transport.rs.
  • The Rust client used by the CLI/TUI/dashboard is generated into src/client/apis/ using checked-in OpenAPI Generator template overrides so it matches Torc's canonical model layer and client conventions.
  • The Python and Julia clients are generated from the checked-in OpenAPI artifact.

Source Of Truth

The main ownership layers are:

  • src/models.rs
    • Canonical API models used by the Rust-owned contract.
  • src/openapi_spec.rs
    • OpenAPI document definition, emission, and parity checks.
  • src/server/live_router.rs
    • Live typed handlers that also own route metadata and operation IDs.
  • src/server/http_transport.rs and src/server/http_transport/*.rs
    • Live HTTP transport implementation for the server.
  • src/server/api_contract.rs
    • Rust server contract traits.

The HTTP API version is single-sourced in:

  • src/api_version.rs

That constant feeds:

  • server version reporting
  • client/server version checks
  • emitted OpenAPI document version
  • external client generation package metadata

OpenAPI Artifacts

The checked-in files in api/ are:

  • api/openapi.yaml
    • Promoted OpenAPI artifact used for external client generation.
  • api/openapi.codegen.yaml
    • Rust-emitted artifact kept alongside the promoted spec.

These should match the Rust emitter output. The parity check enforces that.

Server Creation

The live server is built from:

  • src/server/http_server.rs
    • top-level server wiring and shared state
  • src/server/http_transport.rs
    • HTTP route dispatch and request/response mapping
  • src/server/http_transport/*.rs
    • domain-specific transport handlers
  • src/server/api/*.rs
    • lower-level server business logic modules

Rust Client Creation

The Rust client under src/client/apis/ is generated from api/openapi.yaml, but it does not own its own model layer.

Relevant files:

  • api/regenerate_rust_client.sh
    • Generates a sync Rust client into a temporary directory.
    • Passes api/openapi-generator-templates/rust/ to OpenAPI Generator.
    • Copies only the generated grouped API modules, not the generated models/ tree.
  • api/openapi-generator-templates/rust/
    • Checked-in template overrides for the generated Rust client surface.
    • Must remain version-controlled because regeneration uses them as a required input.
    • Encodes Torc-specific generation behavior such as importing crate::models, using the shared blocking client helpers, and applying auth consistently.
  • src/client/apis/configuration.rs
    • Hand-owned blocking client configuration used by the generated Rust API modules.
    • Carries Torc-specific conventions like TLS settings, cookie handling, and auth application.

The surrounding Rust client logic is hand-written in:

  • src/client/

That includes things like:

  • src/client/version_check.rs
  • src/client/commands/
  • src/client/workflow_spec.rs

The generated Rust client is one layer inside a larger hand-owned Rust client stack. The canonical Rust API models remain in src/models.rs.

The generated Rust client does not own a second Rust model layer. Generated models.rs output is discarded. The repo keeps exactly one canonical Rust API model surface in src/models.rs.

The generated Rust client is tag-grouped. Current generated modules include domains such as:

  • src/client/apis/workflows_api.rs
  • src/client/apis/jobs_api.rs
  • src/client/apis/access_control_api.rs
  • src/client/apis/workflow_actions_api.rs
  • src/client/apis/remote_workers_api.rs
  • src/client/apis/ro_crate_entities_api.rs
  • src/client/apis/system_api.rs

The rest of the Rust codebase now calls those grouped generated modules directly.

Python And Julia Client Creation

The Python and Julia clients are generated from api/openapi.yaml.

Relevant files:

  • api/regenerate_clients.sh
    • Regenerates the Rust, Python, and Julia clients from the selected spec.
  • api/sync_openapi.sh
    • Main developer entrypoint for emitting, checking, promoting, and regenerating clients.

Generated output locations:

  • Python:
    • python_client/src/torc/openapi_client/
  • Julia:
    • julia_client/Torc/src/api/
    • julia_client/julia_client/docs/

There is also a hand-written Python compatibility/helper layer in:

  • python_client/src/torc/api.py

That layer exists to provide a stable high-level interface over the tag-grouped generated Python APIs.

Developer Workflow

Emit the Rust-owned OpenAPI spec:

bash api/sync_openapi.sh emit

Verify the checked-in artifacts match the Rust emitter:

bash api/sync_openapi.sh check

Promote the Rust-emitted spec into api/openapi.yaml:

bash api/sync_openapi.sh promote

Regenerate Rust, Python, and Julia clients:

bash api/sync_openapi.sh clients

This regenerates the Rust client from the selected spec using the checked-in template overrides, then regenerates the Python and Julia clients from the same spec.

To iterate on clients against the Rust-emitted contract before promotion:

bash api/sync_openapi.sh emit
bash api/sync_openapi.sh check
bash api/sync_openapi.sh clients --use-rust-spec

Run the full sync flow:

bash api/sync_openapi.sh all --promote

Why This Layout Exists

This arrangement gives Torc one authoritative contract pipeline:

  • The server contract is owned in normal Rust code.
  • The OpenAPI artifact is emitted deterministically from that Rust code.
  • External clients are generated from the emitted artifact.
  • Rust generator customization is expressed in checked-in templates, not a post-generation patch overlay.
  • Generated files are downstream artifacts, not the source of truth.