Skip to content

feat(server): generate OpenAPI spec with utoipa (#241)#271

Open
haseebrabbani wants to merge 1 commit into
mainfrom
feat/openapi-utoipa-241
Open

feat(server): generate OpenAPI spec with utoipa (#241)#271
haseebrabbani wants to merge 1 commit into
mainfrom
feat/openapi-utoipa-241

Conversation

@haseebrabbani
Copy link
Copy Markdown
Collaborator

@haseebrabbani haseebrabbani commented Jun 4, 2026

Summary

Resolves #241. Integrates utoipa to auto-generate an OpenAPI 3.1 specification directly from the HTTP handlers and wire models, so API docs stay in sync with the code (no manual drift).

Scope covers both HTTP surfaces — the client API (tag: client) consumed by SDKs/packages and the operator dashboard API (tag: dashboard) — plus the feature-gated EVM API (tag: evm).

Per the task framing, the deliverable is the generated spec file; a bundled Swagger UI was treated as optional and is not included (consumers can point Swagger UI / ReDoc / SDK generators at the spec).

What changed

  • Annotations: #[utoipa::path(...)] on all 36 operations across api/http.rs, api/dashboard.rs, api/dashboard_feeds.rs, api/evm.rs (method, path, params, request body, per-status responses); #[derive(ToSchema)] / IntoParams on every request/response/query/model type in the graph (→ 82 component schemas), including the shared signature types.
  • Aggregator: new openapi module with an ApiDoc OpenApi derive and a shared ApiErrorResponse schema mirroring GuardianError's envelope. openapi::openapi() merges the EVM surface only when the evm feature is compiled in, so the spec matches the routes actually mounted.
  • Delivery: served at GET /api-docs/openapi.json (unauthenticated, read-only); a gen-openapi binary writes the spec to a file; the generated docs/openapi.json (built with evm) is committed and documented in docs/OPENAPI.md.

Regenerating

cargo run --features evm --bin gen-openapi -- docs/openapi.json

Testing

  • cargo check (default) and --features evm: clean.
  • cargo clippy --all-targets --all-features -- -D warnings on the touched crates: clean.
  • Server lib suite: 523 passed; plus new unit tests asserting the spec builds/serializes, exposes each surface's paths, registers core schemas, and gates EVM behind the feature.

Notes

Purely additive documentation — no wire-shape changes — so the Rust/TS clients need no updates under the contract-change workflow.

Integrate utoipa to auto-generate an OpenAPI 3.1 spec from the HTTP
handlers and wire models, so API docs stay in sync with the code.

- Annotate every HTTP handler (client, dashboard, and feature-gated
  EVM surfaces) with `#[utoipa::path]` and derive `ToSchema` /
  `IntoParams` on the request/response/query/model types.
- Add `openapi::openapi()` which assembles the document and merges the
  EVM routes only when the `evm` feature is compiled in.
- Serve the spec at `GET /api-docs/openapi.json` (unauthenticated,
  read-only) and add a `gen-openapi` binary to write it to a file.
- Commit the generated `docs/openapi.json` (built with `evm`) and
  document it in `docs/OPENAPI.md`.

36 operations / 82 schemas. Purely additive: no wire-shape changes, so
the Rust/TS clients need no updates.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@haseebrabbani haseebrabbani requested a review from zeljkoX as a code owner June 4, 2026 18:27
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

Walkthrough

This PR integrates utoipa to auto-generate an OpenAPI 3.1 specification directly from Rust type annotations and HTTP handler metadata. The changes add workspace and crate dependencies, annotate 50+ domain types with schema derivations, decorate 25+ handlers with endpoint metadata, implement OpenAPI document generation with feature-gated EVM support, and expose both a runtime JSON endpoint and a CLI tool for spec generation.

Changes

OpenAPI Spec Generation Integration

Layer / File(s) Summary
Workspace and crate dependencies
Cargo.toml, crates/server/Cargo.toml, crates/shared/Cargo.toml
Adds utoipa version 5 with axum_extras feature to workspace dependencies; configures crates/server and crates/shared to depend on it.
Schema and type annotations
crates/server/src/api/dashboard.rs, crates/server/src/api/evm.rs, crates/server/src/api/http.rs, crates/server/src/delta_object.rs, crates/server/src/delta_summary/mod.rs, crates/server/src/evm/proposal.rs, crates/server/src/metadata/auth/mod.rs, crates/server/src/metadata/network.rs, crates/server/src/services/*, crates/shared/src/lib.rs, crates/server/src/state_object.rs
Updates 50+ public types across dashboard, EVM, client API, and service layers to derive utoipa::ToSchema and (for query types) utoipa::IntoParams. Adds explicit schema metadata to JSON payload fields (e.g., #[schema(value_type = Object)]). Includes new VerifyOperatorResponse for auth flow.
HTTP handler OpenAPI annotations
crates/server/src/api/dashboard.rs, crates/server/src/api/dashboard_feeds.rs, crates/server/src/api/evm.rs, crates/server/src/api/http.rs
Decorates 25+ handler functions with #[utoipa::path(...)] macros documenting HTTP method, path, request/response types, parameters, and expected status codes across dashboard auth (challenge/verify/logout), account management (list/detail/snapshot), global feeds, and client API surfaces.
OpenAPI document generation
crates/server/src/openapi.rs, crates/server/src/lib.rs
Implements ApiErrorResponse schema for error envelopes, defines base ApiDoc document aggregating all client and dashboard paths, adds feature-gated EvmApiDoc for conditional EVM routes, and exports public openapi() function that builds, versions from CARGO_PKG_VERSION, and merges specs. Includes unit tests validating JSON serialization and presence of representative paths/schemas.
Runtime and CLI
crates/server/src/builder/handle.rs, crates/server/src/bin/gen-openapi.rs
Registers GET /api-docs/openapi.json endpoint to serve auto-generated spec at runtime (unauthenticated). Implements gen-openapi binary that serializes spec to pretty JSON and writes to file path or stdout with POSIX-compliant newline.
Documentation
docs/OPENAPI.md, docs/README.md
Introduces docs/OPENAPI.md explaining spec generation from utoipa annotations, surfaces covered (client and dashboard APIs), feature-gating for EVM routes, checked-in and runtime spec locations, and regeneration instructions. Updates docs/README.md navigation to include OpenAPI spec links.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • OpenZeppelin/guardian#231: Implements SessionInfoResponse and GET /dashboard/session endpoint; this PR adds utoipa schema/path annotations for the same endpoint and types.
  • OpenZeppelin/guardian#224: Introduces dashboard endpoint/type changes that this PR annotates with OpenAPI metadata.
  • OpenZeppelin/guardian#233: Adds pause/unpause DTOs and handlers to dashboard API; this PR adds OpenAPI annotations for those same types and endpoints.

Suggested labels

cla: allowlist

Suggested reviewers

  • tirumerla
  • onurinanc

Poem

🐇 Hops through schemas with glee,
utoipa makes specs you can see,
No manual drift, just derive and annotate,
OpenAPI docs that stay up-to-date!
Swagger UI ready, DX is great!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(server): generate OpenAPI spec with utoipa (#241)' directly and accurately describes the main objective of the PR: integrating utoipa to generate OpenAPI specifications.
Linked Issues check ✅ Passed All coding objectives from issue #241 are met: utoipa is integrated [#241], data models and HTTP handlers are decorated with ToSchema/IntoParams/path attributes across ~82 component schemas and 36 operations [#241], the generated OpenAPI 3.1 spec covers client, dashboard, and feature-gated EVM surfaces [#241], the spec is auto-generated to keep documentation in sync with source code [#241], and it is served at /api-docs/openapi.json for downstream tool consumption [#241].
Out of Scope Changes check ✅ Passed All changes are in scope: utoipa dependency additions, handler/model schema annotations, new openapi module and gen-openapi binary, documentation additions, and serving the spec via HTTP—all directly support the #241 objective of auto-generating OpenAPI specs. No unrelated refactoring or feature changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/openapi-utoipa-241

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR integrates utoipa into the guardian-server crate to generate an OpenAPI 3.1 specification directly from HTTP handlers and wire models, then exposes and documents that spec for downstream tooling (docs, SDK generators).

Changes:

  • Adds #[utoipa::path] annotations to HTTP handlers and ToSchema / IntoParams derives to request/response/query models across client, dashboard, and feature-gated EVM HTTP surfaces.
  • Introduces a new crates/server/src/openapi.rs aggregator module plus a gen-openapi binary to emit a committed docs/openapi.json.
  • Serves the OpenAPI spec at GET /api-docs/openapi.json and documents regeneration/usage under docs/OPENAPI.md.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
docs/README.md Adds links to the OpenAPI documentation/spec artifact.
docs/OPENAPI.md Documents where the spec lives, runtime endpoint, and regeneration command.
docs/openapi.json Adds the generated OpenAPI 3.1 JSON spec (built with evm).
crates/shared/src/lib.rs Derives utoipa::ToSchema for shared signature types used on the wire.
crates/shared/Cargo.toml Adds utoipa dependency to guardian-shared.
crates/server/src/state_object.rs Derives ToSchema and marks state_json as schema-free object.
crates/server/src/services/unpause_account.rs Derives ToSchema for UnpauseResponse.
crates/server/src/services/pause_account.rs Derives ToSchema for PauseResponse.
crates/server/src/services/dashboard_pagination.rs Derives ToSchema for PagedResult<T>.
crates/server/src/services/dashboard_info.rs Derives ToSchema for dashboard info/status response models.
crates/server/src/services/dashboard_global_proposals.rs Derives ToSchema for global proposal feed entries.
crates/server/src/services/dashboard_global_deltas.rs Derives ToSchema for global delta feed entries.
crates/server/src/services/dashboard_accounts.rs Derives ToSchema for dashboard account summary/detail types.
crates/server/src/services/dashboard_account_snapshot.rs Derives ToSchema for snapshot types.
crates/server/src/services/dashboard_account_proposals.rs Derives ToSchema for per-account proposal feed entries.
crates/server/src/services/dashboard_account_deltas.rs Derives ToSchema for per-account delta feed types.
crates/server/src/services/dashboard_account_delta_detail.rs Derives ToSchema for delta detail response type.
crates/server/src/services/account_status.rs Derives ToSchema for AccountStatus.
crates/server/src/openapi.rs Adds OpenAPI document aggregation, error schema, EVM merge, and unit tests.
crates/server/src/metadata/network.rs Derives ToSchema for NetworkConfig and MidenNetworkType.
crates/server/src/metadata/auth/mod.rs Derives ToSchema for Auth enum used in client configure requests.
crates/server/src/lib.rs Exposes the new openapi module.
crates/server/src/evm/proposal.rs Derives ToSchema for EVM proposal models.
crates/server/src/delta_summary/mod.rs Derives ToSchema for dashboard delta metadata and decode projection types.
crates/server/src/delta_object.rs Derives ToSchema for delta objects/status/signatures and schema-free payload.
crates/server/src/builder/handle.rs Serves the generated spec at /api-docs/openapi.json.
crates/server/src/bin/gen-openapi.rs Adds a binary to generate/write the spec JSON.
crates/server/src/api/http.rs Adds utoipa annotations for client HTTP handlers + schemas/params.
crates/server/src/api/evm.rs Adds utoipa annotations for EVM HTTP handlers + schemas/params.
crates/server/src/api/dashboard.rs Adds utoipa annotations for dashboard auth/account/session/pause endpoints.
crates/server/src/api/dashboard_feeds.rs Adds utoipa annotations for dashboard feed endpoints + query params.
crates/server/Cargo.toml Adds utoipa dependency to the server crate.
Cargo.toml Adds workspace utoipa dependency with axum_extras feature.
Cargo.lock Locks utoipa (and transitive updates like itertools).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +56 to +60
// Issue #241: serve the auto-generated OpenAPI spec. Unauthenticated
// and read-only — it documents the contract, not data.
async fn openapi_json() -> axum::Json<utoipa::openapi::OpenApi> {
axum::Json(crate::openapi::openapi())
}
Comment on lines +17 to +20
/// Wire shape of a Guardian error response body. Mirrors the envelope
/// produced by [`crate::error::GuardianError`]'s `IntoResponse` impl.
/// Documented as the body of every non-2xx response. Optional fields
/// are populated only for the error codes that carry them.
Comment thread crates/shared/Cargo.toml
Comment on lines 12 to +20
[dependencies]
miden-protocol = { version = "=0.14.5" }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
base64 = { workspace = true }
rand = "0.8"
hex = { workspace = true }
prost = { workspace = true }
utoipa = { workspace = true }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add utoipa + model annotations to generate OpenAPI spec

2 participants