Mister Coding

Membuat CRUD Rest API dengan Database MySQL Nest JS


Agik Setiawan

Full Stack Developer

April 4th 2023

 

Apa itu CRUD?


CRUD atau CREATE, READ, UPDATE , DELETE adalah proses membuat, menampilkan, memodifikasi, menghapus data dari suatu Database yang biasa digunakan dalam membuat aplikasi berbasis data. misalnya Portal Berita, kita bisa menambah, menampilkan, menghapus berita yang di simpan di dalam Database.


Contoh Dabase:

  • MySQL
  • Postrgre SQL
  • MariaDB
  • SQLite

 

Persiapan


Pastikan kita sudah melakukan persiapan di bawah ini:

 

Membuat CRUD

Setelah melakukan persiapan yang di sebutkan diatas, saatnya kita kan membuat CRUD, ada beberapa langkah yang harus di lakukan untuk membuat CRUD dengan database MySQL.

 

Buat database


Pada contoh kali ini kita akan menggunakan Dabase MySQL, buatlah Database menggunakan Tools seperti MySQL Workbench agar lebih mudah dalam membuat Database karena memiliki tampilan yang cukup baik dan mudah di gunakan.



Pada gambar diatas saya membuat database dengan nama "nestjs_crud"

 

Prisma


Apa itu Prisma? Prisma adalah database Toolkit yang di buat untuk aplikasi berbasis Node JS dan menggunakan bahasa Typescript yang akan memudahkan kita dalam melakukan proses ke Database.


Kenapa Prisma?

Alasan saya menggunakan prisma yaitu karena Prisma memiliki fitur yang cukup lengkap di antaranya adalah

  • Data Modeling, kita bisa membuat schema seperti table - table, relasi, dengan membuat script schema tanpa harus berhubungan langsung dengan database

  • Migration, kita bisa melakukan proses migration dari shcema tabel - table yang sudah kita buat menjadi tabel - tabel yang ada di dalam database secara otomatis menggunakan Prisma CLI. Contoh: prisma db push

  • Synchronize, kita bisa melakukan Synchronize dari database yang sudah ada menjadi script Schema yang bisa kita gunakan untuk melakukan proses Migration atau sebaliknya. Contoh: prisma db pull

 

Install Prisma


Masuk ke dalam project yang sudah di buat lalu buka terminal dan masukan perintah

npm i prisma --save-dev
npm i @prisma/client

atau

yarn add prisma --dev
yarn add @prisma/client

kemudian masukan perintah pada terminal

npx prisma init

Setelah menjalankan perintah "npx prisma init" akan terbuat Folder "prisma" yang di dalamnya ada scheme dan juga file ".env" yang berisi settingan untuk koneksi Database.



Untuk settingan MySQL, edit file "prisma/schema.prisma" menjadi seperti berikut init

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}


kemudian edit file ".env" sesuai dengan koneksi dan Database MySQL yang sudah di buat sebelumnya

DATABASE_URL="mysql://root:mysql@localhost:3307/nestjs_crud"

 

Buat Module Prisma dan Service


Kita akan membuat Module Prisma yang berisi service yang akan di gunakan untuk service lain, jadi fungsi dari service yang akan kita buat ini adalah sebagai penghubung antara service ke Database, untuk lebih mudah di pahami silahkan ikuti saja tutorialnya supaya nanti akan mengerti.

Jalankan perintah untuk membuat Module

yarn nest g mo prisma

atau

npx nest g mo prisma

kemudian Buat Service dengan perintah:

yarn nest g s prisma

atau

npx nest g s prisma

perintah di atas kan membuat file baru seperti gambar dibawah ini



Edit file "prisma.service.ts" menjadi :

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient
    implements OnModuleInit {

    async onModuleInit() {
        await this.$connect();
    }

    async enableShutdownHooks(app: INestApplication) {
        this.$on('beforeExit', async () => {
            await app.close();
        });
    }
}

Edit Module menjadi Global

Edit module menjadi Global supaya apa yang ada di module bisa di gunakan tanpa harus mengiport Module satu persatu.

