OpenAPI Documentation
Relevant source files
The following files were used as context for generating this wiki page:
The project leverages OpenAPI for API documentation, providing an interactive interface through Scalar. The documentation is automatically generated from the shared API contract defined using ORPC and Zod, ensuring that the API specification is always in sync with the backend's capabilities. This system is built upon the Hono web framework.
The API server exposes two main endpoints for documentation: one to serve the raw OpenAPI JSON specification and another to render an interactive UI using Scalar. This allows developers to explore and test API endpoints directly from their browser. Authentication schemes are also defined within the specification, integrating with the better-auth library.
Sources: README.md:19-21, apps/api/src/handlers/openapi.ts, apps/api/src/index.ts:4-6
Architecture Overview
The OpenAPI documentation system is composed of several key components that work together to generate and serve the API specification and interactive docs. The process begins with the API contract, which is passed to the OpenAPIGenerator. The Hono server then routes requests to specific handlers that either return the generated JSON spec or render the Scalar UI.
The following diagram illustrates the high-level architecture of the documentation generation and serving process.
API Endpoints
The Hono application in apps/api defines specific routes to expose the OpenAPI specification and the interactive documentation UI.
| Method | Path | Handler | Description |
|---|---|---|---|
GET | /api/spec.json | handleOpenAPISpec | Generates and returns the OpenAPI 3.0 specification in JSON format. |
GET | /api/docs | handleScalarDocs | Serves the interactive Scalar API documentation UI. |
ANY | /api/* | handleOpenAPIRequests | Middleware that handles incoming API requests validated against the OpenAPI spec. |
Sources: apps/api/src/index.ts:10-12
Specification Generation
The core of the documentation system is the dynamic generation of the OpenAPI specification from the project's shared contract.
handleOpenAPISpec
This handler is responsible for creating the OpenAPI JSON file. It uses OpenAPIGenerator from the @orpc/openapi library.
- An instance of
OpenAPIGeneratoris created, configured withZodToJsonSchemaConverterto translate Zod schemas from the contract into JSON schemas. - When a request hits
/api/spec.json, thegeneratemethod is called on the generator instance. - The
generatemethod takes thecontractobject and a configuration object as arguments. - The resulting specification is returned as a JSON response.
The following sequence diagram shows the process of generating the spec.
Generator Configuration
The OpenAPIGenerator is configured with metadata and security definitions.
// apps/api/src/handlers/openapi.ts:11-27
const spec = await openAPIGenerator.generate(contract, {
info: {
title: "ORPC Playground",
version: "1.0.0",
},
servers: [
{ url: "/api" }, // Use full URL in prod
],
security: [{ bearerAuth: [] }],
components: {
securitySchemes: {
bearerAuth: {
type: "http",
scheme: "bearer",
},
},
},
});
This configuration defines:
- Info: Basic metadata for the API.
- Servers: The base URL for the API endpoints.
- Security: Declares that endpoints may use
bearerAuth. - Components: Defines the
bearerAuthsecurity scheme as an HTTP Bearer token. This integrates with thebetter-authlibrary's OpenAPI plugin.
Sources: apps/api/src/handlers/openapi.ts:11-27, apps/api/src/lib/auth.ts:6
Interactive Documentation (Scalar)
To provide a user-friendly interface for the API, the project uses Scalar.
handleScalarDocs
The handleScalarDocs constant is an instance of the Scalar Hono middleware. It is configured to render an interactive API browser.
// apps/api/src/handlers/openapi.ts:31-39
export const handleScalarDocs = Scalar({
url: "/api/spec.json",
authentication: {
preferredSecurityScheme: "bearerAuth",
http: {
bearer: {
token: "default-token",
},
},
},
});
Key configurations include:
url: Points to the/api/spec.jsonendpoint to fetch the OpenAPI specification.authentication: Pre-configures the UI to use thebearerAuthsecurity scheme and provides a default token for testing.
When a user navigates to /api/docs, this middleware fetches the spec from /api/spec.json and renders the complete interactive documentation in the browser.
Sources: apps/api/src/handlers/openapi.ts:31-39, README.md:58
ORPC and OpenAPI Request Handling
The OpenAPIHandler from @orpc/openapi is used as middleware to intercept and handle requests that match the defined API contract.
The handleOpenAPIRequests function in apps/api/src/handlers/orpc.ts attempts to match incoming requests against the routes defined in the OpenAPI specification. If a match is found (matched is true), it processes the request and returns the response. Otherwise, it passes control to the next middleware.
This ensures that requests to /api/* are validated and handled according to the contract that was also used to generate the documentation.
// apps/api/src/handlers/orpc.ts:24-35
export async function handleOpenAPIRequests(c: Context, next: Next) {
const { matched, response } = await openAPIHandler.handle(c.req.raw, {
prefix: "/api",
context: {
user: c.get("user"),
session: c.get("session"),
},
});
if (matched) {
return c.newResponse(response.body, response);
}
await next();
}
Sources: apps/api/src/handlers/orpc.ts:7-13, 24-35, apps/api/src/index.ts:12