김데이의 개발공부

[ TIL ] Day 24 - 실습 : 데이터 시딩 작업 후 개별 모델 CRUD 작성 + Route 분리 본문

코드잇 Node.js(BE) 부트 캠프/TIL (Today I Learn) 📑

[ TIL ] Day 24 - 실습 : 데이터 시딩 작업 후 개별 모델 CRUD 작성 + Route 분리

theday365 2025. 10. 29. 19:56
반응형

🗓️ 수업 일자 : 2025.10.29

✨ 오늘의 수업 평가  [ PROJECT ]  드디어 형태가 보인다 👀🏗️

 

자꾸 집중은 안되고, 작업은 밀리는 느낌이 나고.. 

수업이 끝나고도 작업을 좀 했지만, 오늘 안에 목표한 부분까지 어느 정도 끝내서 참 다행이다! 

 

지난 수업에서 route 부분 들은 내용이 로컬/깃헙 모두 저장 안되서 포스팅 내용만 보고 작업하느라 조금 헤멘😅

그래도 이렇게 저렇게 해 보니 되긴 되서 한시름 덜었다!😉

 

일단 모든 요청은 성공 했으니 오늘도 참 수고 했다!

 

 

👩‍💻 [프로젝트] 오늘 작업 내용 💻

- 데이터 시딩 작업

- DB 모델 별 CRUD 작성
     개별 모델 : Product / Article model CRUD 작업
     관계형 모델 : [ Comment + Product ] model / [ Comment + Article ] model CRUD 작업 

- 모델 별 route 분리 작업 (개별 모델)

 


0. 전체 작업 순서 

  1. 작업 내용 분석 : 데이터 모델 정리, 작업 파일 구조화 등 (완벽하지 않아도 됨, 전체 틀을 잡는 다는 생각으로)
  2. 작업 공간 셋팅 : 필요한 npm 다운로드 및 설치 확인(기본 구문으로 테스트), 필요 시 Git 연결 (with new branch)
  3. 데이터 모델링 및 시딩 작업  
    • 데이터 모델링 : schema.prisma 파일에 작업 후 마이그레이션(초기 init) 작업
    • 시딩 작업 : 비어있는 DB에 테스트용 초기 데이터를 넣는 작업
  4. 각 모델 별 CRUD 작업 : (아직 익숙하지 않으므로) app.js 혹은 main.js에 한번에 작업
    이후 모델 별 route 분리 작업 : route 폴더에 모델별로 1차 분기
                                                  → xx_route .js에는 서버 요청만 남기고 xx_controller.js 에 실행 함수 분리.
  5. 유효성 검사 적용 : 공용으로 제작 후, 각 모델별로 분리하여 xx_controller.js에 적용
  6. 비동기 에러 래퍼 함수 적용 : 서버 다운을 막기 위하여 각 xx_route.js에 적용
  7. 미들웨어 적용 작업 : 공용 / 각 모델별 미들웨어를 각각 분리해서 app.js / xx_route.js 에 각각 적용

- 작업을 진행하며 xx.http를 이용해 지속적인 검토 진행

- 데이터 모델링 수정이 필요한 경우, 작업 후 꼭 마이그레이션 진행 

 

 

1. 시딩 작업 진행 

1. mock.js 파일을 생성하고 임시 데이터(각 모델 별로 객체 형식으로 작성)를 작성한다.
   ( 데이터는 GPT에게 기본 틀 주고, 만들어 달라고 지시 했습니다 😉 )

[왼쪽] Product DB 용 데이터 / [오른쪽] Article DB용 데이터

 

2. seed.js 를 만든 뒤, seed()함수 내에 기존 데이터를 삭제하고 신규 데이터를 입력하는 구문을 작성한다.

    그리고 해당 구문이 실행 된 이후 서버를 닫아주는 비동기 작업을 하단에 선언한다. 

import { PrismaClient } from '@prisma/client';
import { PRODUCTS, ARTICLES } from './mock.js';
// mock에 더 많은 DB가 있는 경우, 해당 DB를 모두 작성

const prisma = new PrismaClient();

