@moostjs/event-http 0.5.33 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,210 @@
1
+ # Routing & handlers — @moostjs/event-http
2
+
3
+ > Defining HTTP routes, methods, parameters, wildcards, and handler return values.
4
+
5
+ ## Concepts
6
+
7
+ Every HTTP endpoint is defined by a method decorator (`@Get`, `@Post`, etc.) on a controller method. The decorator specifies the HTTP method and optional path. Route parameters (`:param`), wildcards (`*`), and regex constraints provide flexible URL matching. Controllers group related handlers under a shared prefix.
8
+
9
+ ## API Reference
10
+
11
+ ### HTTP method decorators
12
+
13
+ All imported from `@moostjs/event-http`:
14
+
15
+ | Decorator | HTTP Method | Usage |
16
+ |-----------|-------------|-------|
17
+ | `@Get(path?)` | GET | `@Get('users/:id')` |
18
+ | `@Post(path?)` | POST | `@Post('users')` |
19
+ | `@Put(path?)` | PUT | `@Put('users/:id')` |
20
+ | `@Delete(path?)` | DELETE | `@Delete('users/:id')` |
21
+ | `@Patch(path?)` | PATCH | `@Patch('users/:id')` |
22
+ | `@All(path?)` | All methods | `@All('proxy/*')` |
23
+ | `@HttpMethod(method, path?)` | Any method | `@HttpMethod('OPTIONS', '')` |
24
+ | `@Upgrade(path?)` | UPGRADE | `@Upgrade('/ws')` |
25
+
26
+ ```ts
27
+ import { Get, Post, Put, Delete, Patch, All, HttpMethod, Upgrade } from '@moostjs/event-http'
28
+ ```
29
+
30
+ ### `@HttpMethod(method, path?)`
31
+
32
+ The base decorator — all convenience decorators (`@Get`, `@Post`, etc.) call this internally.
33
+
34
+ ```ts
35
+ @HttpMethod('HEAD', 'health')
36
+ healthCheck() { /* HEAD /health */ }
37
+
38
+ @HttpMethod('OPTIONS', '')
39
+ cors() { /* OPTIONS / */ }
40
+ ```
41
+
42
+ Valid methods: `'GET'`, `'PUT'`, `'POST'`, `'PATCH'`, `'DELETE'`, `'HEAD'`, `'OPTIONS'`, `'UPGRADE'`, `'*'`
43
+
44
+ ### `@Upgrade(path?)`
45
+
46
+ Registers an UPGRADE route for WebSocket handshakes. Use with `@moostjs/event-ws`:
47
+
48
+ ```ts
49
+ @Upgrade('/ws')
50
+ handleUpgrade(ws: WooksWs) {
51
+ return ws.upgrade()
52
+ }
53
+ ```
54
+
55
+ ### Route parameters — `@Param` and `@Params`
56
+
57
+ Imported from `moost` (not from `@moostjs/event-http`):
58
+
59
+ ```ts
60
+ import { Controller, Param, Params } from 'moost'
61
+ import { Get } from '@moostjs/event-http'
62
+
63
+ @Controller('users')
64
+ class UserController {
65
+ @Get(':id')
66
+ find(@Param('id') id: string) {
67
+ return { id } // GET /users/123
68
+ }
69
+
70
+ @Get(':type/:type/:id')
71
+ getAsset(@Params() params: { type: string[], id: string }) {
72
+ return params
73
+ }
74
+ }
75
+ ```
76
+
77
+ ## Common Patterns
78
+
79
+ ### Pattern: Path defaults
80
+
81
+ ```ts
82
+ @Get() // path = method name, e.g. GET /getUsers
83
+ getUsers() {}
84
+
85
+ @Get('') // path = controller root, e.g. GET /
86
+ root() {}
87
+
88
+ @Get('list') // explicit path, e.g. GET /list
89
+ listItems() {}
90
+ ```
91
+
92
+ ### Pattern: Multiple parameters
93
+
94
+ ```ts
95
+ // Slash-separated: /flights/SFO/LAX
96
+ @Get('flights/:from/:to')
97
+ getFlight(@Param('from') from: string, @Param('to') to: string) {}
98
+
99
+ // Hyphen-separated: /dates/2024-01-15
100
+ @Get('dates/:year-:month-:day')
101
+ getDate(
102
+ @Param('year') year: string,
103
+ @Param('month') month: string,
104
+ @Param('day') day: string,
105
+ ) {}
106
+ ```
107
+
108
+ ### Pattern: Regex-constrained parameters
109
+
110
+ ```ts
111
+ // Only matches two-digit hours and minutes: /time/09h30m
112
+ @Get('time/:hours(\\d{2})h:minutes(\\d{2})m')
113
+ getTime(@Param('hours') hours: string, @Param('minutes') minutes: string) {}
114
+ ```
115
+
116
+ ### Pattern: Repeated parameters (arrays)
117
+
118
+ ```ts
119
+ // /rgb/255/128/0 -> color = ['255', '128', '0']
120
+ @Get('rgb/:color/:color/:color')
121
+ getRgb(@Param('color') color: string[]) {}
122
+ ```
123
+
124
+ ### Pattern: Wildcards
125
+
126
+ ```ts
127
+ @Controller('static')
128
+ class StaticController {
129
+ @Get('*')
130
+ handleAll(@Param('*') path: string) {}
131
+
132
+ @Get('*.js')
133
+ handleJS(@Param('*') name: string) {}
134
+
135
+ // Multiple wildcards -> array
136
+ @Get('*/test/*')
137
+ handleTest(@Param('*') paths: string[]) {}
138
+
139
+ // Regex on wildcard: only digits
140
+ @Get('*(\\d+)')
141
+ handleNumbers(@Param('*') path: string) {}
142
+ }
143
+ ```
144
+
145
+ ### Pattern: Controller prefix
146
+
147
+ ```ts
148
+ import { Controller } from 'moost'
149
+
150
+ @Controller('api/v1/users')
151
+ class UserController {
152
+ @Get('') // GET /api/v1/users
153
+ list() {}
154
+
155
+ @Get(':id') // GET /api/v1/users/123
156
+ find() {}
157
+ }
158
+ ```
159
+
160
+ ### Pattern: Nested controllers
161
+
162
+ ```ts
163
+ import { Controller, ImportController } from 'moost'
164
+
165
+ @Controller('api')
166
+ class ApiController {
167
+ @ImportController(() => UserController)
168
+ users!: UserController
169
+
170
+ @ImportController(() => ProductController)
171
+ products!: ProductController
172
+ }
173
+ // Routes: GET /api/users/..., GET /api/products/...
174
+ ```
175
+
176
+ ## Handler return values
177
+
178
+ Whatever the handler returns becomes the response body:
179
+
180
+ | Return type | Content-Type |
181
+ |-------------|--------------|
182
+ | `string` | `text/plain` |
183
+ | object / array | `application/json` |
184
+ | `ReadableStream` | streamed |
185
+ | fetch `Response` | forwarded as-is |
186
+
187
+ ```ts
188
+ @Get('text')
189
+ getText() { return 'Hello!' } // text/plain
190
+
191
+ @Get('json')
192
+ getJson() { return { message: 'Hi' } } // application/json
193
+
194
+ @Get('data')
195
+ async getData() { return await fetchFromDb() } // async works
196
+ ```
197
+
198
+ ## Best Practices
199
+
200
+ - Use `@Get('')` (empty string) for the controller root path, not `@Get()` (which uses the method name)
201
+ - Keep controller prefixes as REST resource names: `@Controller('users')`, `@Controller('products')`
202
+ - Use `@Param` for individual route parameters, `@Params` when you need the full params object
203
+ - Prefer convenience decorators (`@Get`, `@Post`) over `@HttpMethod` for standard methods
204
+
205
+ ## Gotchas
206
+
207
+ - `@Get()` without arguments uses the **method name** as the path — this is rarely what you want
208
+ - Route parameters are always strings — use pipes to transform to numbers/booleans
209
+ - An explicit double slash `//` at the end of a path forces the URL to end with a trailing slash
210
+ - Query parameters are not part of the route path — use `@Query()` to extract them