Multiple APIs
This tutorial mirrors the examples/http multiple-apis app. It shows how to split an app into feature modules with their own prefixes, validation, and feature-local not-found handling.
Create A Feature Module
import { Controller, Logger, Module, optional, UsePrefix } from '@bunito/bunito';
import { Get, Params } from '@bunito/http';
import { z } from 'zod';
const FooParams = z.object({
foo: z.string().max(2),
});
@Controller('/', {
injects: [optional(Logger)],
scope: 'singleton',
})
class FooController {
constructor(private readonly logger: Logger | null) {}
@Get('/:foo', {
injects: [Params(FooParams)],
})
getFoo(params: Params<typeof FooParams>): Response {
return new Response(`foo: ${params.foo}`);
}
}
@Module({
controllers: [FooController],
})
@UsePrefix('/foo')
class FooModule {}Every route in FooModule is mounted under /foo.
Add Another API Module
import { Controller, Logger, Module, optional, UsePrefix } from '@bunito/bunito';
import { Get, NotFoundException, Params } from '@bunito/http';
import { z } from 'zod';
const BarParams = z.object({
bar: z.string().max(2),
});
@Controller('/', {
injects: [optional(Logger)],
scope: 'singleton',
})
class BarController {
constructor(private readonly logger: Logger | null) {}
@Get('/:bar', {
injects: [Params(BarParams)],
})
getBar(params: Params<typeof BarParams>): Response {
return Response.json({
action: 'getBar',
params,
});
}
@Get()
@Get('/*')
notFound(): never {
throw new NotFoundException();
}
}
@Module({
controllers: [BarController],
})
@UsePrefix('/bar')
class BarModule {}BarModule owns its /bar route group and declares a catch-all not-found handler for paths under that prefix.
Compose The App
import { Module } from '@bunito/bunito';
@Module({
imports: [FooModule, BarModule],
})
class AppModule {}The repository example gets shared HTTP, logger, config, and root response setup from ExampleModule:
import { App } from '@bunito/bunito';
import { ExampleModule } from '@libs/example';
import { AppModule } from './app.module';
await App.start({
imports: [ExampleModule.forRoot('multiple-apis'), AppModule],
});In the repository examples, this app lives at examples/http/apps/multiple-apis/src/main.ts. Its port is defined in examples/http/apps/multiple-apis/.env.
Run it:
cd examples/http
bun run start multiple-apisRequest examples are available in examples/http/apps/multiple-apis/requests.http.
You now have two route groups:
/foo/*: simple text responses/bar/*: JSON responses and a local not-found fallback
Continue with CORS Support to add route headers and CORS policy to HTTP modules.
