Express Js + Prisma + Typescript

Penjelasan mengenai cara membuat project dengan Typescript, Express JS, Postgre SQL dan Prisma

npm init -y

npm install express
npm install -D typescript ts-node-dev @types/node @types/express

npx tsc --init

npm install -D prisma
npx prisma init
npm install @prisma/client

npx prisma generate
npx prisma migrate dev --name init

npx prisma studio

npm install bcrypt
npm install -D @types/bcrypt

npm install jsonwebtoken
npm install -D @types/jsonwebtoken

npm install joi
npm install -D @types/joi

Masukkan di package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "ts-node-dev --respawn src/app.ts"
  },

Masukkan di .env

DATABASE_URL="postgresql://postgres:uuaauaua123@localhost:5432/dblivecode?schema=public"

App.ts

import express from "express";
import { router as authRoutes } from "./routes/auth";

const app = express();
app.use(express.json());

app.use(authRoutes);

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Controller

import { Request, Response } from "express";

const testing = async (req: Request, res: Response) => {
    try {
      res.status(200).json({ 
        message: "Server berhasil connect" 
      });
    } catch (error) {
      console.error(error);
      res.status(500).json({ 
        error, 
        message: "Server tidak terhubung" 
      });
    }
  };

export {
    testing,
};

Routes

import { Router } from "express";
import {
    testing,
} from "../controllers/auth";

const router = Router();

router.get("/test", testing);

export { router };

Schema.prisma

model Product {
  id        Int       @id @default(autoincrement())
  name      String
  price     Float
  stock     Int       @default(0)
  createdAt DateTime  @default(now())
}

model User {
  id        Int       @id @default(autoincrement())
  name      String
  email     String    @unique
  createdAt DateTime  @default(now())
}

====================================================

Tambahkan konfigurasi seeder di package.json

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "ts-node-dev --respawn src/app.ts",
    "seed": "ts-node prisma/seed.ts"
  },

Setelah membuat seed.ts, jalankan

npm run seed

Tambahkan di controllers

import { PrismaClient } from "../generated/prisma";

const prisma = new PrismaClient();

Tambahkan table order

model User {
  orders    Order[]
}

model Product {
  orders    Order[]
}

model Order {
  id        Int      @id @default(autoincrement())
  userId    Int
  productId Int
  quantity  Int
  user      User     @relation(fields: [userId], references: [id])
  product   Product  @relation(fields: [productId], references: [id])
  createdAt DateTime @default(now())
}

Update dan Delete

const updateProduct = async (req: Request, res: Response) => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    const product = await prisma.product.update({
      where: { id: Number(id) },
      data: updateData
    });

    res.status(200).json({
      status: "Success",
      data: product,
      message: "Product updated success"
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({
      status: "Error",
      message: "Internal server error"
    });
  }
};
const deleteProduct = async (req: Request, res: Response) => {
  try {
    const { id } = req.params;

    await prisma.product.delete({
      where: { id: Number(id) }
    });

    res.status(200).json({
      status: "Success",
      message: "Product deleted success"
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({
      status: "Error", 
      message: "Internal server error"
    });
  }
};

Validate price tidak boleh < 0

const createProduct = async (req: Request, res: Response) => {
    try {
      const { name, price, stock } = req.body;
      
      if (price < 0) {
        return res.status(400).json({
          status: "Error",
          message: "Price cannot be less than 0"
        });
      }
}

Last updated