API Schema Generation
Relevant source files
The following files were used as context for generating this wiki page:
API Schema Generation in this project refers to the automated process of synchronizing the backend .NET API definitions with the frontend TypeScript environment. The system utilizes OpenAPI (Swagger) specifications to generate a strictly typed client, ensuring that data structures used in the web application match the definitions in the API service.
The architecture relies on the backend's ability to expose an OpenAPI document at runtime, which is then consumed by frontend tooling to produce a comprehensive TypeScript schema file. This prevents type drifting and provides compile-time safety for API requests and responses.
Backend Configuration
The .NET API serves as the source of truth for the schema. It is configured to generate an OpenAPI document that describes all available endpoints, data models (DTOs), and enumerations.
OpenAPI Setup
The API enables OpenAPI support through service extensions in the application bootstrap process. It maps a specific route to serve the generated JSON document, typically located at /openapi/{documentName}.json.
Sources: packages/api/Program.cs:17, packages/api/Program.cs:33
Strict Schema Transformations
To improve the quality of generated TypeScript types, the backend includes a schema transformer. This transformer iterates through model properties and explicitly marks them as "Required" if they are not nullable, preventing the frontend from receiving unexpectedly undefined values for mandatory fields.
builder.Services.AddOpenApi(options =>
{
options.AddSchemaTransformer((schema, _, _) =>
{
if (schema.Properties is { Count: > 0 })
{
schema.Required ??= new HashSet<string>();
foreach (var (name, property) in schema.Properties)
{
var isNullable = property.Type is { } t && (t & JsonSchemaType.Null) != 0;
if (!isNullable)
{
schema.Required.Add(name);
}
}
}
return Task.CompletedTask;
});
});
Sources: REVIEW.md:144-162
Frontend Generation Process
The frontend uses the openapi-typescript utility to convert the backend's JSON specification into a TypeScript definition file.
Generation Workflow
The synchronization process is triggered via a specific script in the web package. This script fetches the live OpenAPI JSON from the running API and overwrites the local schema file.
| Action | Command / Logic | File Destination |
|---|---|---|
| Trigger | bun run gen:api | packages/web/src/api/schema.ts |
| Source | http://localhost:5204/openapi/v1.json | N/A |
| Post-Process | bun run check:fix | Cleaned source code |
Sources: packages/web/package.json:19, packages/web/CLAUDE.md:31
Schema Generation Flow
The following diagram illustrates the data flow from the .NET backend to the TypeScript frontend.
The diagram shows how the backend definitions are transformed into a static TypeScript file used by the API client.
Sources: packages/web/package.json:19, packages/web/src/api/client.ts:46
Consumption of Generated Types
The generated schema.ts file exports a paths interface that represents the entire API surface area.
Typed API Client
The project uses openapi-fetch to create a lightweight client. This client is instantiated using the generated paths interface, which provides autocomplete and type checking for endpoint URLs, HTTP methods, parameters, and response bodies.
import createClient from 'openapi-fetch';
import { type paths } from './schema';
export const client = createClient<paths>({ baseUrl: env.SERVER_URL });
Sources: packages/web/src/api/client.ts:4, packages/web/src/api/client.ts:46
Data Structures
The generated schema includes a components['schemas'] object containing all shared data models used across the application.
| Schema Object | Description | Relevant Fields |
|---|---|---|
Customer | Core customer entity | id, number, name, isArchived |
UserResponse | Detailed user data | id, name, role, leaves |
Contract | Project contract details | id, subject, tasks |
AdminStats | Dashboard summary counts | customers, users, contracts |
Sources: packages/web/src/api/schema.ts:684-900
Maintenance and Best Practices
To ensure the integrity of the API schema, the following practices are enforced:
- Manual Regeneration: Developers must manually run
bun run gen:apiafter making changes to backend DTOs or Controllers. - No Direct Changes: The
src/api/schema.tsfile contains a header warning against manual edits, as they will be overwritten by the generator. - DTO Usage: The API is encouraged to expose specific DTOs rather than full database entities to maintain control over the contract exposed to the client.
Sources: packages/web/src/api/schema.ts:1-4, REVIEW.md:49-51
Conclusion
The API Schema Generation system provides a robust bridge between the .NET backend and the React frontend. By leveraging OpenAPI and TypeScript generation, the project maintains high type safety and reduces integration errors during development.