Prisma

Prisma

Prisma๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ GraphQL API๋กœ ๋ฐ”๊พธ๊ณ  GraphQL์„ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฒ”์šฉ ์ฟผ๋ฆฌ ์–ธ์–ด๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. SQL์„ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ NoSQL API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹  GraphQL์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฟผ๋ฆฌ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์žฅ์—์„œ๋Š” Prisma์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃจ์ง€ ์•Š์œผ๋ฏ€๋กœ ์›น ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•˜์—ฌ features๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์‚ดํŽด๋ณด์‹ญ์‹œ์˜ค.

warning ์•Œ๋ฆผ ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” Prisma๋ฅผ Nest ํ”„๋ ˆ์ž„ ์›Œํฌ์— ํ†ตํ•ฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ•™์Šตํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฏธ GraphQL ๊ฐœ๋…๊ณผ @nestjs/graphql ๋ชจ๋“ˆ์— ์ต์ˆ™ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค..

Dependencies

๋จผ์ € ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

$ npm install --save prisma-binding

Setup Prisma

Prisma๋กœ ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ ์ž์‹ ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๊ฑฐ๋‚˜ Prisma Cloud๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์†Œ๊ฐœ์—์„œ๋Š” Prisma๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฐ๋ชจ ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  1. Prisma CLI ์„ค์น˜ npm install -g prisma

  2. ์ƒˆ๋กœ์šด ์„œ๋น„์Šค prisma init๋ฅผ ๋งŒ๋“ค๊ณ  ๋ฐ๋ชจ ์„œ๋ฒ„๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ ์ง€์‹œ๋ฅผ ๋”ฐ๋ฅด์‹ญ์‹œ์˜ค

  3. ์„œ๋น„์Šคprisma deploy ๋ฐฐํฌ

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Quick Start ์„น์…˜์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๊ฒฐ๊ตญ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์—prisma.yaml ์„ค์ • ํŒŒ์ผ์ด๋ผ๋Š” ๋‘ ๊ฐœ์˜ ์ƒˆ๋กœ์šด ํŒŒ์ผ์ด ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

endpoint: https://us1.prisma.sh/nest-f6ec12/prisma/dev
datamodel: datamodel.graphql

์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ datamodel.graphql.

type User {
  id: ID! @unique
  name: String!
}

warning ์•Œ๋ฆผ ์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๋” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Prisma์˜ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์„ ๋ณด๋ ค๋ฉด ์—ฌ๊ธฐ๋ฅผ ํด๋ฆญํ•˜์‹ญ์‹œ์˜ค.

prisma playground๋ฅผ ์ž…๋ ฅํ•˜๋ฉด Prisma GraphQL ๋†€์ดํ„ฐ๋ฅผ ์—ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Create the client

GraphQL API๋ฅผ ํ†ตํ•ฉํ•˜๋Š” ๋ช‡ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ GraphQL ๊ฐœ๋ฐœ ์›Œํฌ ํ”Œ๋กœ์šฐ๋ฅผ ์œ„ํ•œ ๋ช…๋ น ์ค„ ๋„๊ตฌ ์ธ GraphQL CLI๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. GraphQL CLI๋ฅผ ์„ค์น˜ํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

$ npm install -g graphql-cli

๊ทธ๋Ÿฐ ๋‹ค์Œ Nest ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— .graphqlconfig๋ฅผ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.

$ touch .graphqlconfig.yml

๋‹ค์Œ ๋‚ด์šฉ์„ ๋„ฃ์œผ์‹ญ์‹œ์˜ค.

projects:
  database:
    schemaPath: src/prisma/prisma-types.graphql
    extensions:
      endpoints:
        default: https://us1.prisma.sh/nest-f6ec12/prisma/dev
      codegen:
        - generator: prisma-binding
          language: typescript
          output:
            binding: src/prisma/prisma.binding.ts

Prisma GraphQL ์Šคํ‚ค๋งˆ๋ฅผ prisma/prisma-types.graphql๋กœ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  prisma/prisma.binding.graphql์—์„œ Prisma ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

$ graphql get-schema --project database
$ graphql codegen --project database

Integration

๊ฑฐ์˜ ๋‹ค๋์Šต๋‹ˆ๋‹ค. ์ด์ œ Prisma ํ†ตํ•ฉ์„ ์œ„ํ•œ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค.

@@filename(prisma.service)
import { Injectable } from '@nestjs/common';
import { Prisma } from './prisma.binding';

@Injectable()
export class PrismaService extends Prisma {
  constructor() {
    super({
      endpoint: 'https://us1.prisma.sh/nest-f6ec12/prisma/dev',
      debug: false,
    });
  }
}

PrismaService๊ฐ€ ์ค€๋น„๋˜๋ฉด ํ•ด๋‹น ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.

@@filename(prisma.module)
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}

info ํžŒํŠธ ์ƒˆ๋กœ์šด ๋ชจ๋“ˆ๊ณผ ์„œ๋น„์Šค๋ฅผ ์ฆ‰์‹œ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด Nest CLI๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. PrismaModule ํƒ€์žŽ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” nest g module prisma ๊ทธ๋ฆฌ๊ณ  ์„œ๋น„์Šค๋ฅผ ์œ„ํ•ด์„œ nest g service prisma

Usage

์ƒˆ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด PrismaModule์„ ๊ฐ€์ ธ์˜ค๊ณ  PrismaService๋ฅผ UsersResolver์— ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

@@filename(users.module)
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
  imports: [PrismaModule],
  providers: [UsersResolver],
})
export class UsersModule {}

PrismaModule์„ ๊ฐ€์ ธ ์˜ค๋ฉด UsersModule ์ปจํ…์ŠคํŠธ์—์„œ ๋‚ด ๋ณด๋‚ธ PrismaService๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@@filename(users.resolver)
import { Query, Resolver, Args, Info } from '@nestjs/graphql';
import { PrismaService } from '../prisma/prisma.service';
import { User } from '../graphql.schema';

@Resolver()
export class UsersResolver {
  constructor(private readonly prisma: PrismaService) {}

  @Query('users')
  async getUsers(@Args() args, @Info() info): Promise<User[]> {
    return await this.prisma.query.users(args, info);
  }
}

Example

์•ฝ๊ฐ„ ์ˆ˜์ •๋œ ์˜ˆ์ œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์—ฌ๊ธฐ.

Last updated

Was this helpful?