async function seed() {

  // Product DB 비우고, 등록하기 
  await prisma.product.deleteMany();
  await prisma.product.createMany({
    data: PRODUCTS,
    skipDuplicates: true,
  });
  
  // Article DB 비우고, 등록하기
  await prisma.article.deleteMany();
  await prisma.article.createMany({
    data: ARTICLES,
    skipDuplicates: true,
  });
  
  // 더 많은 DB가 있는 경우 동일한 패턴으로 추가 작성
}

// seed() 함수가 실행 된 이후 서버와 종료
seed()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (err) => {
    console.log(err);
    await prisma.$disconnect();
    process.exit(1);
  });

 

3. 작업 진행을 위하여 package.js에 "prisma"를 선언하고 명령어를 작성한다.

{
  "name": "pandamarket",
  "version": "1.0.0",
  ...
  "scripts": {...},
  "dependencies": {...},
  
  // dependencies 하단에 아래의 내용 작성
  "prisma":{
    "seed" : "node prisma/seed.js"
  }
}

 

4. 해당 명령어를 터미널에서 실행하면 Seeding 성공! 🌱

터미널 시딩 성공 메세지
🌱 터미널 시딩 성공 메세지 🌱
prisma studio를 통해 확인 해 본 결과, 작업 한 DB만 데이터가 들어감
prisma studio를 통해 확인 해 본 결과, 작업 한 DB만 데이터가 들어감
DB 데이터 상세 보기 : id / createdAt / updatedAt 데이터는 자동으로 입력
DB 데이터 상세 보기 : id / createdAt / updatedAt 데이터는 자동으로 입력

 

 

2. DB 모델 별 CRUD 작업 진행

[ 전체 파일 내 공용 설정 ]

  1. express를 불러 온 뒤 변수에 할당하고, 포트를 선언한다 ⇒ 앱 개발 베이스 작업
  2. Prisma Client를 불러온 뒤 변수에 new 로 생성한다 ⇒ prisma client의 여러 메소드 사용 가능
import express from "express";
import { PrismaClient } from "@prisma/client";

// 백엔드 개발 환경 셋팅
const app = express();
const port = 3000;

// prisma client를 사용해 통신하기 위한 작업
const prisma = new PrismaClient();

// 전역에 적용 할 미들웨어 적용 
app.use(express.json());

 

[ 유용한 CRUD 메소드 ]

[사용법]
... 위 셋팅은 생략 ...

await prisma.product.findMany({
  skip : parseInt(offset), // 이미 객체로 변환 되어 온 경우, 필요한 형 변환 하면 됨 
  data : req.body,         // 마찬가지로 객체로 받은 데이터는 바로 선언 가능  
  where: { id }            // 객체가 아닌 경우, 객체로 변환하여 값 전달
})

여러 데이터 정보에 대한 예시로, 실제 문법과 맞지 않습니다. 자세한 메서드 별 프로퍼티 정보는 아래를 참고하세요 :) 

.findMany() GET쿼리 스트링을 이용하여 여러 데이터를 받을 때 사용.
관련 프로퍼티
(조건)
  • 단독 사용 가능 : 추가로 값을 전달하지 않으면 DB 전체 값을 가지고 옴
  • skip : 건너 뛸 데이터 갯수 지정, 데이터 [ parseInt(offset 값) = offset 값 정수형 변환 ] 사용 
  • take : 가지고 올 데이터 갯수 지정, 데이터 [ parseInt(limit 또는 count 값) = 값 정수형 변환 ] 사용  
  • orderBy : 값의 오름차순 / 내림차순을 정함. sorting 할 데이터 필드를 정하고 "asc" / "desc"를 설정
                    'asc' = 오름차순, 작은 값에서 큰 값으로 이동 (0 → 9, a  z)
                    'desc' = 내림차순, 큰 값에서 작은 값으로 이동 (9 → 0, z  a)

                    예시 - { createdAt : 'desc'} 또는 { firstName : 'asc'} 등등 필드값과 설정 값의 묶음으로 사용 
.findUnique() GETID 또는 Unique 필드를 이용하여 하나의 값을 불러올 때 사용
관련 프로퍼티
(조건)
  • 단독 사용 불가능 : where을 함께 전달 해야함
  • where : 불러 올 데이터의 고유 값인 id를 객체로 전달 필요
