Basic Architecture of Sport Web
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import 'reflect-metadata';
|
||||
|
||||
import { VersioningType } from '@nestjs/common';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import type { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||
import compression from 'compression';
|
||||
import helmet from 'helmet';
|
||||
import { Logger } from 'nestjs-pino';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { CURRENT_API_VERSION } from './common/constants/api';
|
||||
import { requestIdMiddleware } from './common/middleware/request-id.middleware';
|
||||
import { APP_CONFIG } from './config/app-config.module';
|
||||
import type { AppConfig } from './config/configuration';
|
||||
|
||||
async function bootstrap(): Promise<void> {
|
||||
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
|
||||
// Buffer startup logs until the pino logger is attached, so boot output is
|
||||
// structured too rather than a mix of two formats.
|
||||
bufferLogs: true,
|
||||
});
|
||||
|
||||
const config = app.get<AppConfig>(APP_CONFIG);
|
||||
|
||||
app.useLogger(app.get(Logger));
|
||||
app.flushLogs();
|
||||
|
||||
// Behind Nginx: required for correct client IPs in rate limiting and logs.
|
||||
app.set('trust proxy', 1);
|
||||
|
||||
// First in the chain: every log line and error response carries this id.
|
||||
app.use(requestIdMiddleware);
|
||||
app.use(helmet({ crossOriginResourcePolicy: { policy: 'cross-origin' } }));
|
||||
app.use(compression());
|
||||
|
||||
app.enableCors({
|
||||
origin: [...config.app.corsOrigins],
|
||||
credentials: true,
|
||||
exposedHeaders: ['x-request-id'],
|
||||
});
|
||||
|
||||
app.setGlobalPrefix(config.app.globalPrefix);
|
||||
|
||||
/**
|
||||
* URI versioning: /api/v1/products.
|
||||
*
|
||||
* Chosen over headers because it is visible in logs, cacheable by CDN path,
|
||||
* trivially testable with curl, and unambiguous for the mobile app and
|
||||
* partner integrations that will follow. See ADR-0005.
|
||||
*/
|
||||
app.enableVersioning({
|
||||
type: VersioningType.URI,
|
||||
defaultVersion: CURRENT_API_VERSION,
|
||||
});
|
||||
|
||||
app.enableShutdownHooks();
|
||||
|
||||
if (!config.app.isProduction) {
|
||||
const swaggerConfig = new DocumentBuilder()
|
||||
.setTitle('Sport Store API')
|
||||
.setDescription('REST API for the storefront and admin dashboard.')
|
||||
.setVersion(config.app.version)
|
||||
.addBearerAuth({ type: 'http', scheme: 'bearer', bearerFormat: 'JWT' })
|
||||
.build();
|
||||
|
||||
SwaggerModule.setup('docs', app, SwaggerModule.createDocument(app, swaggerConfig), {
|
||||
jsonDocumentUrl: 'docs/json',
|
||||
});
|
||||
}
|
||||
|
||||
await app.listen(config.app.port, '0.0.0.0');
|
||||
}
|
||||
|
||||
void bootstrap();
|
||||
Reference in New Issue
Block a user