애드블럭 종료 후 보실 수 있습니다.

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • NextJS API 활용하기 (feat. Prisma, Planetscale)
    Next.js 2022. 8. 23. 16:35
    728x90

    (해당 글은 next@12.2.2, prisma@4.1.1, pscale@0.112.0을 기반으로 작성되었습니다.)

    1. NextJS Api Router

    nextJS의 9 버전은 여러 의미로 큰 변화가 있던 버전이라고 생각한다.

    단순히 React의 프레임워크를 뛰어넘어 내부에서 server를 사용할 수 있게 된 버전이기 때문이다.

    그 방법 역시 무척 간단한데 pages 폴더 내부에 api폴더를 만들고 사용하려는 api의 이름으로 js(ts) 파일을 만들어 사용하기만 하면 되는 방식이었다.

     

    이것으로 이제 간단한 Serverless 환경의 개발이 가능하게 변경되었다.

    그리고 이제 nextJS가 12 버전까지 오르며 ISR이나 edge runtime 등의 기능이 추가되며 Next 역시 앞으로의 발전 방향에 Api Router를 중요하게 생각하는 것 같다.

    2. Planetscale

    Api Router를 통해 DB와 통신할 수 있게 되었기 때문에 DB를 선택할 수 있는데 지금까지는 주로 RDS를 많이 사용했지만 요즘 가장 잘 사용하고 있는 Planetscale에 대해 소개하고자 한다.

     

    Planetscale은 Mysql을 호환하는 DB로 동시 연결도 거의 무제한에(250,000개 이상) 가깝게 할 수 있으며 Autoscaling과 Git과 비슷한 Branch를 지원하며 무척 저렴한 비용으로 사용할 수 있다.

     

    Planetscale은 Vitess를 기반으로 제작되었는데, Vitess는 유튜브의 많은 데이터 처리를 위해 Google에서 제작한 오픈소스로 초당 수백만 개의 쿼리 처리와 수평 샤딩 등을 지원하기에 Planetscale 또한 그에 대해서 그대로 지원하는 장점이 있다.

     

    Planetscale을 사용하기 위해 설치를 진행해야 하는데, 각각의 개발 기기가 다르기 때문에 설치 방법의 경우 아래의 링크를 참고하기를 바란다.

     

    PlanetScale environment set up - Documentation - PlanetScale

     

    PlanetScale environment set up - Documentation - PlanetScale

    Use the PlanetScale CLI to create development branches, make non-blocking schema changes, and open deploy requests directly from your terminal.

    planetscale.com

    3. Prisma

    Planetscale 설치까지 끝났다면 이제 ORM을 선택해야 한다.

     

    ORM이란 Object Relational Mapping의 약자로 객체와 관계형 데이터베이스의 데이터를 자동으로 Mapping 해주는 것을 말한다.

    NodeJS에서는 Sequelize, TypeORM, Prisma 정도가 유명한데 나는 Prisma를 선호하는 편이다.

     

    Sequelize의 경우 가장 원본에 가까운 ORM이지만 사용법 등에 있어 아무래도 다른 둘에 비해 불편한 부분들이 존재하고 TS를 사용할 때 자동으로 Type을 제작해 주는 다른 두 라이브러리에 비해 모자란 감이 존재한다.

     

    TypeORM의 경우 무척 훌륭하지만 class와 데코레이터를 사용해야 되는 단점 아닌 담점이 존재한다.

     

    Prisma의 경우 위에서 설명한 장점 이외에도 간단하게 테이블의 구조를 수정할 수 있고, Prisma Studio를 통해 간단한 CMS를 바로 사용해 볼 수 있다는 큰 장점이 존재하기 때문에 Prisma를 사용하고 있다.

     

    설치 방법은 무척 간단하다.

    npm i @prisma/client
    npm i -D prisma

    프로젝트에 위의 두 라이브러리를 설치해준다.

    npx prisma init

    그런 뒤 위 cli를 입력하면 프로젝트에 prisma/schema.prisma가 설치된다.

    // This is your Prisma schema file,
    // learn more about it in the docs: https://pris.ly/d/prisma-schema
    
    datasource db {
      provider = "sqlite"
      url      = env("DATABASE_URL")
    }
    
    generator client {
      provider = "prisma-client-js"
    }

    이제 prisma를 planetscale과 연결하기 위한 코드를 작성하기 위해 수정해 주면 된다.

    // .env
    DATABASE_URL="mysql://127.0.0.1:3306/any-datebasename"
    
    // schema.prisma
    generator client {
      provider = "prisma-client-js"
      previewFeatures = ["referentialIntegrity"]
    }
    
    datasource db {
      provider = "mysql"
      url      = env("DATABASE_URL")
      referentialIntegrity = "prisma"
    }
    
    model User{
      id Int @id @default(autoincrement())
      email String @unique
      password String
      name String
      createdAt DateTime @default(now())
      updatedAt DateTime @updatedAt
      posts Post[]
    }
    
    model Post{
      id Int @id @default(autoincrement())
      title String
      createdAt DateTime @default(now())
      updatedAt DateTime @updatedAt
      user        User       @relation(fields: [userId], references: [id], onDelete: Cascade)
      userId      Int
      @@index([userId])
    }

    차근차근 설명하자면 

    previewFeatures = ["referentialIntegrity"]
    ...
    referentialIntegrity = "prisma"

    경우 planetscale이 mysql을 호환하는 DB이기 때문에 외래 키를 지원하지 않기 때문에 prisma의 참조 무결성 기능을 이용해 외래 키를 사용할 수 있도록 설정해 줄 수 있다.

     

    그 이외에 특별한 점이라면 model을 만들 때 관계를 설정한 뒤 @@index를 생성해 주는 것이다.

    mysql의 경우 자동으로 index를 생성해 주는 것과 달리 planetscale은 index를 자동으로 생성해주는 기능이 없기 때문이다.

    이를 통해 데이터를 검색할 때 전체에서 검색하는 것이 아닌 설정한 index를 기반으로 검색할 수 있어 더 빠른 속도를 제공한다.

     

    이제 모든 model을 만들었다면 마지막으로 내가 만든 DB에 테이블들을 생성할 수 있다.

    pscale connect any-databasename
    npx prisma db push

    더 자세한 prisma의 기능들은 Prisma Documentation | Concepts, Guides, and Reference에서 확인할 수 있다.

     

    4. 사용 예시

    마지막으로 간단한 api사용 법에 대해 예시를 작성하는 것으로 끝내려 한다.

     

    위에서 설명한 내용은 가장 기본이 되는 사용법이고 이외에도 무척 유용한 기능들이 많기 때문에 더 자세한 사항의 경우 위의 링크들을 통해 얻기를 바란다.

    // configs/client.ts
    import { PrismaClient } from '@prisma/client';
    
    declare global {
      // eslint-disable-next-line no-var
      var client: PrismaClient | undefined;
    }
    
    const client = global.client || new PrismaClient();
    
    if (process.env.NODE_ENV === 'development') global.client = client;
    
    export default client;
    
    // pages/api/post/[id].ts
    
    import { NextApiRequest, NextApiResponse } from 'next';
    
    import client from '@configs/client';
    
    const PostAPI = async (req: NextApiRequest, res: NextApiResponse) => {
      try {
          const { id } = req.query;
          
          if (!postId) return res.status(403).json({ error: 'Invalid post' });
          
          const post = await client.post.findUnique({
            where: { id: +id },
            include: { user: { select: { id: true, name: true } } },
          });
          return res.json({ post });
      } catch (error) {
        console.error(error);
        return res.status(500).json({ error: (error as Error)?.message });
      }
    };
    
    export default PostAPI;

     

    댓글

Designed by Tistory.