Prerequisites
- Installed Node version of
v20.10.0
- Installed PostgreSQL version of
16
Initialize NestJS application
I'm assuming that you have already created project directories just like what I did in the first post.
-
Install nest cli globally using
command prompt
.
npm i -g @nestjs/cli
Open new
command prompt
from thenest-service
directory.-
Create new NestJS project by running command below. I choose
npm
as the package manager.
nest new .
-
Install these dependencies:
Dependency to work with .env file
npm i --save @nestjs/config
TypeOrm dependencies
npm install @nestjs/typeorm typeorm
PostgreSQL dependency
npm install pg
My
package.json
dependencies looks like:
"dependencies": { "@nestjs/common": "^10.0.0", "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", "@nestjs/typeorm": "^10.0.1", "pg": "^8.11.3", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "typeorm": "^0.3.17" }
-
Create project directory skeleton that looks like this:
nest-service/ ├── src/ │ ├── config/ │ ├── controllers/ │ ├── entities/ │ ├── modules/ │ ├── services/ │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ └── main.ts ├── .env └── package.json
-
My
.env
file looks like below. Makesure that you have correct and working port and credentials.
PORT=3002 DB_HOST=localhost DB_PORT=5432 DB_USERNAME=postgres DB_PASSWORD=password DB_NAME=customer
Creating configuration
Inside config
directory, create a file named database.config.ts
the content will look like this:
import { PostgresConnectionOptions } from "typeorm/driver/postgres/PostgresConnectionOptions";
import { ConfigService } from '@nestjs/config';
export const databaseConfig = async (configService: ConfigService): Promise<PostgresConnectionOptions> => ({
type: 'postgres',
host: configService.get<string>('DB_HOST'),
port: parseInt(configService.get<string>('DB_PORT')),
username: configService.get<string>('DB_USERNAME'),
password: configService.get<string>('DB_PASSWORD'),
database: configService.get<string>('DB_NAME'),
entities: ["dist/**/*.entity{.ts,.js}"],
synchronize: false,
});
creating entities
Now, let's move on to entities
directory. Create a file called Customer.enitity.ts
.
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
@Entity('customers')
export class Customer {
@PrimaryGeneratedColumn()
id: number;
@Column()
no: string;
@Column()
nama: string;
@Column()
alamat: string
@Column()
kota: string
@CreateDateColumn()
createdAt: Date
@UpdateDateColumn()
updatedAt: Date;
}
Creating services
In services we are going to create a file named customer.service.ts
and the content is looks like this:
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { randomUUID } from "crypto";
import { Customer } from "src/entities/Customer.entity";
import { Repository } from "typeorm";
export interface CustomerInterface {
id?: string,
no?: string,
nama: string,
alamat: string,
kota: string
createdAt?: Date;
updatedAt?: Date;
};
@Injectable()
export class CustomersService {
constructor(
@InjectRepository(Customer)
private customerRepository: Repository<CustomerInterface>
) {}
create(customer: CustomerInterface): Promise<CustomerInterface> {
const customerBody = this.customerRepository.create(customer);
customerBody.no = randomUUID();
customerBody.createdAt = new Date();
customerBody.updatedAt = new Date();
return this.customerRepository.save(customerBody);
}
findAll(): Promise<CustomerInterface[]> {
return this.customerRepository.find();
}
findById(id: string): Promise<CustomerInterface> {
return this.customerRepository
.findOne({
where: {
id: id
}
});
}
update(id: string, data: CustomerInterface): Promise<any> {
return this.customerRepository
.createQueryBuilder()
.update()
.set({
nama: data.nama,
alamat: data.alamat,
kota: data.kota
})
.where('id = :id', { id })
.execute();
}
delete(id: string): Promise<any> {
return this.customerRepository
.createQueryBuilder()
.delete()
.from(Customer)
.where('id = :id', { id })
.execute();
}
}
Creating controllers
Let's create the controller for customer by making a file called customer.controller.ts
inside controllers
directory.
import { Body, Controller, Delete, Get, Param, Post, Put } from "@nestjs/common";
import { CustomerInterface, CustomersService } from "src/services/customer.service";
interface CreateCustomerDto {
nama: string,
alamat: string,
kota: string
};
@Controller('api/customers')
export class CustomersController {
constructor(private customerService: CustomersService) {}
@Post()
async create(@Body() createCustomerDto: CreateCustomerDto) {
const customer = await this.customerService.create(createCustomerDto);
if(!customer) {
return 'Error creating customer';
}
return 'Customer created successfully';
}
@Get()
async findAll() {
const customers: Array<CustomerInterface> = await this.customerService.findAll();
return customers;
}
@Get(':id')
async findByNama(@Param('id') id: string ) {
const customer: CustomerInterface = await this.customerService.findById(id);
return customer;
}
@Put(':id')
async update(@Param('id') id: string, @Body() body: CustomerInterface) {
const newCustomer: CustomerInterface = await this.customerService.update(id, body);
if(!newCustomer) {
return 'Error updating customer';
}
return 'Customer updated successfully';
}
@Delete(':id')
async remove(@Param('id') id: string) {
await this.customerService.delete(id);
return 'Successfully deleted customer with id' + id;
}
}
Creating module
Last, we need to pool our entity
, controller
, and service
at the module
. Create a file called customer.module.ts
inside modules
directory.
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CustomersController } from 'src/controllers/customer.controller';
import { Customer } from 'src/entities/Customer.entity';
import { CustomersService } from 'src/services/customer.service';
@Module({
imports: [TypeOrmModule.forFeature([Customer])],
controllers: [CustomersController],
providers: [CustomersService]
})
export class CustomersModule {}
Configuring customer module in main module
In app.module.ts
file which located in root directory, we will configuring the things we've created like this:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CustomersModule } from './modules/customer.module';
import { databaseConfig } from './config/database.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => await databaseConfig(configService),
}),
CustomersModule
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Running application
- Back to
nest-service
root directory, open command prompt directed to the directory. - Run
npm run start
. It will take a little longer. - If it is running correctly you will see this log:
- Test your API endpoints using Postman or Thunder Client.
Top comments (0)