ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js 13] 1. 토이프로젝트 하면서 공부한 내용 정리 (Prisma)
    front-end/Next.js 2023. 6. 25. 17:57

    이번 포스팅은 토이프로젝트 하면서 Next.js에 Prisma 를 이용한 서버사이드 렌더링에 대해서 제일 먼저 작성하려고 합니다.

    우선 Next.js는 서버사이드렌더링으로 기본적으로 API에서 fetch 나 axios로 데이터를 fetching 해오는게 아니라 디비와

    바로 통신을 해서 seo나 첫화면 로딩속도를 개선 할 수 있습니다.

     

    1. 클라이언트 사이드 렌더링

    클라이언트 사이드 렌더링(Client-side Rendering, CSR): 클라이언트 사이드 렌더링은 초기 HTML 마크업만 서버에서 받고, 브라우저에서 JavaScript를 사용하여 데이터를 가져와 동적으로 페이지를 렌더링하는 방식입니다. 즉, 브라우저에서 JavaScript 코드를 실행하여 서버로부터 데이터를 가져와서 동적으로 화면을 구성합니다. 초기 로딩 시에는 비어있는 페이지가 표시되고, JavaScript가 실행되어 데이터를 가져와서 렌더링합니다.

     

    2.서버 사이드 렌더링
    서버 사이드 렌더링(Server-side Rendering, SSR): 서버 사이드 렌더링은 서버에서 요청을 받을 때마다 서버에서 데이터를 가져와서 완.전히 렌더링된 HTML 생성하여 클라이언트에게 제공하는 방식입니다. 따라서 클라이언트에 도달하기 전에 서버에서 페이지를 완전히 렌더링하여 렌더링된 페이지를 바로 전송합니다. 이렇게 하면 초기 로딩 시에 완전한 컨텐츠가 있는 페이지를 바로 표시할 있습니다.

     

     

     

     

    Next.js SSR 기본적으로 지원하며, Prisma 사용하면 서버에서 데이터베이스와 통신하여 필요한 데이터를 가져올 있습니다. 예를 들어, Next.js에서 Prisma 사용하여 서버 사이드 렌더링을 서포트 해주는 Prisma의 쿼리 문입니다.

    SQL과 같은 쿼리문을 잘 몰라도 Prisma Client를 이용하면됩니다.

     

    • create: 데이터베이스에 새로운 레코드를 생성합니다. 예를 들어, prisma.user.create({ data: { name: 'Kwangmin', age: 31 } })는 'User' 테이블에 새로운 사용자를 생성합니다.
    • findMany: 데이터베이스에서 여러 레코드를 검색합니다. 예를 들어, prisma.user.findMany()는 'User' 테이블의 모든 사용자를 검색합니다.
    • findUnique: 고유한 식별자를 기반으로 데이터베이스에서 특정 레코드를 검색합니다. 예를 들어, prisma.user.findUnique({ where: { id: 1 } })는 'User' 테이블에서 ID가 1인 사용자를 검색합니다.
    • update: 데이터베이스에서 특정 레코드를 업데이트합니다. 예를 들어, prisma.user.update({ where: { id: 1 }, data: { age: 30 } })는 ID가 1인 사용자의 나이를 30으로 업데이트합니다.
    • delete: 데이터베이스에서 특정 레코드를 삭제합니다. 예를 들어, prisma.user.delete({ where: { id: 1 } })는 ID가 1인 사용자를 삭제합니다.

     

    prisma를 next.js13에 사용하기위한 간단 한 세팅 방식입니다.

     

    데이터베이스에 연결하려면 Prisma 스키마의 datasource 블록의 url 필드를 데이터베이스 연결 URL로 설정해야 합니다

    . url 필드는 환경 변수(DATABASE_URL)를 통해 데이터베이스 연결 URL을 가져오도록 설정되어 있습니다.

    위 예시에서는 MongoDB Atlas의 URL을 사용하는 것으로 예시되어 있습니다.

    .env 파일에는 다음과 같이 MongoDB Atlas URL 설정해주어야 합니다:

     

    env 파일

    DATABASE_URL="mongodb+srv://EXAMPLE:YOURPASSWORD@cluster0.uaatmat.mongodb.net/test"

     

     

    schema.prisma

    // 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 = "mongodb"
      url      = env("DATABASE_URL")
    }
    
    
    model DogListing {
      id String @id @default(auto()) @map("_id") @db.ObjectId
      desc String
      imageSrc String
      createdAt DateTime @default(now())
      dogType String
      dogAge Int
      dogName String
      weight Int
      dogMonth String?
      male String
      personality String[]
      userId String @db.ObjectId
      user User @relation(fields: [userId], references: [id], onDelete: Cascade)
    }

     

     generator 섹션은 Prisma Client를 생성하는 데 사용됩니다. provider 설정은 Prisma Client의 제공자를 지정합니다. 여기서는 prisma-client-js를 사용하여 Prisma Client를 생성하도록 설정되어 있습니다.

     

    datasource 섹션은 Prisma가 데이터베이스에 연결할 데이터 소스를 지정합니다. 여기서는 mongodb 데이터베이스를 사용하도록 설정되어 있으며, url 속성을 통해 데이터베이스 연결 URL을 환경 변수(DATABASE_URL)로부터 가져오고 있습니다.

     

    model 섹션은 데이터 모델을 정의하는 부분입니다. DogListing이라는 모델은 DogListing 컬렉션(또는 테이블)에 대응됩니다. 각 필드는 데이터 모델의 속성을 정의합니다. 예를 들어, id는 문자열 형식의 고유 식별자로 정의되고, desc, imageSrc, createdAt 등은 해당하는 속성의 데이터 유형과 기타 설정을 정의합니다.

     

    npx prisma db push 커맨드를 입력하면 설정한 몽고디비에 데이터베이스가 생성 된것을 볼 수 있습니다.

     

     

    자 이제

    Prisma 스키마 파일을 사용하여 데이터 모델을 정의하고, Prisma Client 생성하여 데이터베이스와 상호 작용하는데 사용할 있습니다

     

     

     

    Next.js 13은 기본적으로 서버사이드 렌더링을 합니다.

    만약 useState , useEffect 같은 리액트 훅을 사용하고 싶으면 , 파일 최상단에 'use client'를 작성 해줘야합니다.

     

    우선 서버사이드렌더링을 하기 위함이 Nextjs의 가장 큰 목적이니까  서버사이드렌더링 페이지에서 Prisma를 이용해 데이터를 갖고온 후 ,

    하위 클라이언트 컴포넌트로 갖고온 데이터를 props로 전달해줍니다. 

     

    path는 대략 이런식 입니다.

     

    Folder: list -> page.tsx -> ListingClient.tsx

     

    Next.js는 파일기반 라우팅이니 /list 라는 url에 들어오면 page.tsx가 보일건데 여기서 page.tsx 는 서버 컴포넌트 입니다.

     

     

     

    1. getList.ts (prisma client를 page에 선언 안하고 따로 관리 하는게 더욱 깔끔합니다.)

    import prisma from '@/app/libs/prismadb';
    
    export default async function getListing() {
      try {
        const getDogList = await prisma.dogListing.findMany({
          orderBy: {
            createdAt: 'desc'
          }
        })
        return getDogList;
        
      } catch (error: any) {
        console.log(error)
      }
    }

     

    여기서 prisma 에서 dogListing의 디비를 조회를 합니다. 비동기로 처리해야하니 try catch문으로 예외처리를 항상 해줘야합니다.

     

    2. list / page.tsx 에서 위 prisma 클리이언트로 디비를 조회하는 함수를 import 해옵니다. 그리고 client compoent로 props를

    전달 해줍니다.

     

    export default async function List({ params }: { params: IParams }) {
      
      const allDogList = await getListing();
      
      return (
          <ListingClient
            loggedInUser={loggedInUser}
            dogList={dogList}
            allDogList={allDogList}
          />
      );
    }

     

    3. ListingClient 에선 파일 최상단에 'use client' 선언 후 , 리액트 훅들을 사용 하면 됩니다.

     

     

    이번에 Prsima 클라이언트로 클라이언트에서 fetch나 axois같은 데이터 통신이 아니라 서버에서 바로 통신 하는것을

    배워서 서버사이드 렌더링에 대해서 조금은 더 알아 갔던것같습니다.

     

    프론트엔드 개발자인 저에게 DB설계같은게 익숙치 않았지만 , Prisma를 이용해서 디비 구축도 조금은 쉽게 했던거같습니다!

    Next js의 공부가 아니라 전반적인 프론트엔드와 백엔드의 통신하는 법 또한 더 공부할수 있었던 기회 였던거 같습니다.

     

     

    잘못된 정보가 있으면 댓글로 알려주세요!

     

     

    Reference:

    https://www.prisma.io/

     

    Prisma | Next-generation ORM for Node.js & TypeScript

    Prisma is a next-generation Node.js and TypeScript ORM for PostgreSQL, MySQL, SQL Server, SQLite, MongoDB, and CockroachDB. It provides type-safety, automated migrations, and an intuitive data model.

    www.prisma.io

     

     

     

     

Designed by Tistory.