Edited at

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について - たけぞう瀕死ブログ