# HOW TO GRAPHQLでGraphQLの勉強をはじめました その⑥

# Adding a Database

今回はPrizmaをセットアップしてGraphQLサーバーからデータベースに接続してみる感じ。

# Why Prisma

GraphQLサーバーがどのように動いているかは理解できたはず(驚くほどシンプルですよね?)で、強い型付けなスキーマ定義とGraplhQLエンジンがAPI開発のしんどいところを吸収してくれる様が見て取れたと思います、と。

で、それではGraphQLサーバーの構築の何が難しいのでしょうか??

real-worldのアプリケーションではリゾルバーの実装が非常に複雑になりがちです、と。GraphQLクエリは複数のレベルにネストするけど、それはトリッキーでパフォーマンスの問題になってしまいがち。

例えば、ほとんどの場合、authentication, authorization, pagination, filtering, realtime, integrating with 3rd-party services or legasy systems...といったことを考慮にいれなくてはなりません。

大体の場合、リゾルバの実装は以下の2つのような感じになります(両方凄い説得力があるわけでも無さそうですが…)

  • データベースにSQLもしくはNoSQLのAPIを使って直接アクセスする 👉 SQLをリゾルバの中で書くと複雑になってすぐに手に負えなくなりがち。でもってSQL自体は文字列なので構造化しにくく、エディタの自動補完機能とかが辛い

  • ORMを使ってデータベースへのアクセスを抽象化してプログラムからアクセスさせる 👉 単純なものには良いアプローチだけど、複雑なクエリやエッヂケースに対応が難しい場合がある

Prismaは上記のような課題を解決し、あなたのリゾルバをよりシンプルに保ってくれるデータアクセスレイヤのソリューションです、と。

# Architecture

以下がPrismaを使った場合のアーキテクチャのオーバービューです。

Architecture

API Server (graphql-yogaを使って構築してきたようなもの)にPrisma Clientを適用することで(アプローチとしてはORMに近い)、簡単にPrisma Serverを通してデータベースにアクセスできる、というもの。

# Setting up Prisma with a demo database

ミニマムなセットアップではじめます。ファイルを2つ作ってprismaというディレクトリに配置します。

mkdir prisma
touch prisma/prisma.yml
touch prisma/datamodel.prisma

prisma.ymlはPrismaの設定ファイル。datamodel.prismaはあなたのデータモデルの定義すなわちあなたのアプリケーションのmodel。それぞれのmodelはデータベースのテーブルにマッピングされる。

Hacker NewsクローンアプリのデータタイプはLinkしかありません。PrismaはGraphQL SDLをモデル定義に使うので、schema.graphqlのLinkの定義をdatamodel.prismaに移植すれば良い感じ。

ということでdatamodel.prismaを開いて以下のコードを足していきます。

type Link {
  id: ID! @id
  createdAt: DateTime! @createdAt
  description: String!
  url: String!
}

schema.graphqlとの違いは @id のところ。これによってPrismaはLinkレコードにユニークなIDを自動生成してデータベースのidフィールドに値を保存します、と。そして、createdAtのところはPrismaがよろしくレコードを作成した日を付けてくれるし、 @updateAtを使えば最後にレコードが更新されたのがいつかを保存してくれます。

次に prisma.yml。以下を追加します。

# The HTTP endpoint for your Prisma API
endpoint: ''

# Points to the file that contains your datamodel
datamodel: datamodel.prisma

# Specifies language & location for the generated Prisma client
generate:
  - generator: javascript-client
    output: ../src/generated/prisma-client
  • endpoint: Prisma APIのHTTPエンドポイント
  • datamodel: APIサーバーで使うPrisma clientのデータモデルファイル
  • generate: Prisma clientとして自動生成されるものを言語と共に指定

yarnでPrismaのCLIをインストール

yarn global add prisma

今回のチュートリアルではPrisma Cloudと呼ばれる環境にあるデモ用のAWSのAurorをタダで使えるそうです。

ということで👇。対話型のインターフェースで諸々やってくれます。Dockerイメージとして自分のローカルとかで動かしたりも出来るようですが、とりあえず全ておまかせの方向で。

$ prisma deploy
? Set up a new Prisma server or deploy to an existing server? Demo server + MySQL database
Opening https://app.prisma.io/cli-auth?secret=$2a$08$7ImeVvVkrKtdmAxnU0/Uhu in the browser

Authenticating ✔
Authenticated with xxx@xxx.com
? Choose the region of your demo server xxx-xxxx-e75aef/demo-us1
? Choose a name for your service hackernews-node
? Choose a name for your stage dev

Written endpoint `https://us1.prisma.sh/xxx-xxxx-e75aef/hackernews-node/dev` to prisma.yml

Creating stage dev for service hackernews-node ✔
Deploying service `hackernews-node` to stage `dev` to server `prisma-us1` 1.3s

Changes:

  Link (Type)
  + Created type `Link`
  + Created field `id` of type `ID!`
  + Created field `createdAt` of type `DateTime!`
  + Created field `description` of type `String!`
  + Created field `url` of type `String!`

Applying changes 979ms
Generating schema 24ms
Saving Prisma Client (JavaScript) at /Users/xxxx/hackernews-node/src/generated/prisma-client

Your Prisma endpoint is live:

  HTTP:  https://us1.prisma.sh/eiji-shinohara-e75aef/hackernews-node/dev
  WS:    wss://us1.prisma.sh/eiji-shinohara-e75aef/hackernews-node/dev

You can view & edit your data here:

  Prisma Admin: https://us1.prisma.sh/eiji-shinohara-e75aef/hackernews-node/dev/_admin

そしてPrisma APIを通してデータベースとやりとりできるように prisma generate コマンドで prisma.yml を元に自動生成されます。

$ prisma generate
Generating schema 20ms
Saving Prisma Client (JavaScript) at /Users/xxxx/hackernews-node/src/generated/prisma-client

自動生成されたコードは hackernews-node/src/generated/prisma-client のパスに保存されます。これをimportして👇のようなシンプルなNodeのスクリプトを書くことができます。Linkをcreateしてから全て読み込んでprintする的な。またTypeScript定義も生成されるので、これによってVisual Studio Codeなどを使うとIDEで自動補完とかも出来るようになる、と。

const { prisma } = require('./generated/prisma-client')

async function main() {

  // Create a new link
  const newLink = await prisma.createLink({ 
    url: 'www.prisma.io',
    description: 'Prisma replaces traditional ORMs',
  })
  console.log(`Created new link: ${newLink.url} (ID: ${newLink.id})`)

  // Read all links from the database and print them to the console
  const allLinks = await prisma.links()
  console.log(allLinks)
}

main().catch(e => console.error(e))

次の章ではAPIを進化させGraphQLサーバーとPrismaクライアントを使ってデータベースにアクセスするようなリゾルバ半クションを作っていきます。

このエントリーをはてなブックマークに追加

Algolia検索からの流入のみConversionボタン表示