import { Global, Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Global()
@Module({
  providers: [PrismaService],
  exports:[PrismaService]
})
export class PrismaModule {}

Untuk menggunakan service berbeda module kita harus mengexport terlebih dahulu, contohnya :

exports:[PrismaService]

 

Buat Schema Biodata

model biodata {
  id          Int           @id @default(autoincrement())
  nama  String        @unique(map: "sliderCode_UNIQUE") @db.VarChar(45)
  nik  Int
  address  String?       @db.VarChar(200)
}

 

Migrate schema


Lakukan migrate schema supaya tersinkron dengan database yang sudah kita buat dengan mamasukan perintah

npx prisma db push

Setelah melakukan perintah diatas pastikan kita check database apakah sudah terbentuk table baru dengan nama biodata.

setelah itu masukan perintah

npx prisma generate

 

Buat Module Biodata


Pada contoh kali ini saya akan membuat CRUD Biodata yang akan menampung data dari siswa seperti Nama, NIK, dan Alamat.


Masukan perintah:

npx nest g res crud/biodata


Perintah diatas adalah perintah untuk membuat CRUD secara cepat tanpa harus membuat Module, Service, Controller satu persatu.


Pilih REST API karena kita akan membuat CRUD Rest API



Setelah melakukan perintah diatas maka akan terbentuk struktur folder seperti



Hapus folder "entities" karena tidak kita gunakan


 

Edit DTO (Data Transfer Object)


Apa itu Data Transfer Object atau DTO?


DTO adalah Type, atau Class yang berisi nama - nama parameter dan type data yang dikirimkan dari Request yang digunakan untuk tujuan agar parameter yang dikirim melalui Request sesuai dengan apa yang di inginkan dan bisa digunakan untuk proses Validasi terhadap data yang dikirim.


Pada gambar diatas sebelum request ke controller, request akan melalu DTO terlebih dahulu untuk memastikan apakah data yang dikirim sesuai atau tidak. Jika sesuai maka akan di teruskan ke controller dengan data yang dikirim, jika tidak sesuai maka akan mengirimkan Error bahwa data yang dikirim tidak sesuai apa yang ada di DTO


Setelah memahami DTO selanjutnya kita akan edit DTO sesuai dengan schema Table yang sebelumnya kita buat.

Install Validator

Kita akan menginstall library untuk Validatornya

yarn add class-validator class-transformer

atau

npm i --save class-validator class-transformer


Edit file "crud/biodata.dto/create-biodatum.dto.ts"

export class CreateBiodatumDto {}


Menjadi

import { Prisma } from "@prisma/client";
import { IsNotEmpty,IsString, IsNumber } from 'class-validator';

export class CreateBiodatumDto implements Prisma.biodataCreateInput {

    @IsString()
    @IsNotEmpty()
    nama: string;

    @IsNumber()
    @IsNotEmpty()
    nik: number;

    @IsString()
    @IsNotEmpty()
    address: string;
}

Tambahkan Pipe pada Controller


Edit controller "crud/biodata/biodata.controller.ts"

import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
import { BiodataService } from './biodata.service';
import { CreateBiodatumDto } from './dto/create-biodatum.dto';
import { UpdateBiodatumDto } from './dto/update-biodatum.dto';

@Controller('biodata')
export class BiodataController {
  constructor(private readonly biodataService: BiodataService) {}

  @Post()
  create(@Body() createBiodatumDto: CreateBiodatumDto) {
    return this.biodataService.create(createBiodatumDto);
  }

  @Get()
  findAll() {
    return this.biodataService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.biodataService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateBiodatumDto: UpdateBiodatumDto) {
    return this.biodataService.update(+id, updateBiodatumDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.biodataService.remove(+id);
  }
}

Menjadi

import { Controller, Get, Post, Body, Patch, Param, Delete, UsePipes, ValidationPipe } from '@nestjs/common';
import { BiodataService } from './biodata.service';
import { CreateBiodatumDto } from './dto/create-biodatum.dto';
import { UpdateBiodatumDto } from './dto/update-biodatum.dto';

@Controller('biodata')
export class BiodataController {
  constructor(private readonly biodataService: BiodataService) {}

  @Post()
  @UsePipes(ValidationPipe)
  create(@Body() createBiodatumDto: CreateBiodatumDto) {
    return this.biodataService.create(createBiodatumDto);
  }

  @Get()
  findAll() {
    return this.biodataService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.biodataService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateBiodatumDto: UpdateBiodatumDto) {
    return this.biodataService.update(+id, updateBiodatumDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.biodataService.remove(+id);
  }
}

Pada file di atas kita menambahkan

 @UsePipes(ValidationPipe)


Fungsi di atas supaya Class Validator yang ada di DTO bekerja, kalau tidak menambahkan script di atas maka Validator tidak akan berkerja

Ubah semua fungsi di controller menjadi async dan await

import { Controller, Get, Post, Body, Patch, Param, Delete, UsePipes, ValidationPipe } from '@nestjs/common';
import { BiodataService } from './biodata.service';
import { CreateBiodatumDto } from './dto/create-biodatum.dto';
import { UpdateBiodatumDto } from './dto/update-biodatum.dto';

@Controller('biodata')
export class BiodataController {
  constructor(private readonly biodataService: BiodataService) {}

  @Post()
  @UsePipes(ValidationPipe)
  async create(@Body() createBiodatumDto: CreateBiodatumDto) {
    return await this.biodataService.create(createBiodatumDto);
  }

  @Get()
  async findAll() {
    return await this.biodataService.findAll();
  }

  @Get(':id')
  async findOne(@Param('id') id: string) {
    return await this.biodataService.findOne(+id);
  }

  @Patch(':id')
  async update(@Param('id') id: string, @Body() updateBiodatumDto: UpdateBiodatumDto) {
    return await this.biodataService.update(+id, updateBiodatumDto);
  }

  @Delete(':id')
  async remove(@Param('id') id: string) {
    return await this.biodataService.remove(+id);
  }
}

Penjelasan

@Controller('biodata')

adalah nama controller yang sekaligus menjadi route yang bisa langsung di akses via API.


Untuk contoh controller di atas, akses API nya adalah http://localhost:3000/biodata


@Post(), @Get(),@Patch(':id'), @Delete(':id') adalah Request Method dari client

Membuat fungsi Create, Get, Update, Delete pada Service


Edit file "biodata.service.ts"

import { Injectable } from '@nestjs/common';
import { CreateBiodatumDto } from './dto/create-biodatum.dto';
import { UpdateBiodatumDto } from './dto/update-biodatum.dto';

@Injectable()
export class BiodataService {
  create(createBiodatumDto: CreateBiodatumDto) {
    return 'This action adds a new biodatum';
  }

  findAll() {
    return `This action returns all biodata`;
  }

  findOne(id: number) {
    return `This action returns a #${id} biodatum`;
  }

  update(id: number, updateBiodatumDto: UpdateBiodatumDto) {
    return `This action updates a #${id} biodatum`;
  }

  remove(id: number) {
    return `This action removes a #${id} biodatum`;
  }
}

Menjadi

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { CreateBiodatumDto } from './dto/create-biodatum.dto';
import { UpdateBiodatumDto } from './dto/update-biodatum.dto';

@Injectable()
export class BiodataService {
  constructor(private dbService: PrismaService) { }

  async create(createBiodatumDto: CreateBiodatumDto) {
    const createBiodata = await this.dbService.biodata.create({
      data: createBiodatumDto
    });
    if (createBiodata) {
      return {
        statusCode: 200,
        message: 'success'
      }
    }
    throw new HttpException('Bad request', HttpStatus.BAD_REQUEST);
  }

  async findAll() {
    const biodataAll = await this.dbService.biodata.findMany();
    return {
      statusCode: 200,
      message: 'success',
      data: biodataAll ?? []
    }
  }

  async findOne(id: number) {
    const biodata = await this.dbService.biodata.findFirst({ where: { id } });
    return {
      statusCode: 200,
      message: 'success',
      data: biodata ?? {}
    }
  }

  async update(id: number, updateBiodatumDto: UpdateBiodatumDto) {
    const biodata = await this.dbService.biodata.update({
      where: { id },
      data: updateBiodatumDto
    });
    if (biodata) {
      return {
        statusCode: 200,
        message: 'success',
        data: biodata ?? {}
      }
    }
    throw new HttpException('Bad request', HttpStatus.BAD_REQUEST);
  }

  async remove(id: number) {
    const biodata = await this.dbService.biodata.delete({ where: { id } });
    if (biodata) {
      return {
        statusCode: 200,
        message: 'success'
      }
    }
  }
}

Penjelasan

  • create digunakan untuk membuat Biodata baru
  • findAll digunakan untuk menampilkan semua biodata
  • findOne digunakan untuk menampilkan biodata berdasarkan id
  • update digunakan untuk mengubah biodata berdasarkan id
  • remove digunakan untuk menghapus biodata berdasarkan id

Jalankan Aplikasi


Jalankan aplikasi dengan terminal dan masukan perintah\

yarn start:dev

atau

npm run start:dev


Endpoint dari NestJS secara default adalah port 3000, jadi untuk membuat request URL nya adalah http://localhost:3000


Jika tidak ada error makan akan tampil seperti gambar dibawah ini

Uji coba menggunakan Postman

Untuk menguji API yang sudah kita buat saya akan menggunakan Postman

  • Buat Biodata & Test DTO dengan memasukan type data yang salah misal nik di kasih type data String, seharusnya muncul error

pada gambar Postman di atas terjadi error karena kita memberi NIK dengan type data String, berarti DTO Validator sudah bekerja dengan baik

pada gambar diatas kita berhasil membuat Biodata

  • Test menampilkan semua Biodata yang sudah kita buat

  • Test menampilkan Biodata berdasarkan id

  • Test mengubah Biodata berdasarkan id

  • Test menghapus Biodata berdasarkan id

 

Kesimpulan


Sampai sejauh ini kita sudah berhasil membuat Rest API dengan contoh biodata, untuk pengembangan lebih lanjut silahkan membaca dokumentasi dari Nenst JS melalui Website resminya.

 

Repository


https://github.com/mister-coding/basic-crud-nestjs

Artikel Terkait

Berkenalan dengan NestJS dan cara install NestJS

Pada tutorial kali ini kita akan berkenalan dengan NestJS, memahami cara kerja NestJS dan cara menginstall NestJS

Mister Coding

© 2023 PT Koding Digital Indonesia. All rights reserved

Company

Privacy PolicyTerms & Condition