galbe 0.1.6 → 0.1.8
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.
- package/.github/workflows/deploy_website.yml +1 -1
- package/README.md +3 -1
- package/bin/cli.ts +11 -9
- package/bun.lockb +0 -0
- package/docs/getting-started.md +221 -3
- package/docs/handler.md +1 -0
- package/docs/hooks.md +88 -0
- package/docs/plugins.md +1 -0
- package/docs/router.md +1 -0
- package/docs/routes.md +124 -0
- package/docs/schemas.md +240 -0
- package/package.json +1 -2
- package/src/index.ts +122 -219
- package/src/parser.ts +98 -100
- package/src/routes.ts +3 -1
- package/src/schema.ts +378 -0
- package/src/server.ts +6 -2
- package/src/types.ts +128 -147
- package/src/validator.ts +33 -35
- package/test/parser.test.ts +67 -67
- package/test/requests.test.ts +64 -118
- package/test/resources/test.route.comment.ts +3 -3
- package/test/responses.test.ts +3 -3
- package/test/routeFiles.test.ts +13 -0
- package/test/test.utils.ts +14 -12
- package/docs/Getting Started/basic.md +0 -1
- package/docs/Guides/routes.md +0 -1
|
@@ -16,5 +16,5 @@ jobs:
|
|
|
16
16
|
-H "Accept: application/vnd.github+json" \
|
|
17
17
|
-H "Authorization: Bearer ${{ secrets.GH_WEBSITE_TOKEN }}" \
|
|
18
18
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
|
19
|
-
https://api.github.com/repos/pierre-cm/galbe-website/actions/workflows/
|
|
19
|
+
https://api.github.com/repos/pierre-cm/galbe-website/actions/workflows/deploy.yml/dispatches \
|
|
20
20
|
-d '{"ref":"main"}'
|
package/README.md
CHANGED
package/bin/cli.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { RouteMeta } from '../src/routes'
|
|
|
5
5
|
import { program } from 'commander'
|
|
6
6
|
import { relative, resolve } from 'path'
|
|
7
7
|
import { mkdir, readdir, lstat, rm } from 'fs/promises'
|
|
8
|
-
import { metaAnalysis } from '../src/routes'
|
|
8
|
+
import { DEFAULT_ROUTE_PATTERN, metaAnalysis } from '../src/routes'
|
|
9
9
|
import { randomUUID } from 'crypto'
|
|
10
10
|
import { Galbe } from '../src'
|
|
11
11
|
|
|
@@ -14,7 +14,8 @@ const BUILD_ID = randomUUID()
|
|
|
14
14
|
|
|
15
15
|
Bun.env.FORCE_COLOR = '1'
|
|
16
16
|
|
|
17
|
-
const parseRoutes = async (routes?: string | string[]): Promise<{ path: string; meta: RouteMeta }[]> => {
|
|
17
|
+
const parseRoutes = async (routes?: boolean | string | string[]): Promise<{ path: string; meta: RouteMeta }[]> => {
|
|
18
|
+
routes = routes === true ? DEFAULT_ROUTE_PATTERN : routes
|
|
18
19
|
if (!routes) return []
|
|
19
20
|
let files: { path: string; meta: RouteMeta }[] = []
|
|
20
21
|
if (typeof routes === 'string') {
|
|
@@ -61,11 +62,12 @@ program.name('galbe').description('CLI to execute galbe utilities').version('0.1
|
|
|
61
62
|
|
|
62
63
|
program
|
|
63
64
|
.command('dev')
|
|
64
|
-
.description('
|
|
65
|
+
.description('Start a dev server running your Galbe application')
|
|
65
66
|
.argument('<string>', 'filename')
|
|
66
67
|
.option('-p, --port <number>', 'port number', '')
|
|
68
|
+
.option('-w, --watch', 'watch file changes', 'true')
|
|
67
69
|
.action(async (fileName, props) => {
|
|
68
|
-
const { port } = props
|
|
70
|
+
const { port, watch } = props
|
|
69
71
|
const devRoot = resolve(ROOT, '.galbe', 'dev')
|
|
70
72
|
await mkdir(devRoot, { recursive: true })
|
|
71
73
|
await Bun.write(
|
|
@@ -76,15 +78,15 @@ program
|
|
|
76
78
|
await rm(resolve(ROOT, '.galbe', 'dev'), { recursive: true })
|
|
77
79
|
})
|
|
78
80
|
|
|
79
|
-
await $`BUN_ENV=development bun run --watch ${resolve(devRoot, 'index.ts')}`.cwd(ROOT)
|
|
81
|
+
await $`BUN_ENV=development bun run ${watch ? '--watch' : ''} ${resolve(devRoot, 'index.ts')}`.cwd(ROOT)
|
|
80
82
|
})
|
|
81
83
|
|
|
82
84
|
program
|
|
83
85
|
.command('build')
|
|
84
|
-
.description('
|
|
86
|
+
.description('undle your Galbe application')
|
|
85
87
|
.argument('<string>', 'filename')
|
|
86
|
-
.option('-o, --out <string>', 'output file', '')
|
|
87
|
-
.option('-c, --compile', 'standalone executable', false)
|
|
88
|
+
.option('-o, --out <string>', 'output file/directory', '')
|
|
89
|
+
.option('-c, --compile', 'create a standalone executable', false)
|
|
88
90
|
.action(async (fileName, props) => {
|
|
89
91
|
const { out, compile } = props
|
|
90
92
|
const g: Galbe = (await import(resolve(ROOT, fileName))).default
|
|
@@ -97,7 +99,7 @@ program
|
|
|
97
99
|
buildIndex,
|
|
98
100
|
'--target',
|
|
99
101
|
'bun',
|
|
100
|
-
...(compile ? ['--compile', '--outfile', out ? out : '
|
|
102
|
+
...(compile ? ['--compile', '--outfile', out ? out : 'app'] : ['--outdir', out ? out : 'dist'])
|
|
101
103
|
].filter(c => c)
|
|
102
104
|
Bun.spawn(cmds, {
|
|
103
105
|
cwd: ROOT,
|
package/bun.lockb
CHANGED
|
Binary file
|
package/docs/getting-started.md
CHANGED
|
@@ -1,5 +1,223 @@
|
|
|
1
|
-
|
|
1
|
+
# Getting started
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Galbe is a Javascript web framework for building fast and versatile backend servers with Bun.
|
|
4
|
+
|
|
5
|
+
Designed with simplicity in mind, Galbe allows you to quickly create and set up a project. In addition to its ease of use, Galbe also offers a range of useful features that help you focus on the core logic of your application.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
To start developing your Galbe project, you first need to install [Bun](https://bun.sh).
|
|
10
|
+
|
|
11
|
+
## Automatic Installation
|
|
12
|
+
|
|
13
|
+
This is the recommended way of setting up a Galbe project.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun create galbe app
|
|
17
|
+
cd app
|
|
18
|
+
bun install
|
|
5
19
|
```
|
|
20
|
+
|
|
21
|
+
This will create a new project under `app` directory and install it.
|
|
22
|
+
|
|
23
|
+
Now you can start the dev server by running:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This will start a web server on `localhost:3000`.
|
|
30
|
+
|
|
31
|
+
To verify that the project was setup correctly and is running, try to reach `localhost:3000/hello` endpoint, this should return following greeting message:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
curl localhost:3000/hello
|
|
35
|
+
Hello from Galbe!
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> [!TIP]
|
|
39
|
+
> By default, the dev server automatically reloads on every file change.
|
|
40
|
+
|
|
41
|
+
## Manual Installation
|
|
42
|
+
|
|
43
|
+
Init a new Bun project and add Galbe as dependency:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bun init
|
|
47
|
+
bun add galbe
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Open `package.json` file and add the following scripts:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"scripts": {
|
|
55
|
+
"dev": "galbe dev index.ts",
|
|
56
|
+
"build": "galbe build index.ts",
|
|
57
|
+
"test": "bun test"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
As you can see, those scripts rely on Galbe CLI to run and build the application. You will find more info about Galbe CLI available options in the next section [Galbe CLI](#galbe-cli).
|
|
63
|
+
|
|
64
|
+
This require your `index.ts` to export a default Galbe instance in order to work. As in the following example:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { Galbe } from 'galbe'
|
|
68
|
+
|
|
69
|
+
const g = new Galbe({ port: 3000 })
|
|
70
|
+
g.get('/hello', () => 'Hello Mom!')
|
|
71
|
+
|
|
72
|
+
export default galbe
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This is the recommended way to proceed but it is not mandatory. Galbe instances also provide a `listen` method that will allow you to manually start your server instance from the code.
|
|
76
|
+
|
|
77
|
+
> [!WARNING]
|
|
78
|
+
> In the case you decide to not rely on Galbe CLI to run/build your app, you will not have access to [Automatic Route Analyzer](routes.md#automatic-route-analyzer) feature.
|
|
79
|
+
|
|
80
|
+
### Galbe CLI
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
galbe <command> <argument> [options]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Here are the available commands:
|
|
87
|
+
|
|
88
|
+
**dev**
|
|
89
|
+
|
|
90
|
+
Start a dev server running your Galbe application.
|
|
91
|
+
|
|
92
|
+
_argument_
|
|
93
|
+
|
|
94
|
+
The path of the file exporting your Galbe instance
|
|
95
|
+
|
|
96
|
+
_options_
|
|
97
|
+
|
|
98
|
+
- `--port` or `-p`: port number (default: 3000)
|
|
99
|
+
- `--watch` or `-w`: watch file changes (default: true)
|
|
100
|
+
|
|
101
|
+
**build**
|
|
102
|
+
|
|
103
|
+
Bundle your Galbe application.
|
|
104
|
+
|
|
105
|
+
_argument_
|
|
106
|
+
|
|
107
|
+
The path of the file exporting your Galbe instance
|
|
108
|
+
|
|
109
|
+
_options_
|
|
110
|
+
|
|
111
|
+
- `--out` or `-o`: output file | directory (default: app | dist )
|
|
112
|
+
- `--compile` or `-c`: create a standalone executable (default: false)
|
|
113
|
+
|
|
114
|
+
## Configuration
|
|
115
|
+
|
|
116
|
+
To configure your Galbe server, you should pass your configuration to the Galbe constructor when you instanciate it.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
const galbe = new Galbe(configuration)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Properties
|
|
123
|
+
|
|
124
|
+
**port**
|
|
125
|
+
|
|
126
|
+
The port number that the server will be listening on. Default is `3000`.
|
|
127
|
+
|
|
128
|
+
**basePath**
|
|
129
|
+
|
|
130
|
+
The base path is added as a prefix to all the routes created.
|
|
131
|
+
|
|
132
|
+
**routes**
|
|
133
|
+
|
|
134
|
+
A Glob Pattern or a list of Glob patterns defining the route files to be analyzed by the [Automatic Route Analyzer](routes.md#automatic-route-analyzer). Default is `src/**/*.route.{js,ts}`.
|
|
135
|
+
|
|
136
|
+
**plugin**
|
|
137
|
+
|
|
138
|
+
A property that can be used by plugins to add plugin's specific configuration. Every key should correspond to a [Unique Plugin Identifier](plugins.md).
|
|
139
|
+
|
|
140
|
+
### Examples
|
|
141
|
+
|
|
142
|
+
A common way to handle server configuration is to create new file `galbe.config.(js|ts|json)` at the root of your project directory and import it in your code. Here is an example:
|
|
143
|
+
|
|
144
|
+
galbe.config.js
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
export default {
|
|
148
|
+
port: Bun.env.GALBE_PORT
|
|
149
|
+
routes: 'src/**/*.route.ts',
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
index.js
|
|
154
|
+
|
|
155
|
+
```js
|
|
156
|
+
import { Galbe } from 'galbe'
|
|
157
|
+
import config from './galbe.config'
|
|
158
|
+
|
|
159
|
+
export default new Galbe(config)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> [!TIP]
|
|
163
|
+
> If you are using Typescript, you can import `GalbeConfig` type from galbe package to ensure type consistency for your configuration. Here is an example:
|
|
164
|
+
>
|
|
165
|
+
> ```ts
|
|
166
|
+
> import type { GalbeConfig } from 'galbe'
|
|
167
|
+
> const config: GalbeConfig = {
|
|
168
|
+
> port: Number(Bun.env.GALBE_PORT),
|
|
169
|
+
> routes: 'routes/*.route.ts'
|
|
170
|
+
> }
|
|
171
|
+
> export default config
|
|
172
|
+
> ```
|
|
173
|
+
|
|
174
|
+
## Project Structure
|
|
175
|
+
|
|
176
|
+
One key aspect of Galbe, is its versatility in terms of project structure. This is partly allowed by the [Automatic Route Analyzer](routes.md#automatic-route-analyzer) and the `routes` config property which defaults to `src/**/*.route.{js,ts}`.
|
|
177
|
+
|
|
178
|
+
Here are two examples of valid project structures by default:
|
|
179
|
+
|
|
180
|
+
**Example 1**
|
|
181
|
+
|
|
182
|
+
```txt
|
|
183
|
+
┌── src
|
|
184
|
+
│ ├── hooks
|
|
185
|
+
│ │ └── log.hook.ts
|
|
186
|
+
│ ├── routes
|
|
187
|
+
│ │ ├── foo.route.ts
|
|
188
|
+
│ │ └── foo.route.ts
|
|
189
|
+
│ └── schemas
|
|
190
|
+
│ ├── bar.schema.ts
|
|
191
|
+
│ └── bar.schema.ts
|
|
192
|
+
├── galbe.config.ts
|
|
193
|
+
├── index.ts
|
|
194
|
+
├── package.json
|
|
195
|
+
├── README.md
|
|
196
|
+
└── tsconfig.json
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**Example 2**
|
|
200
|
+
|
|
201
|
+
```txt
|
|
202
|
+
┌── src
|
|
203
|
+
│ ├── hooks
|
|
204
|
+
│ │ └── log.hook.ts
|
|
205
|
+
│ ├── foo
|
|
206
|
+
│ │ ├── foo.route.ts
|
|
207
|
+
│ │ └── foo.schema.ts
|
|
208
|
+
│ └── bar
|
|
209
|
+
│ ├── bar.route.ts
|
|
210
|
+
│ └── bar.schema.ts
|
|
211
|
+
├── galbe.config.ts
|
|
212
|
+
├── index.ts
|
|
213
|
+
├── package.json
|
|
214
|
+
├── README.md
|
|
215
|
+
└── tsconfig.json
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
In both cases, the [Automatic Route Analyzer](routes.md#automatic-route-analyzer) will analyze `foo.route.ts` and `bar.route.ts` Route Files to find route definitions.
|
|
219
|
+
|
|
220
|
+
You can find more info about Route Files definition in the [Routes Files](routes.md#route-files) section.
|
|
221
|
+
|
|
222
|
+
> [!NOTE]
|
|
223
|
+
> The examples provided above will work with the default configuration, but you can easily customize the routes property to fit your own project structure. Simply redefine the `routes` property with your own pattern(s) to to fit your own project structure.
|
package/docs/handler.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Handler
|
package/docs/hooks.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Hooks
|
|
2
|
+
|
|
3
|
+
Hooks provide a simple way to perform specific actions before and/or after reaching a specific route endpoint.
|
|
4
|
+
|
|
5
|
+
## Hook Definition
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
const hook = (context, next) => {
|
|
9
|
+
context.state['foo'] = 'bar'
|
|
10
|
+
await next()
|
|
11
|
+
console.log('Hook end')
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The hook takes only two arguments, a `context` object and a `next` function.
|
|
16
|
+
|
|
17
|
+
**context**
|
|
18
|
+
|
|
19
|
+
The `context` object contains the request information along with a state property that is modifiable and preserved across all hooks and the handler. It is useful for sharing information or objects across hooks and handler. You can find more information about it in the [Context]() section.
|
|
20
|
+
|
|
21
|
+
**next**
|
|
22
|
+
|
|
23
|
+
The `next` function calls the next hook in the hook list or the handler if the current hook is the last one declared. The `next` function should be called at most once. If it is omitted, Galbe will call it automatically at the end of the execution of the current hook.
|
|
24
|
+
|
|
25
|
+
> [!TIP]
|
|
26
|
+
> Hooks are interruptible objects, meaning they can return a response at any moment. This provides a powerful mechanism for implementing custom logic, such as authentication, authorization, caching, and more."
|
|
27
|
+
|
|
28
|
+
## Hooks Declaration
|
|
29
|
+
|
|
30
|
+
Hooks should be declared just before the handler method in the [Route Definition]() method as a list of Hooks.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
galbe.get('foo', [ hook1, hook2, ... ], ctx => {})
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Hooks are called just before the [Handler]() in the order that they have been declared in the hook list of the [Route Definition](). To get a better understanding of hooks execution during the request lifecycle, you can refer to the [Lifecycle]() section.
|
|
37
|
+
|
|
38
|
+
### Examples
|
|
39
|
+
|
|
40
|
+
Linear hooks declaration:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const hook1 = context => {
|
|
44
|
+
console.log('hook1 called')
|
|
45
|
+
}
|
|
46
|
+
const hook2 = context => {
|
|
47
|
+
console.log('hook2 called')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
galbe.get('example', [hook1, hook2], ctx => {
|
|
51
|
+
console.log('handler')
|
|
52
|
+
})
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
curl http://localhost:3000/example
|
|
57
|
+
hook1
|
|
58
|
+
hook2
|
|
59
|
+
handler
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Nested hooks declaration:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const hook1 = (context, next) => {
|
|
66
|
+
console.log('hook1 start')
|
|
67
|
+
await next()
|
|
68
|
+
console.log('hook1 end')
|
|
69
|
+
}
|
|
70
|
+
const hook2 = context => {
|
|
71
|
+
console.log('hook2 start')
|
|
72
|
+
await next()
|
|
73
|
+
console.log('hook2 end')
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
galbe.get('example', [hook1, hook2], ctx => {
|
|
77
|
+
console.log('handler')
|
|
78
|
+
})
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
curl http://localhost:3000/example
|
|
83
|
+
hook1 start
|
|
84
|
+
hook2 start
|
|
85
|
+
handler
|
|
86
|
+
hook2 end
|
|
87
|
+
hook1 end
|
|
88
|
+
```
|
package/docs/plugins.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Plugins
|
package/docs/router.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Router
|
package/docs/routes.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Routes
|
|
2
|
+
|
|
3
|
+
Routes are the entry points for handling client requests in a Galbe application. In this section, we'll cover how to define routes, the various options available for route definitions, and how to use the Automatic Route Analyzer to simplify route setup.
|
|
4
|
+
|
|
5
|
+
## Route Definition
|
|
6
|
+
|
|
7
|
+
Here is how to define routes in Galbe.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
galbe.[method](path: string, schema?: Schema, hooks?: Hooks[], handler: Handler)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**method** ( get | post | put | delete | patch | options )
|
|
14
|
+
|
|
15
|
+
The [HTTP Request Method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) for the defined route.
|
|
16
|
+
|
|
17
|
+
**path** (string)
|
|
18
|
+
|
|
19
|
+
The path of the route. It should be composed of a sequence of segments separated by `/`. Each segment can be composed alphanumeric characters and dashes, but should not start or end with a dash.
|
|
20
|
+
|
|
21
|
+
There are two special segments:
|
|
22
|
+
|
|
23
|
+
- `:param` Any segment starting with `:` indicates a parameter segment.
|
|
24
|
+
- `*` To indicate a wildcard segment. This will match any segment or sequence of segments.
|
|
25
|
+
|
|
26
|
+
**schema** (Schema) _Optional_
|
|
27
|
+
|
|
28
|
+
See [Schemas](schemas.md) section.
|
|
29
|
+
|
|
30
|
+
**hooks** (Hook[]) _Optional_
|
|
31
|
+
|
|
32
|
+
See [Hooks](hooks.md) section.
|
|
33
|
+
|
|
34
|
+
**handler** (Handler)
|
|
35
|
+
|
|
36
|
+
See [Handler](handler.md) section.
|
|
37
|
+
|
|
38
|
+
### Examples
|
|
39
|
+
|
|
40
|
+
**Basic route**
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
galbe.get('/foo', ctx => 'Hello World!')
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Route with Schema**
|
|
47
|
+
|
|
48
|
+
<!-- prettier-ignore -->
|
|
49
|
+
```js
|
|
50
|
+
galbe.get(
|
|
51
|
+
'/foo/:bar',
|
|
52
|
+
{ params: { bar: $T.string() } },
|
|
53
|
+
ctx => `Hello ${ctx.params.bar} !`
|
|
54
|
+
)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Route with Hooks**
|
|
58
|
+
|
|
59
|
+
<!-- prettier-ignore -->
|
|
60
|
+
```js
|
|
61
|
+
galbe.get(
|
|
62
|
+
'/foo/:bar',
|
|
63
|
+
[() => console.log('Hook1'), () => console.log('Hook2')],
|
|
64
|
+
ctx => `Hello ${ctx.params.bar} !`
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Route with Schemas and Hooks**
|
|
69
|
+
|
|
70
|
+
<!-- prettier-ignore -->
|
|
71
|
+
```js
|
|
72
|
+
galbe.get(
|
|
73
|
+
'/foo/:bar',
|
|
74
|
+
{ params: { bar: $T.string() } },
|
|
75
|
+
[() => console.log('Hook')],
|
|
76
|
+
ctx => `Hello ${ctx.params.bar} !`
|
|
77
|
+
)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Automatic Route Analyzer
|
|
81
|
+
|
|
82
|
+
> [!NOTE]
|
|
83
|
+
> This feature is only available if you run/build the app via the [Galbe CLI](getting-started.md#galbe-cli), which is the case by default if you created your app following the [Automatic Installation](getting-started.md#automatic-installation) step or if you configured your package.json to do so.
|
|
84
|
+
|
|
85
|
+
The Automatic Route Analyzer is responsible for analyzing all the Route Files of your project and setting up the route definitions for your Galbe server automatically. By default, the analyzer will search for Route Files matching paths like `src/**/*.route.{js,ts}`. This can be configured by modifying the value of `routes` property of your Galbe configuration. A value of `false` will disable the analyzer.
|
|
86
|
+
|
|
87
|
+
### Route Files
|
|
88
|
+
|
|
89
|
+
In order to be properly analyzed, Route Files must export a default function that takes a Galbe instance as unique argument. Your routes should be defined using that Galbe instance. Here's a basic example in JavaScript:
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
export default g => {
|
|
93
|
+
g.get('/foo/:bar', ctx => ctx.params.bar)
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The same example in Typescript:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
import type { Galbe } from 'galbe'
|
|
101
|
+
export default (g: Galbe) => {
|
|
102
|
+
g.get('/foo/:bar', ctx => ctx.params.bar)
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The Automatic Route Analyzer can also collect metadata about your Route File and your routes by analyzing multiline comments. This can be used by some plugins to perform specific tasks. Here's an example of a Route File with multiline comment metadata:
|
|
107
|
+
|
|
108
|
+
```js
|
|
109
|
+
/**
|
|
110
|
+
* This is the header's head comment
|
|
111
|
+
* @annotation example of header's annotation
|
|
112
|
+
*/
|
|
113
|
+
export default g => {
|
|
114
|
+
/**
|
|
115
|
+
* This is a route head comment
|
|
116
|
+
* @deprecated
|
|
117
|
+
* @tag tag1
|
|
118
|
+
* @tag tag2
|
|
119
|
+
*/
|
|
120
|
+
g.get('/foo/:bar', ctx => ctx.params.bar)
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
You will find more information about comment metadata and how to use them along with examples in the [Plugin](plugins.md) section.
|