
GraphQLでデータ操作をしてみた
2023.07.10
はじめに
こんにちは、福岡オフィスでWebエンジニアとして働いているずおです!
今回は、GraphQLでデータ操作をしてみるというお題で記事を書いていきたいと思います。
よろしくお願いします。
GraphQLとは
一言で言うと「APIのクエリ言語」です。
REST APIと異なり、GraphQLは、基本的に1つのエンドポイントから、自分が欲しい情報だけを取得することができます。
RESTとGraphQLの対応関係は下記の通りです。
REST | GraphQL | |
---|---|---|
取得 | GET | Query |
登録 | POST | Mutation |
更新 | PATCH | Mutation |
削除 | DELETE | Mutation |
詳しくは、こちらの記事をご参照ください。
では実際にGraphQLを利用してみましょう!
GraphQLサーバー構築
まずは、ディレクトリを作成し、package.jsonを作成します。
私はディレクトリ名をgraphql-backendとしました。
1 2 3 | mkdir graphql-backend cd graphql-backend npm init -y |
次に、apollo/serverとgraphqlライブラリのインストールを行います。
1 | npm install @apollo/server graphql |
インストール完了後、package.jsonにライブラリが追加されていればOKです!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | { "name": "graphql-backend", "version": "1.0.0", "description": "", "main": "index.js", "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@apollo/server": "^4.7.4", "graphql": "^16.7.1" } } |
そして、schema.graqhqlファイルを作成し、スキーマを定義していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # GraphQLスキーマを定義する type Query { info: String! feed: [Link!]! } type Mutation { post(url: String!, description: String!): Link! } type Link { id: ID! description: String! url: String! } |
次にindex.js
ファイルを作成し、先ほど別ファイルで定義したスキーマを読み込みます。
1 2 3 4 5 6 | import { ApolloServer } from "@apollo/server"; import { startStandaloneServer } from "@apollo/server/standalone"; import { readFileSync } from "fs"; // schema.graphqlファイルを読み込む const typeDefs = readFileSync("./src/schema.graphql", { encoding: 'utf-8' }); |
次にリゾルバを定義します。
スキーマで定義された型の取得方法を定義し、実際にデータ操作を行うのがリゾルバというものになります。
1 2 3 4 5 6 | // リゾルバを定義する const resolvers = { Query: { info: () => `github information` } }; |
スキーマとリゾルバが定義できたら、ApolloServerをインスタンス化し、
それをstartStandaloneServerに渡し、実際にサーバーが起動できているか確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | // ApolloServerをインスタンス化する const server = new ApolloServer({ typeDefs, resolvers }); // startStartaloneServer関数にApolloServerインスタンスを渡す const { url } = await startStandaloneServer(server, { listen: { port: 4000 }, }); // console.logでサーバーのURLを表示する console.log(`🚀 Server ready at ${url}`); |
無事起動できました😀
Prisma
それでは、DBにデータを保存するためprisma、prisma/clientをインストールします
1 | npm install prisma --save-dev |
1 | npm install @prisma/client |
インストール後、初期化処理を行います。
1 | npx prisma init |
実行後、prismaディレクトリに、schema.prismaファイルが作成されます。
今回DBはSQliteを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = "file:./dev.db" } model Link { id Int @id @default(autoincrement()) createdAt DateTime @default(now()) description String url String } |
model作成後、マイグレーションを行います
1 | npx prisma migrate dev --name init |
1 2 3 4 5 6 7 | -- CreateTable CREATE TABLE "Link" ( "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "description" TEXT NOT NULL, "url" TEXT NOT NULL ); |
マイグレーションファイルが作成されたので、Prisma Clientを再生成します。
1 | npx prisma generate |
script.jsファイルを作成し、Prisma Clientでデータベース操作をするためのコードを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // DBにアクセスするためのクライアントライブラリ import { PrismaClient } from "@prisma/client"; // PrismClientのインスタンスを作成 const prisma = new PrismaClient(); async function main() { const newLink = await prisma.link.create({ data: { description: "this is zuoboo's github", url: "https://github.com/zuoboo", }, }); const allLinks = await prisma.link.findMany(); console.log(allLinks); } main() .then(async () => { await prisma.$disconnect(); }) .catch(async (e) => { console.error(e); await prisma.$disconnect(); process.exit(1); }); |
1 2 3 4 5 6 7 | node src/script.js { id: 1, createdAt: 2023-06-25T14:04:24.696Z, description: 'this is zuoboo's github', url: 'https://github.com/zuoboo' }, |
ターミナルで確認するとデータが入っているので連携しているようです。
クライアントとPrismaは連携ができたので、次はサーバーとPrismaを連携してみます。
index.jsにコンテキストを追加して、リゾルバ関数内で使用できるようにコードを修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // リゾルバを定義する const resolvers = { Query: { info: () => `github information`, feed: async (parent, args, context) => { return context.prisma.link.findMany(); }, }, Mutation: { post: (parent, args, context) => { const newLink = context.prisma.link.create({ data: { description: args.description, url: args.url, }, }); return newLink; }, }, }; // ApolloServerをインスタンス化する const server = new ApolloServer({ typeDefs, resolvers, }); // startStartaloneServer関数にApolloServerインスタンスを渡す const { url } = await startStandaloneServer(server, { // contextを追加し、リゾルバに渡す context: async ({ req, res }) => ({ prisma, }), listen: { port: 4000 }, }); |
Apollo Serverを起動して、データの取得や作成ができるか確認してみます。
Mutation実行後、
データが追加されました
1 | npx prisma studio |
ちなみに、Prisma Studioを使用すると、データベースの中身をテーブルで確認することもできます!
終わりに
記事をご覧いただきありがとうございました。
今回はバックエンドだけの実装であったことと、GraphQLの初歩的なデータ操作しか扱わなかったので、次回は、フロント側の実装や、もう少し深いところまで記事にできたら良いなと思います。
書いた人はこんな人

- 愛媛県の田舎町で生まれ育ちましたずおと申します。
趣味はサウナと居酒屋巡りです。
未経験で入社させていただいたので、いち早く戦力になれるように日々頑張ります!
座右の銘は「悩んでるひまに、一つでもやりなよ」
ドラえもんの名言です。よろしくお願いします。
IT技術11月 28, 2023Reactで複雑な状態管理を行わずに、レンダリングを最適化する
ライトコードの日常7月 28, 2023YOUは何しにライトコードへ?〜ずお編〜
IT技術7月 5, 2023GraphQLでデータ操作をしてみた