Skip to content

Commit a065e73

Browse files
committed
docs: update guides and add descriptions and metadata section
1 parent d5c8a7e commit a065e73

9 files changed

Lines changed: 506 additions & 106 deletions

docs/concepts/decorators.md

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,67 @@
22

33
[Docs Home](../index.md) | [Previous: Getting Started](../getting-started.md) | [Next: Request Lifecycle](request-lifecycle.md)
44

5-
Decorators define routes, validation, metadata, and runtime behavior. bun-openapi reads decorator metadata at startup and builds:
5+
Decorators are the primary way you configure bun-openapi. Instead of writing separate route registration code and OpenAPI spec files, you annotate your controller classes — and the framework reads that metadata at startup to build:
66

7-
- Bun route handlers
8-
- runtime validation wiring
9-
- OpenAPI document
7+
- **Bun route handlers** with parameter binding and validation.
8+
- **Runtime behavior** — guards, interceptors, and middleware execution order.
9+
- **OpenAPI 3.0 document** with paths, schemas, security, and response descriptions.
10+
11+
This means your TypeScript code is the single source of truth for both the running server and the API documentation.
1012

1113
## Class-Level Decorators
1214

13-
- @Route("/prefix") sets the base path.
14-
- @Tags("Users") sets OpenAPI tags for all methods.
15-
- @Security("bearerAuth") applies default security requirements.
16-
- @UseGuards(...) attaches guards to all controller methods.
17-
- @UseInterceptors(...) attaches interceptors to all methods.
18-
- @ValidateResponse(true) enables response validation by default.
19-
- @Middleware(...) adds middleware wrappers at controller scope.
15+
These decorators go on your controller class and affect all methods within it.
16+
17+
| Decorator | Effect |
18+
| ------------------------- | -------------------------------------------- |
19+
| `@Route("/prefix")` | Sets the base path for all endpoints |
20+
| `@Tags("Users")` | Applies OpenAPI tags to all methods |
21+
| `@Security("bearerAuth")` | Adds default security requirement |
22+
| `@UseGuards(...)` | Attaches guards to all methods |
23+
| `@UseInterceptors(...)` | Attaches interceptors to all methods |
24+
| `@ValidateResponse(true)` | Enables response validation by default |
25+
| `@Middleware(...)` | Adds middleware wrappers at controller scope |
2026

2127
## Method-Level Decorators
2228

23-
- HTTP verbs: @Get, @Post, @Put, @Patch, @Delete
24-
- OpenAPI metadata: @Summary, @Description, @OperationId, @Deprecated, @Hidden
25-
- Response metadata: @Returns(status, schema, description), @Produces(contentType)
26-
- Runtime behavior: @UseGuards, @UseInterceptors, @ValidateResponse, @Render
29+
These decorators go on individual methods to define endpoints and their behavior.
30+
31+
- **HTTP verbs**: `@Get`, `@Post`, `@Put`, `@Patch`, `@Delete`
32+
- **OpenAPI metadata**: `@Summary`, `@Description`, `@OperationId`, `@Deprecated`, `@Hidden`
33+
- **Response metadata**: `@Returns(status, schema, description)`, `@Produces(contentType)`
34+
- **Runtime behavior**: `@UseGuards`, `@UseInterceptors`, `@ValidateResponse`, `@Render`, `@Security`
35+
36+
> **TIP**: Method-level decorators override class-level ones where it makes sense. For example, `@Security` on a method replaces the controller-level security requirement for that specific endpoint.
2737
2838
## Parameter Decorators
2939

30-
- @Param(schema) or @Param("id")
31-
- @Query(schema) or @Query("page")
32-
- @Header(schema) or @Header("x-request-id")
33-
- @Body(schema)
34-
- @Request()
40+
These bind incoming request data to method arguments. They come in two flavors:
41+
42+
- **Whole-object**: pass a schema class for validation — `@Param(UserParams)`, `@Body(CreateUser)`
43+
- **Scalar**: pass a string name for single values — `@Param("id")`, `@Query("page")`
44+
45+
| Decorator | Source |
46+
| ----------------- | --------------- |
47+
| `@Param(schema)` | Path parameters |
48+
| `@Query(schema)` | Query string |
49+
| `@Header(schema)` | Request headers |
50+
| `@Body(schema?)` | Request body |
51+
| `@Request()` | Raw `Request` |
3552

3653
## Mental Model
3754

38-
Think in layers:
55+
Think of decorators as defining layers that compose at startup:
56+
57+
```
58+
@Route + @Get/@Post/... → 1. Route matching
59+
@Param/@Query/@Body/... → 2. Parameter binding & validation
60+
@UseGuards / @Security → 3. Guard & security checks
61+
@UseInterceptors → 4. Interceptor wrapping
62+
→ 5. Controller method execution
63+
@Returns + @ValidateResponse → 6. Optional response validation
64+
```
3965

