[GraphQL] Psima를 이용한 Database 연동

GraphQL + Node.js - 4

Posted by owin2828 on 2020-11-17 15:09 · 8 mins read

들어가기 앞서


지난 포스팅에 이어 이번에는 prisma를 사용하여 database를 연동해보도록 한다.
SQLite를 DB로 이용하여 데이터를 저장할 예정이다.

본 시리즈는 HOW TO GRAPHQL 글을 참고하여 작성했습니다.
기존에 참조하던 cadenzah 님의 포스팅이 deprecated되어 새롭게 작성하였습니다.
오타 및 의역이 있을 수 있으니 양해를 부탁 드리며, 수정 사항은 댓글로 알려주세요.

Prisma1 vs Prisma2

기존에 Prisma1에서 Prisma2로 변경되며 많은 부분이 변경되었다. 이로 인해, GraphQL 블로그의 튜토리얼이 변경된듯 하다.
내가 이 시리즈의 포스팅을 작성하게 된 가장 큰 이유가 된 부분이다..

Prisma DB Proxy 선택사항(출처: https://www.prisma.io/blog/announcing-prisma-2-zq1s745db8i5)

Prisma1 vs Prisma2(출처: https://www.codemochi.com/blog/2019-06-26-prisma-2-sneak-peak)


1. Prisma는 무엇인가?


Prisma는 개발자들이 깔끔하고 type-safe한 API를 통해 데이터베이스에 접근하게 해주는 오픈소스이다.
이는 다음과 같은 3가지 툴과 각각의 기능으로 구성이 되어있다.

  • Primsa Client: Node.js 및 TypeScript를 위한 쿼리 자동 생성
  • Prisma Migrate: 명시적인 데이터 모델링 및 마이그레이션 시스템
  • Prisma Studio: GUI를 통한 데이터베이스 접근 및 수정

2. Prisma를 사용하는 이유


지금까지 살펴본 방법으로 매우 간단하고 아름답게 GraphQL 서버가 동작함을 알 수 있다.
그러나 실제로 서버를 개발할 때는 이렇게 간단한 문제들로만 구성되는 않는다.

특히 GraphQL 쿼리들은 깊은 단계로 중첩이 될 수 있는데, 이때 리졸버를 구현하는 것은 까다롭고, 성능문제를 야기할 수 있다.
이러한 개발자들의 고충을 해결하기 위해, Prisma는 더욱 효율적으로 데이터에 접근하는 방법에 초점을 맞췄다.

3. Prisma & SQLite 설정하기


우선 다음의 명령을 통해 Prisma CLI를 설치한다.

# ./hackernews-node/
npm install @prisma/cli --save-dev

다음의 명령을 통해 schema.prisma 파일을 생성한다.

# ./hackernews-node/
mkdir prisma
touch prisma/schema.prisma

Prisma1과 Prisma2가 가장 다른 점은 위의 방법처럼 Database에 관련된 파일을 관리하는 방법과 아키텍처가 다르다.
자세한 사항은 Prisma2와 Prisma1의 차이점을 참고

위의 과정을 통해 생성된 schema.prisma는 데이터베이스 스키마처럼 생각하면 되며, 다음과 같이 구성된다.

  1. Data source: 데이터베이스에 연결한다.
  2. Generator: Prisma Client를 생성한다.
  3. Data model: 애플리케이션의 모델을 정의한다.

이를 코드로 작성해보자.

// ./hackernews-node/prisma/schema.prisma

// 1
datasource db {
  provider = "sqlite" 
  url      = "file:./dev.db"
}

// 2
generator client {
  provider = "prisma-client-js"
}

// 3
model Link {
  id                      Int      @id @default(autoincrement())
  createdAt       DateTime @default(now())
  description     String
  url                     String
}

Link 모델은 link 데이터 베이스 테이블의 구조를 정의하며, Prisma는 이를 기반으로 테이블을 생성해준다.

4. SQLite로 시작하기


드디어 SQLite 데이터베이스를 만들 시간이다. SQLite는 serverless, 설정의 간편함, 트랜잭션등 다양한 장점이 있다.
또한 다른 SQL 데이터베이스와는 달리 별도의 서버 프로세스가 없어 일반 디스크 파일에 직접 읽고 쓰기를 수앻한다.
하나의 완전한 데이터 베이스(table, indice, trigger 및 view)가 하나의 디스크 파일에 포함된다.
이러한 장점은 본 프로젝트와 잘 어울린다.

다행히 Prisma와의 연동은 간편하게 진행할 수 있는데, 다음과 같은 명령어를 통해 migration을 생성함으로써 가능하다.

# ./hackernews-node/
npx prisma migrate save --experimental

위의 명령어를 수행하면 다음과같이 묻는 문구가 뜨게 되는데 Yes를 클릭하고, 이름을 정해준다.

You are trying to create a migration for SQLite database dev.db.
A database with that name doesn't exist at file:./dev.db
> YES
> Name of migration:

성공적으로 수행하고 나면, prisma 디렉토리 밑에 /migrations라는 디렉토리가 생성되었음을 알 수 있다.
README.md 파일을 참조하면, 우리가 생성한 Link에 대한 테이블구성을 볼 수 있으며, 여러가지 수정사항이 함께 기록된다.

이제 실제로 데이터베이스에 대해 마이그레이션을 실행하기 위해 다음의 명령을 수행한다.

# ./hackernews-node/
npx prisma migrate up --experimental

이제 테이블이 있는 데이터베이스가 생성되었다.

5. Prisma Client 생성


위에서 생성한 데이터 모델을 기반으로 Prisma Client를 생성해보자.

# ./hackernews-node/
npx prisma generate

성공적으로 수행된다면, Prisma client를 /node_modules/@prisma/client에서 가져와 사용할 수 있다는 문구가 뜨게 된다.
Prisma Client로 첫 번째 쿼리를 만들어서 분석을 하기 위해, 별도의 src/script.js 파일을 만들고 다음 코드를 추가한다.

// 1
const { PrismaClient } = require("@prisma/client")

// 2
const prisma = new PrismaClient()

//3
async function main() {
  const allLinks = await prisma.link.findMany()
  console.log(allLinks)
}

//4
main()
  .catch(e => {
    throw e
  })
  // 5
  .finally(async () => {
    await prisma.$disconnect()
  })

위 코드는 다음과 같이 동작한다.

  1. 노드모듈 PrismaClient에서 생성자를 가져옴
  2. 가져온 모듈 인스턴스화, PrismaClient
  3. 데이터베이스에 쿼리를 보내기 위해 async로 호출되는 main 함수를 정의
  4. 실제 main 함수 호출
  5. 스크립트가 종료되면 데이터베이스 연결을 끊음

위와 같이 정상적으로 설정된다면, 아래 사진처럼 자동완성이 가능해진다.

Prisma 인스턴스를 가져와 자동완성 되는 모습

위에서 작성한 스크립트를 다음의 명령으로 실행하자.

# ./hackernews-node/
node src/script.js

성공적으로 수행된다면, 아무것도 없는 빈배열이 응답될 것이다. 새로운 link 생성을 위해 다음과 같이 추가한다.

// ./hackernews-node/src/script.js

...
async function main() {
  const newLink = await prisma.link.create({
    data: {
        description: 'Fullstack tutorial for GraphQL',
        url: 'www.howtographql.com',
    },
  })
  const allLinks = await prisma.link.findMany()
  console.log(allLinks)
}

다음과 같이 성공적으로 가져온 결과물을 확인할 수 있다.

[ { id: 1,
    createdAt: 2020-11-17T07:33:26.767Z,
    description: 'Fullstack tutorial for GraphQL',
    url: 'www.howtographql.com' } ]


6. Workflow 요약


데이터를 업데이트하는 위의 과정들을 요약하자면 다음과 같다.

  1. Prisma 데이터 모델 수정
  2. prisma migrate 명령을 통해 데이터베이스 마이그레이션
  3. Prisma Client 생성
  4. 어플리케이션에서 코드로 데이터베이스에 접근

끝마치며


Prisma와 SQLite를 이용하여 데이터베이스에 데이터를 저장하는 방법에 대해 알아보았다.
다른 DB를 사용하기 위해서는 datasource에 다른 db를 연결하면 된다.
Prisma는 꼭 GraphQL이 아니라 RESTful API에서도 사용이 가능하다.

이곳을 참조

다음 포스팅에서는 리졸버 함수 내에서 데이터베이스에 접근하는 방법에 대해 알아보도록 한다.

Refernce