$ nest new platzi-store
$ nest g controller products
$ nest g s services/products
$ nest g pipe services/products
// src/app.module.ts
import { Module, HttpModule, HttpService } from '@nestjs/common'; // π imports
@Module({
imports: [HttpModule, UsersModule, ProductsModule],
controllers: [AppController],
providers: [
imports: [HttpModule, UsersModule, ProductsModule], // π add HttpModule
...,
{
provide: 'TASKS',
useFactory: async (http: HttpService) => { // π implement useFactory
const tasks = await http
.get('https://jsonplaceholder.typicode.com/todos')
.toPromise();
return tasks.data;
},
inject: [HttpService],
},
],
})
export class AppModule {}
// src/app.service.ts
import { Injectable, Inject } from '@nestjs/common';
@Injectable()
export class AppService {
constructor(
@Inject('API_KEY') private apiKey: string,
@Inject('TASKS') private tasks: any[], // π inject TASKS
) {}
getHello(): string {
console.log(this.tasks); // π print TASKS
return `Hello World! ${this.apiKey}`;
}
}
We can create a global module, and have global env, and also services in order to avoid cirluar dependecies
// src/database/database.module.ts
import { Module, Global } from '@nestjs/common';
const API_KEY = '12345634';
const API_KEY_PROD = 'PROD1212121SA';
@Global()
@Module({
providers: [
{
provide: 'API_KEY',
useValue: process.env.NODE_ENV === 'prod' ? API_KEY_PROD : API_KEY,
},
],
exports: ['API_KEY'],
})
export class DatabaseModule {}
// src/app.module.ts
...
import { DatabaseModule } from './database/database.module';
@Module({
imports: [
HttpModule,
UsersModule,
ProductsModule,
DatabaseModule // π Use DatabaseModule like global Module
],
...
})
export class AppModule {}
// src/users/services/users.service.ts
import { Injectable, NotFoundException, Inject } from '@nestjs/common';
..
@Injectable()
export class UsersService {
constructor(
private productsService: ProductsService,
@Inject('API_KEY') private apiKey: string, // π Inject API_KEY
) {}
}
$ npm i @nestjs/config
- Create 2 files and fill them with the info .stag.env and .prod.env
- create a new file src/environments.ts
export const enviroments = {
dev: '.env',
stag: '.stag.env',
prod: '.prod.env',
};
- Them, modify the AppModule
// src/app.module.ts
...
import { enviroments } from './enviroments'; // π
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: enviroments[process.env.NODE_ENV] || '.env', // π
isGlobal: true,
}),
...
],
...
})
export class AppModule {}
$ npm i joi
// src/app.module.ts
import * as Joi from 'joi'; // π
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: enviroments[process.env.NODE_ENV] || '.env',
load: [config],
isGlobal: true,
validationSchema: Joi.object({ // π
API_KEY: Joi.number().required(),
DATABASE_NAME: Joi.string().required(),
DATABASE_PORT: Joi.number().required(),
}),
}),
...
],
...
})
export class AppModule {}
$ npm install --save @nestjs/swagger swagger-ui-express
// src/main.ts
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
...
const config = new DocumentBuilder()
.setTitle('API')
.setDescription('PLATZI STORE')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
...
await app.listen(3000);
}
bootstrap();
Add plugin compilerOptions
# nest-cli.json
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger/plugin"]
}
}
Replace PartialType on DTOs with swagger
// src/products/dtos/brand.dtos.ts
import { PartialType } from '@nestjs/swagger';
Using same @nest/swagger, import ApiProperty in order to use in DTOs and ApiOperation to add a summary in each route of your controllers
In this case we use docker to create the mongoDB image and mongoCompass to work and add some data(tasks). Once you have this done, keep the next steps
$ npm i mongodb
Types as a Dev dependencies
$ npm i @types/mongodb -D
# src/app.module.ts
import { MongoClient } from 'mongodb';
const uri = 'mongodb://root:root@localhost:27017/?authSource=admin&readPreference=primary';
const client = new MongoClient(uri);
async function run() {
await client.connect();
const database = client.db('platzi-store');
const taskCollection = database.collection('tasks');
const tasks = await taskCollection.find().toArray();
console.log(tasks);
}
run();
npm install --save @nestjs/mongoose mongoose
// src/database/database.module.ts
import { MongooseModule } from '@nestjs/mongoose'; // π Import
@Global()
@Module({
imports: [
// π
MongooseModule.forRootAsync({
// π Implement Module
useFactory: (configService: ConfigType<typeof config>) => {
const {
connection,
user,
password,
host,
port,
dbName,
} = configService.mongo;
return {
uri: `${connection}://${host}:${port}`,
user,
pass: password,
dbName,
};
},
inject: [config.KEY],
}),
],
providers: [
{
provide: 'API_KEY',
inject: [config.KEY],
},
],
exports: ['API_KEY', 'MONGO', MongooseModule], // π add in exports
})
export class DatabaseModule {}
// src/products/entities/product.entity.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
@Schema()
export class Product extends Document {
@Prop({ required: true })
name: string;
@Prop()
description: string;
@Prop({ type: Number })
price: number;
@Prop({ type: Number })
stock: number;
@Prop()
image: string;
}
export const ProductSchema = SchemaFactory.createForClass(Product);
// src/products/products.module.ts
...
import { MongooseModule } from '@nestjs/mongoose';
import { Product, ProductSchema } from './entities/product.entity';
@Module({
imports: [
MongooseModule.forFeature([
{
name: Product.name,
schema: ProductSchema,
},
]),
],
...
})
export class ProductsModule {}
A progressive Node.js framework for building efficient and scalable server-side applications.
Nest framework TypeScript starter repository.
$ npm install
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
- Author - Kamil MyΕliwiec
- Website - https://nestjs.com
- Twitter - @nestframework
Nest is MIT licensed.