.findFirst() GET과 Unique 하지 않은 일반 필드로 값을 찾을 수 있음, 단 첫번째 객체만 리턴 하기 때문에 쿼리 스트링으로 적절한 추가 필터링이 필요
관련 프로퍼티
(조건)
  • 단독 사용 가능 : 하지만 보통은 원하는 필드와 값을 where로 담아서 함께 전달함
  • where : 불러 올 데이터의 필드와 값이 쌍으로 있는 객체( { name: "kim" } )로 전달 필요
  • orderBy : 값의 오름차순 / 내림차순을 정함. 첫번째 값을 정하기 위해 함께 사용. 
.count() GET으로 불러오는 데이터의 수량을 확인 할 때 사용. 
관련 프로퍼티
(조건)
  • 단독 사용 가능 : 프로퍼티를 넣지 않으면 전체 데이터 갯수를 확인 할 수 있음
  • where : 불러 올 데이터의 필드와 값이 쌍으로 있는 객체를 전달하여,
                 조건에 해당하는 데이터가 몇개인지 알 수 있음
.create() POST 요청에 사용하는 메서드
관련 프로퍼티
(조건)
  • 단독 사용 불가능 : request를 넘겨주어야 함 
  • data : request 넘겨주는 기본 프로퍼티,
              같이 넘겨야 하는 관계형 데이터가 있다면 필드명을 넣고 {  create : 값 }으로 넘김
  • include : POST 작업 하며 관계형 모델로 생성된 데이터를 확인 할 때 사용 
.update() PATCH 요청에 사용하는 메서드
관련 프로퍼티
(조건)
  • 단독 사용 불가능 : request를 넘겨주어야 함 
  • data : request 넘겨주는 기본 프로퍼티,
              같이 넘겨야 하는 관계형 데이터가 있다면 필드명을 넣고 { update: 값 }으로 넘김
  • include : POST 작업 하며 관계형 모델로 생성된 데이터를 확인 할 때 사용 
.delete() DELETE 요청에 사용하는 메서드
관련 프로퍼티
(조건)
  • 단독 사용 불가능 : where을 함께 전달 해야함
  • where : 불러 올 데이터의 고유 값인 id를 객체로 전달 필요

 

3. 모델 별 route 분리 

: app.js에 한번에 몰아서 작업한 요청들을 각각의 모델별로 나누어 관리하도록 분리

  1. [ route ] 폴더 내에 각 모델 별 route 파일을 생성
    • / productRoute.js 
    • / articleRoute.js  
  2. 파일 안에 express / @prisma/client 를 불러오고, route 기능을 사용하기 위하여 express.route 를 변수로 선언
    [ 예시 : articleRoute.js ]
    import express from 'express';
    import { PrismaClient } from '@prisma/client';

    const articleRoute = express.Router();
    const prisma = new PrismaClient();
  3. Router()로 선언한 변수에 경로끼리 묶어서 작업을 정리해 줌, 마지막으로 해당 변수를 내보냄
    [ 예시 : articleRoute.js ]  
    articleRoute
      .route('/')
      .get(async (req, res) => {...})
      .post(async (req, res) => {...})

    articleRoute
      .route('/:id')
      .get(async (req, res) => { {...})
      .patch(async (req, res) => { {...})
      .delete(async (req, res) => { {...})

    export default articleRoute;
  4. 기존의 app.js 파일로 돌아와서 해당 변수를 import 하고, route에 사용할 경로를 설정 해 줌
    import productRoute from './routers/productRoute.js';
    import articleRoute from './routers/articleRoute.js';

     

     ... 서버 셋팅 / 기본 미들웨어 작업들이 있음 ...
     
    // route 작업
    app.use('/products', productRoute);
    app.use('/articles', articleRoute);
  5. 서버가 제대로 동작 하는지 확인! 

route 정상 동작 - GET 데이터 확인 작업
route 정상 동작 - GET 데이터 확인 작업

 


 

📃 내일은 뭘 배울까 🤔

- DB 모델 별 CRUD 작성
   개별 모델 : Product / Article model CRUD 작업
   관계형 모델 : [ Comment + Product ] model / [ Comment + Article ] model CRUD 작업 
- 모델 별 route 분리 작업 (관계형 모델)

- 유효성 검사 작업

반응형