Hun's Blog

Nexus GraphQL tutorials (5) - Persisting data (via Prisma) 본문

Backend/GraphQL

Nexus GraphQL tutorials (5) - Persisting data (via Prisma)

jhk-im 2020. 12. 7. 23:16

GraphQL을 개인 프로젝트에 적용하기위해 제대로 학습해보기 시리즈

해당 글은 Nexus 를 개인 프로젝트에 적용하고자 제대로 학습하기 위해 Nexus tutorial의 내용을 정리한 것입니다.

Nexus tutorial에도 상세하게 나와있음을 알려드립니다. 

 

 

5. Persisting data (via Prisma)

5. Persisting data (via Prisma)

nexusjs.org

지금까지의 튜토리얼은 in-memory 데이터로 작업해왔다. 이제부터는 데이터에 초점을 두고 Nexus가 데이터베이스와 함께 사용하는 방법에 대해 알아보자. 해당 튜토리얼에선 PostgreSQL과 Prisma를 활용한다. 

 

PostgreSQL은 오픈소스 관계형 데이터베이스이다.

 

Nexus는 이러한 기술들을 요구하지 않으며 데이터베이스 추상화(raw SQL, Query builder, ORM ..)와 함께 사용될 수 있지만 Nexus는 Prisma의 팀에 의해 만들어졌기 때문에  둘 사이에 유용하게 통합된 부분이 있다. 

 

What is Prisma?

  • Prisma Client: Node.js & TypeScript 용 자동 생성 및 Type-safe Query Builder
  • Prisma Migrate (experimental): Declarative data modeling & Migration system
  • Prisma Studio: 데이터베이스의 데이터를 눈으로 확인하고 편집하는 GUI

Prisma의 중심에는 Schema.prisma라는 파일이있다. 데이터베이스 스키마, 데이터베이스 연결 등을 인코딩하고 domain spcific 언어를 사용하는 Declarative 파일이다. 

 

Connect to your database

  • Prisma 클라이언트, Prisma CLI 설치
  • api/schema.ts 모듈에서 사용
  • Prisma 스키마 만들기
  • 데이터베이스 인증내용을 저장할 .env 파일 만들기
  • 데이터베이스 연결 
yarn add @prisma/client && yarn add --dev @prisma/cli  
npx prisma init

prisma

이제 postgreSQL을 설치해보자. 현재 Ubuntu 20.04를 사용하고있고 그에 맞게 설치해보도록 하겠다. 

 

sudo apt update
sudo apt install postgresql postgresql-contrib
//PostgreSQL 접속
sudo -u postgres psql
// psql

// user 생성 
CREATE USER jrooms WITH PASSWORD 'jrooms123!';

// user 권한설정
ALTER ROLE jrooms superuser createrole createdb;

// database 생성
CREATE DATABASE gqltalk OWNER jrooms;
// prisma/.env
DATABASE_URL="postgresql://jrooms:jrooms123!@localhost:5432/gqltalk"

 

Create your database schema

in-memory 데이터를 실제 데이터베이스의 테이블로 바꿔보자. 이를위해 prisma 스키마에 모델을 작성한다. 

 

// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

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

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  body      String
  published Boolean
}

데이터베이스 스키마를 지정하고 다음을 입력하여 첫 번째 데이터베이스 마이그레이션을 진행해보자. 

npx prisma migrate save --experimental

마이그레이션을 지정한 후 다음을 입력하여 마이그레이션을 적용한다. 

npx prisma migrate up --experimental

 

Access your database

이제 in-memory 데이터를 버리고 Prisma 클라이언트로 대체해보자. 

// api/db.ts
import { PrismaClient } from '@prisma/client'

export const db = new PrismaClient()
npx prisma generate
// api/graphql/Post.ts

export const PostQuery = extendType({
  type: 'Query',
  definition(t) {
    t.list.field('drafts', {
      type: 'Post',
      resolve(_root, _args, ctx) {
        return ctx.db.post.findMany({ where: { published: false } })
      },
    })
    t.list.field('posts', {
      type: 'Post',
      resolve(_root, _args, ctx) {
        return ctx.db.post.findMany({ where: { published: true } })
      },
    })
  },
})

export const PostMutation = extendType({
  type: 'Mutation',
  definition(t) {
    t.field('createDraft', {
      type: 'Post',
      args: {
        title: nonNull(stringArg()),
        body: nonNull(stringArg()),
      },
      resolve(_root, args, ctx) {
        const draft = {
          title: args.title,
          body: args.body,
          published: false,
        }
        return ctx.db.post.create({ data: draft })
      },
    })
    t.field('publish', {
      type: 'Post',
      args: {
        draftId: nonNull(intArg()),
      },
      resolve(_root, args, ctx) {
        return ctx.db.post.update({
          where: {
            id: args.draftId
          },
          data: {
            published: true,
          },
        })
      },
    })
  },
})

 

Try it out

yarn dev

playground

dbeaver