To fully understand and follow this guide, it is important to have:
Node.js runtime installed on your computer.
Some basic knowledge of working with Nest.js
A working MongoDB setup. This can be the locally installed MongoDB. Ensure you have the MongoDB compass installed.
To create any Nest.js you need Nest.js installed. This will allow us to scaffold a basic Nest.js application instead of building everything from scratch.
npm install -g @nestjs/cli
Once the above command is executed, navigate to a folder where you want the Nest.js app to live. Open the folder using a text editor such as VS code. Finally, create Nest.js using the following command:
nest new nest-crud-api
This will create a nest-crud-api and scaffold a basic Nest.js app. To create this application, we need some Node.js packages. These are:
@nestjs/mongoose
Mongoose
To install them, change the directory to nest-crud-api
:
cd nest-crud-api
Then run the following commands to install them:
npm install mongoose @nestjs/mongoose
We will use MongoDB to save the employee details. Here we will use Mongoose to simplify the database interactions. At this point, ensure you have MongoDB up and running. Then create the configuration file to communicate with MongoDB. To create the configuration, navigate to the src/app.module.ts:
Import Mongoose
import { MongooseModule } from '@nestjs/mongoose';
Set up the MongooseModule
inside the module imports as follows:
1 2 3 4
@Module({ imports: [ MongooseModule.forRoot('mongodb://localhost:27017/Employee'), ]
Here, ensure you have the MongoDB URI that points to your database. Parameter Employee
represents the database that Mongoose will create to save user details.
A schema will represent the database representation of an employee. We will use Mongoose schema to create this database representation. Inside the src folder, create a schema folder, and inside this directory create an employee.schema.ts file. Finally, represent the employee database as shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import {
Prop,
Schema,
SchemaFactory
} from '@nestjs/mongoose';
import {
Document
} from 'mongoose';
export type EmployeeDocument = Employee & Document;
@Schema()
export class Employee {
@Prop()
FirstName: string;
@Prop()
SurName: string;
@Prop()
Designation: string;
@Prop()
Email: string;
@Prop()
Address: string;
@Prop()
Salary: string;
@Prop()
Gender: string;
}
export const EmployeeSchema = SchemaFactory.createForClass(Employee);
An interface in a typescript class is used for checking types. We need to check every data entry and make sure it matches the data we want to be added to the database. Go ahead and create an entities
directory inside the src
folder. Inside the entities
folder, create an employee.entity.ts
and set up the interface as follows:
1
2
3
4
5
6
7
8
9
export class Employee {
FirstName: string;
SurName: string;
Gender: string;
Designation: string;
Email: string;
Address: string;
Salary: string;
}
DTO stands for Data Transfer Object. It encapsulates the data and defines how it will be transmitted over the network. Inside the src
folder, create a dto
directory. Here we are creating a CRUD application. Thus we need to define DTO for adding and manipulating employee data.
To create an employee and transmit the data to the internet create a create-employee.dto.ts
file and add the following CreateEmployeeDto
class:
1
2
3
4
5
import {
Employee
} from "../entities/employee.entity";
export class CreateEmployeeDto extends Employee {}
To update and change employee data and transmit the data to the internet, create an update-employee.dto.ts
file and add the following UpdateEmployeeDto
class:
1
2
3
4
5
6
7
8
import {
PartialType
} from '@nestjs/mapped-types';
import {
CreateEmployeeDto
} from './create-employee.dto';
export class UpdateEmployeeDto extends PartialType(CreateEmployeeDto) {}
A service handles the logic of a Nest.js API, the database interactions, and returning the appropriate responses. This service will define how the API communicates with the database to perform different operations using Mongoose. This includes:
Adding employee using create()
Fetching employee (s) findAll() and findOne.
Updating an employee using update()
Deleting an employee using remove()
To create a service to execute these methods create an employee.service.ts
file inside the src
folder as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import {
Injectable
} from '@nestjs/common';
import {
InjectModel
} from '@nestjs/mongoose';
import {
Model
} from 'mongoose';
import {
CreateEmployeeDto
} from './dto/create-employee.dto';
import {
UpdateEmployeeDto
} from './dto/update-employee.dto';
import {
Employee,
EmployeeDocument
} from './schema/employee.schema';
@Injectable()
export class EmployeeService {
constructor(@InjectModel(Employee.name) private readonly employeeModel: Model < EmployeeDocument > ) {}
async create(createEmployeeDto: CreateEmployeeDto): Promise < EmployeeDocument > {
const employee = new this.employeeModel(createEmployeeDto);
return employee.save();
}
async findAll(): Promise < EmployeeDocument[] > {
return this.employeeModel.find()
.exec();
}
async findOne(id: string) {
return this.employeeModel.findById(id);
}
async update(id: string, updateEmployeeDto: UpdateEmployeeDto): Promise < EmployeeDocument > {
return this.employeeModel.findByIdAndUpdate(id, updateEmployeeDto);
}
async remove(id: string) {
return this.employeeModel.findByIdAndRemove(id);
}
}
Controllers allow creating routes to execute the created service logic. This lets you create and handle HTTP calls for the API. To handle incoming requests and responses, create an employee.controller.ts
file inside the src
directory and add the following controllers using the HTTP methods (GET, POST, PUT, DELETE):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import {
Controller,
Get,
Post,
Body,
Param,
Delete,
Put
} from '@nestjs/common';
import {
EmployeeService
} from './employee.service';
import {
CreateEmployeeDto
} from './dto/create-employee.dto';
import {
UpdateEmployeeDto
} from './dto/update-employee.dto';
@Controller('employee')
export class EmployeeController {
constructor(private readonly employeeService: EmployeeService) {}
@Post()
create(@Body() createEmployeeDto: CreateEmployeeDto) {
return this.employeeService.create(createEmployeeDto);
}
@Get()
findAll() {
return this.employeeService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.employeeService.findOne(id);
}
@Put(':id')
update(@Param('id') id: string, @Body() updateEmployeeDto: UpdateEmployeeDto) {
return this.employeeService.update(id, updateEmployeeDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.employeeService.remove(id);
}
}
To execute the above logic, we need a module. This will execute the controllers and providers (service). To create a module, add a new file to the src
directory and call it employee.module.ts
and add the following code block:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import {
Module
} from '@nestjs/common';
import {
EmployeeService
} from './employee.service';
import {
EmployeeController
} from './employee.controller';
import {
Employee,
EmployeeSchema
} from './schema/employee.schema';
import {
MongooseModule
} from '@nestjs/mongoose';
@Module({
imports: [
MongooseModule.forFeature([
{
name: Employee.name,
schema: EmployeeSchema
},
])
],
controllers: [EmployeeController],
providers: [EmployeeService]
})
export class EmployeeModule {}
For this module to be executed by Nest.js, we need to add the controllers and providers (service) inside the employee.module.ts to the app.module.ts file as follows:
Add the employee.module.ts import:
import { EmployeeModule } from './employee/employee.module';
Execute the module inside the
1 2 3 4 5
@Module({ imports: [ MongooseModule.forRoot('mongodb://localhost:27017/Employee'), EmployeeModule ],
At this point you should have the following project structure:
+---src
| | app.controller.ts
| | app.module.ts
| | app.service.ts
| | main.ts
| |
| \---employee
| | employee.controller.ts
| | employee.module.ts
| | employee.service.ts
| |
| +---dto
| | create-employee.dto.ts
| | update-employee.dto.ts
| |
| +---entities
| | employee.entity.ts
| |
| \---schema
| employee.schema.ts
To test the application run:
npm run start
This will successfully start the application on port 3000.
Then test the API endpoints using postman as follows:
Add an employee
Fetch all employees
Fetch single employee by ID
Update an employee
Delete an employee
Note: the 62fa9320e04265c1a53efa48
value is the ID of an employee saved when creating that employee.