Help us understand the problem. What is going on with this article?

prisma - 最速 GraphQL Server実装

More than 1 year has passed since last update.

react-apollo の調査で GraphQL サーバーをさっくり実装する必要があり、 今 graphqool どうなってるんだっけ、と見に行ったら prisma が推奨されていました。

日本語情報がまったくなかったので、調査した結果をまとめておきます。

prisma とはなにか

  • GraphQL の形をした ORM
    • MySQL/Postgre への マイグレーションヘルパー付き
    • モデル定義からインデックス自動生成
    • CRUD自動生成
  • graphqoolの次期版?
    • PaaS に依存せず、自分でデプロイ可能なマイクロサービス

自分も最初よくわからなかったのですが、 使ってみた感じでは、 GraphQL の形をとった ORM + Migration Helper です。

$ npm i -g prisma
$ prisma init my-graphql-server # REPL で実装を選ぶ
$ cd my-grhapql-server
$ docker-compose up -d
$ prisma deploy

これで GraphQL サーバーが起動します。 docker の prismagraphql/prisma イメージが、prisma.yml ファイルを読んで起動します。

データモデル定義

先のチュートリアルの prisma deploy は datamodel.graphql をDBに向けて migration する操作です。
init ではこんなファイルが生成されています。

$ tree my-graphql-server/
├── datamodel.graphql
├── docker-compose.yml
└── prisma.yml
datamodel.graphql
type User {
  id: ID! @unique
  name: String!
}

この User 定義に合わせて、 DB上のテーブルが生成され、GraphQL 上の CRUD 操作が実装されています。

動作確認のために、組み込みの GraphQL Playground を起動してみましょう。

prisma playground -p 9999

ブラウザが立ち上がるので、クエリを入力してみます。デフォルトだと 4466 に prisma サーバーが立ち上がっています。

mutation {
  createUser(data: {
    name: "Alice"
  }) {
    id
  }
}
{
  users {
    id
    name
  }
}

users, createUser, deleteUser, updateUser などが datamodel.graphql のモデル定義から自動生成されています。

リレーションを生成

次のようにモデルを追加して prisma deploy してみます。

datamodel.graphql
type User {
  id: ID! @unique
  name: String!
  articles: [Article!]!
}

type Article {
  id: ID! @unique
  title: String!
  content: String!
  author: User!
}

これを prisma deploy すると、 DB上に新しいテーブルを作って、User と article 属性の定義に従って、自動的にインデックスを張ってくれます。

こういうクエリが発行できるようになります

{
  users {
    id
    name
    articles {
      title
      content
    }
  }
}

実際のワークフロー

GraphQLはクライアント側のユースケースでクエリを作るため、CRUD実装のままデプロイしてしまうと、あらゆる操作がクライアントから可能になってしまいます。

なので、この GraphQL を利用する GraphQL サーバーをもう一つ立てます。

クライアントから見たときはこういう構成になります

Client <=> User GraphQL <=> Prisma GraphQL <=> MySQL

この User GraphQL は apollo で resolver を定義した GraphQL サーバーを書きます。詳しい実装方法は、 https://www.prisma.io/docs/tutorials/build-graphql-servers/development/build-a-graphql-server-with-prisma-ohdaiyoo6c を読んでください。

このとき、 prisma は GraphQL サーバーからみた GraphQL による CRUD 実装ということが出来ます。このときの apollo による GraphQL サーバーの resolver が次のようになります。

const resolvers = {
  Query: {
    posts: (_, args, context, info) => {
      return context.prisma.query.articles(
        {
          where: {
            OR: [
              { title_contains: args.searchString },
              { content_contains: args.searchString },
            ],
          },
        },
        info,
      )
    },
  },
  //...
}

apolloのprismaプラグインによって context.prisma が定義され、 datamodel 定義によるクエリ操作が可能です。(これを詳しく覚えないといけないのがちょっと面倒ですね…)

graphqool を使う場合、 PaaS としての graphqool を使う必要がありました。 prisma は prisma cloud にデプロイしてつかうことも可能なのですが、 これは10req/10s の制限があります。

プロダクションで使うには、 prisma の docker image を k8s などでデプロイすることになると思います。結局自前のGraphQL サーバーをデプロイする必要があるので、マイクロサービス前提のアーキテクチャですね。

最後に

https://github.com/mizchi-sandbox/myjam で next.js + prisma で簡単なブログサービスを実装してみました。いわゆる JAM Stack です。

GraphQL は自分でサーバーを書くのが面倒くさかったのですが、prisma は面倒臭さを極力抑えて マイクロサービス前提で複雑さを抑えようというものです。

実際に使い込むと粗が出そうですが、パッと見筋は良さそうに見えます。

追記

日本語情報ない、と言いましたが、書き終わったあとに @takezoen さんの記事があることに気づきました

GraphQLスキーマからCRUDを自動生成できるPrismaについて - たけぞう瀕死ブログ

plaid
CXプラットフォーム「KARTE」の開発・運営、EC特化型メディア「Shopping Tribe」の企画・運営、CX特化型メディア「XD(クロスディー)」の企画・運営
https://plaid.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away