Customer: Use Case (3: Implementing NestJS Service)

amalja0

Amalia Hajarani

Posted on November 30, 2023

Customer: Use Case (3: Implementing NestJS Service)

Prerequisites

  1. Installed Node version of v20.10.0
  2. 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.

  1. Install nest cli globally using command prompt.

     npm i -g @nestjs/cli
    
  2. Open new command prompt from the nest-service directory.

  3. Create new NestJS project by running command below. I choose npm as the package manager.

    nest new .
    
  4. 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"
    }
    
  5. 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
    
  6. 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,
});
Enter fullscreen mode Exit fullscreen mode

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;

}
Enter fullscreen mode Exit fullscreen mode

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();
  }
}
Enter fullscreen mode Exit fullscreen mode

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;
  }

}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

Running application

  1. Back to nest-service root directory, open command prompt directed to the directory.
  2. Run npm run start. It will take a little longer.
  3. If it is running correctly you will see this log: Image description
  4. Test your API endpoints using Postman or Thunder Client.
💖 💪 🙅 🚩
amalja0
Amalia Hajarani

Posted on November 30, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related