40-
1. Route matching from @Route + verb decorators.
41-
2. Parameter binding and validation from parameter decorators.
42-
3. Guards and security checks.
43-
4. Interceptor wrapping.
44-
5. Controller execution.
45-
6. Optional response validation.
66+
Each layer reads metadata that you declared with decorators. No manual wiring required.
4667

47-
Continue with [Request Lifecycle](request-lifecycle.md) for exact execution order.
68+
Continue with [Request Lifecycle](request-lifecycle.md) for the exact execution order at runtime.

docs/getting-started.md

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,35 @@
22

33
[Docs Home](index.md) | [Next: Decorator Basics](concepts/decorators.md)
44

5+
This guide walks you through building a small Users API with bun-openapi. By the end you will have a running Bun server with automatic request validation, a generated OpenAPI 3.0 spec, and live Swagger UI.
6+
7+
> **Prerequisites**: [Bun](https://bun.sh/) >= 1.0 installed.
8+
59
## Install
610

7-
Install bun-openapi and one schema adapter.
11+
Install bun-openapi and one schema adapter. This guide uses `class-validator`, but you can swap it for TypeBox, Zod, or Valibot later.
812

913
```sh
1014
bun add bun-openapi class-validator
1115
```
1216

13-
## 1) Create a Controller
17+
## 1) Define a Model
18+
19+
Start by defining the data shapes your API will use. These classes serve double duty — they are TypeScript types for your code **and** the source for OpenAPI schema definitions.
1420

1521
```ts
1622
import {
17-
Body,
18-
Controller,
19-
Get,
20-
Post,
21-
Returns,
22-
Route,
23-
Summary,
24-
} from "bun-openapi";
23+
IsEmail,
24+
IsString,
25+
MinLength,
26+
} from "class-validator";
2527

2628
class CreateUser {
29+
@IsString()
30+
@MinLength(1)
2731
name!: string;
32+
33+
@IsEmail()
2834
email!: string;
2935
}
3036

@@ -33,6 +39,24 @@ class User {
3339
name!: string;
3440
email!: string;
3541
}
42+
```
43+
44+
> **TIP**: With `class-validator`, you can add validation constraints directly on the DTO fields. These constraints are enforced at runtime and also appear in the generated OpenAPI spec.
45+
46+
## 2) Create a Controller
47+
48+
Controllers define your routes. The `@Route` decorator sets the base path, and HTTP-verb decorators (`@Get`, `@Post`, ...) register individual endpoints. Parameter decorators like `@Body` bind and validate incoming data automatically.
49+
50+
```ts
51+
import {
52+
Body,
53+
Controller,
54+
Get,
55+
Post,
56+
Returns,
57+
Route,
58+
Summary,
59+
} from "bun-openapi";
3660

3761
@Route("/users")
3862
class UserController extends Controller {
@@ -57,7 +81,20 @@ class UserController extends Controller {
5781
}
5882
```
5983

60-
## 2) Start Bun Server
84+
Let's break down what's happening:
85+
86+
- `@Route("/users")` sets `/users` as the base path for all methods in this class.
87+
- `@Get()` combined with the base route creates a `GET /users` endpoint.
88+
- `@Post()` creates `POST /users`.
89+
- `@Summary(...)` becomes the endpoint summary in generated OpenAPI docs.
90+
- `@Returns(201, User, ...)` tells bun-openapi what the success response looks like — both for documentation and optional response validation.
91+
- `@Body(CreateUser)` validates the incoming JSON body against the `CreateUser` schema before the method executes.
92+
93+
> **TIP**: If validation fails (e.g. a missing `name` field), the framework automatically returns a 400 error with details. You don't need to write any validation logic yourself.
94+
95+
## 3) Start the Server
96+
97+
Wire everything together with `createApp()` and pass the result to `Bun.serve`:
6198

6299
```ts
63100
import { createApp } from "bun-openapi";
@@ -82,16 +119,33 @@ Bun.serve({
82119
});
83120
```
84121

85-
## 3) Open Generated Docs
122+
`createApp()` does several things at startup:
123+
124+
1. Reads decorator metadata from your controllers.
125+
2. Builds a Bun route map with validation, guards, and interceptors wired in.
126+
3. Generates an OpenAPI 3.0 document from the collected metadata.
127+
4. Optionally serves Swagger UI and the raw spec.
128+
129+
## 4) Open Generated Docs
130+
131+
Start your server and visit:
132+
133+
- **Swagger UI**: [http://localhost:3000/docs/swagger/](http://localhost:3000/docs/swagger/)
134+
- **OpenAPI JSON**: [http://localhost:3000/docs/swagger/openapi.json](http://localhost:3000/docs/swagger/openapi.json)
135+
136+
You should see your `Users` endpoints listed with their request/response schemas — all generated from the decorators you wrote. Try sending a `POST /users` with an invalid body to see validation in action.
86137

87-
- Swagger UI: /docs/swagger/
88-
- OpenAPI JSON: /docs/swagger/openapi.json
138+
## What's Next?
89139

90-
## What To Read Next
140+
Now that you have a running API, explore deeper topics:
91141

92-
- [Decorator Basics](concepts/decorators.md)
93-
- [Request Binding](guides/request-binding.md)
94-
- [Validation and Schemas](guides/validation-and-schemas.md)
142+
- **[Decorator Basics](concepts/decorators.md)** — understand the full decorator model and how layers compose.
143+
- **[Request Binding](guides/request-binding.md)** — learn about `@Param`, `@Query`, `@Header`, and scalar vs. whole-object binding.
144+
- **[Validation and Schemas](guides/validation-and-schemas.md)** — swap adapters, add constraints, and understand how validation integrates with OpenAPI.
145+
- **[Error Handling](guides/error-handling.md)** — customize error responses with `errorFormatter` and built-in exceptions.
146+
- **[Dependency Injection](guides/dependency-injection.md)** — organize code with providers and service classes.
147+
- **[Guards and Security](guides/guards-and-security.md)** — add authentication and authorization to your endpoints.
148+
- **[Descriptions and Metadata](guides/descriptions-and-metadata.md)** — enrich your OpenAPI docs with summaries, descriptions, and operation IDs.
95149

96150
## Runnable Example
97151

docs/guides/controllers-and-routes.md

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[Docs Home](../index.md) | [Previous: Request Lifecycle](../concepts/request-lifecycle.md) | [Next: Request Binding](request-binding.md)
44

5-
Use Controller subclasses with route decorators to define endpoints.
5+
Controllers are the core building block in bun-openapi. Each controller is a class that extends `Controller` and uses decorators to define its routes. At startup, `createApp()` reads this metadata and builds both Bun route handlers and the OpenAPI specification.
66

77
## Basic Pattern
88

@@ -29,28 +29,59 @@ class ProjectController extends Controller {
2929
}
3030
```
3131

32+
The `@Route("/projects")` decorator sets `/projects` as the base path. `@Get()` and `@Post()` register `GET /projects` and `POST /projects` respectively. The return value is automatically serialized as JSON.
33+
3234
## Path Joining Rules
3335

34-
- Controller prefix comes from @Route.
35-
- Method path comes from verb decorator argument.
36-
- Trailing slash aliases are handled for registered routes.
36+
The final path for each endpoint is constructed by joining the controller prefix with the method path:
37+
38+
| `@Route` | Verb decorator | Resulting path |
39+
| -------- | ---------------- | ------------------ |
40+
| `/users` | `@Get()` | `GET /users` |
41+
| `/users` | `@Get("/:id")` | `GET /users/:id` |
42+
| `/users` | `@Post("/bulk")` | `POST /users/bulk` |
43+
44+
> **TIP**: Path parameters use the `:name` syntax (e.g. `/:id`). These map to `{id}` in the generated OpenAPI spec and can be bound with `@Param("id")` or `@Param(schema)`.
3745
3846
## OpenAPI Metadata
3947

4048
Add method decorators to enrich generated operations:
4149

42-
- @Summary
43-
- @Description
44-
- @OperationId
45-
- @Tags
46-
- @Deprecated
47-
- @Hidden
50+
- `@Summary("...")` — short one-liner shown as endpoint title.
51+
- `@Description("...")` — longer explanation shown when expanded.
52+
- `@OperationId("...")` — stable identifier for SDK generators.
53+
- `@Tags("...")` — groups endpoints in Swagger UI.
54+
- `@Deprecated()` — marks the endpoint as deprecated.
55+
- `@Hidden()` — excludes the endpoint from the OpenAPI spec entirely.
56+
57+
See [Descriptions and Metadata](descriptions-and-metadata.md) for detailed examples.
4858

4959
## Choosing Response Status
5060

51-
Call this.setStatus(code) before returning to set a non-default status.
61+
By default, successful responses return status 200. Call `this.setStatus(code)` before returning to set a different status:
62+
63+
```ts
64+
@Post()
65+
@Returns(201, Project, "Created")
66+
create(@Body(CreateProject) body: CreateProject) {
67+
this.setStatus(201);
68+
return { id: crypto.randomUUID(), ...body };
69+
}
70+
```
71+
72+
## Multiple Controllers
73+
74+
Pass multiple controller classes to `createApp()`. Each controller manages its own route prefix:
75+
76+
```ts
77+
const app = createApp({
78+
schema: classValidator(),
79+
controllers: [UserController, ProjectController, HealthController],
80+
});
81+
```
5282

5383
## See Also
5484

85+
- [Descriptions and Metadata](descriptions-and-metadata.md) — making your API docs richer.
5586
- [examples/basic/controller.ts](https://github.com/xseman/bun-openapi/blob/master/examples/basic/controller.ts)
5687
- [examples/multi-controller/controllers.ts](https://github.com/xseman/bun-openapi/blob/master/examples/multi-controller/controllers.ts)

0 commit comments

Comments
 (0)