, 19 min read
Pada tutorial kali ini Kita akan belajar membuat CRUD Rest API dengan Database MySQL Nest JS supaya kita lebih memahami alur dari framework Nest JS
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:
Pastikan kita sudah melakukan persiapan di bawah ini:
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.
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"
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
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"
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]
model biodata {
id Int @id @default(autoincrement())
nama String @unique(map: "sliderCode_UNIQUE") @db.VarChar(45)
nik Int
address String? @db.VarChar(200)
}
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
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
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.
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;
}
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
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
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
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
Untuk menguji API yang sudah kita buat saya akan menggunakan Postman
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
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.
https://github.com/mister-coding/basic-crud-nestjs
Tags