• トップ
  • ブログ一覧
  • GraphQLでデータ操作をしてみた
  • GraphQLでデータ操作をしてみた

    ずお(エンジニア)ずお(エンジニア)
    2023.07.05

    IT技術

    はじめに

    こんにちは、福岡オフィスでWebエンジニアとして働いているずおです!

    今回は、GraphQLでデータ操作をしてみるというお題で記事を書いていきたいと思います。

    よろしくお願いします。

    GraphQLとは

    一言で言うと「APIのクエリ言語」です。

    REST APIと異なり、GraphQLは、基本的に1つのエンドポイントから、自分が欲しい情報だけを取得することができます。

    RESTとGraphQLの対応関係は下記の通りです。

    RESTGraphQL
    取得GETQuery
    登録POSTMutation
    更新PATCHMutation
    削除DELETEMutation

    詳しくは、こちらの記事をご参照ください。

    では実際にGraphQLを利用してみましょう!

    GraphQLサーバー構築

    まずは、ディレクトリを作成し、package.jsonを作成します。

    私はディレクトリ名をgraphql-backendとしました。

    1mkdir graphql-backend
    2cd graphql-backend
    3npm init -y

    次に、apollo/serverとgraphqlライブラリのインストールを行います。

    1npm install @apollo/server graphql

    インストール完了後、package.jsonにライブラリが追加されていればOKです!

    1{
    2  "name": "graphql-backend",
    3  "version": "1.0.0",
    4  "description": "",
    5  "main": "index.js",
    6  "type": "module",
    7  "scripts": {
    8    "test": "echo \"Error: no test specified\" && exit 1"
    9  },
    10  "keywords": [],
    11  "author": "",
    12  "license": "ISC",
    13  "dependencies": {
    14    "@apollo/server": "^4.7.4",
    15    "graphql": "^16.7.1"
    16  }
    17}

    そして、schema.graqhqlファイルを作成し、スキーマを定義していきます。

    1# GraphQLスキーマを定義する
    2type Query {
    3  info: String!
    4  feed: [Link!]!
    5}
    6
    7type Mutation {
    8  post(url: String!, description: String!): Link!
    9}
    10
    11type Link {
    12  id: ID!
    13  description: String!
    14  url: String!
    15}

    次にindex.jsファイルを作成し、先ほど別ファイルで定義したスキーマを読み込みます。

    1import { ApolloServer } from "@apollo/server";
    2import { startStandaloneServer } from "@apollo/server/standalone";
    3import { readFileSync } from "fs";
    4
    5// schema.graphqlファイルを読み込む
    6const typeDefs = readFileSync("./src/schema.graphql", { encoding: 'utf-8' });

    次にリゾルバを定義します。

    スキーマで定義された型の取得方法を定義し、実際にデータ操作を行うのがリゾルバというものになります。

    1// リゾルバを定義する
    2const resolvers = {
    3	Query: {
    4		info: () => `github information`
    5	}
    6};

    スキーマとリゾルバが定義できたら、ApolloServerをインスタンス化し、

    それをstartStandaloneServerに渡し、実際にサーバーが起動できているか確認します。

    1// ApolloServerをインスタンス化する
    2const server = new ApolloServer({
    3	typeDefs,
    4	resolvers
    5});
    6
    7// startStartaloneServer関数にApolloServerインスタンスを渡す
    8const { url } = await startStandaloneServer(server, {
    9  listen: { port: 4000 },
    10});
    11
    12// console.logでサーバーのURLを表示する
    13console.log(`🚀 Server ready at ${url}`);

    無事起動できました😀

    Prisma

    それでは、DBにデータを保存するためprisma、prisma/clientをインストールします

    1npm install prisma --save-dev
    1npm install @prisma/client

    インストール後、初期化処理を行います。

    1npx prisma init

    実行後、prismaディレクトリに、schema.prismaファイルが作成されます。

    今回DBはSQliteを使用します。

    1// This is your Prisma schema file,
    2// learn more about it in the docs: https://pris.ly/d/prisma-schema
    3
    4generator client {
    5  provider = "prisma-client-js"
    6}
    7
    8datasource db {
    9  provider = "sqlite"
    10  url      = "file:./dev.db"
    11}
    12
    13model Link {
    14  id          Int      @id @default(autoincrement())
    15  createdAt   DateTime @default(now())
    16  description String
    17  url         String
    18}

    model作成後、マイグレーションを行います

    1npx prisma migrate dev --name init
    1-- CreateTable
    2CREATE TABLE "Link" (
    3    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    4    "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    5    "description" TEXT NOT NULL,
    6    "url" TEXT NOT NULL
    7);

    マイグレーションファイルが作成されたので、Prisma Clientを再生成します。

    1npx prisma generate

    script.jsファイルを作成し、Prisma Clientでデータベース操作をするためのコードを記述します。

    1// DBにアクセスするためのクライアントライブラリ
    2import { PrismaClient } from "@prisma/client";
    3
    4// PrismClientのインスタンスを作成
    5const prisma = new PrismaClient();
    6
    7async function main() {
    8  const newLink = await prisma.link.create({
    9    data: {
    10      description: "this is zuoboo's github",
    11      url: "https://github.com/zuoboo",
    12    },
    13  });
    14  const allLinks = await prisma.link.findMany();
    15  console.log(allLinks);
    16}
    17
    18main()
    19  .then(async () => {
    20    await prisma.$disconnect();
    21  })
    22  .catch(async (e) => {
    23    console.error(e);
    24    await prisma.$disconnect();
    25    process.exit(1);
    26  });
    1node src/script.js
    2{
    3id: 1,
    4createdAt: 2023-06-25T14:04:24.696Z,
    5description: 'this is zuoboo's github',
    6url: 'https://github.com/zuoboo'
    7},

    ターミナルで確認するとデータが入っているので連携しているようです。
    クライアントとPrismaは連携ができたので、次はサーバーとPrismaを連携してみます。

    index.jsにコンテキストを追加して、リゾルバ関数内で使用できるようにコードを修正します。

    1// リゾルバを定義する
    2const resolvers = {
    3  Query: {
    4    info: () => `github information`,
    5    feed: async (parent, args, context) => {
    6      return context.prisma.link.findMany();
    7    },
    8  },
    9
    10  Mutation: {
    11    post: (parent, args, context) => {
    12      const newLink = context.prisma.link.create({
    13        data: {
    14          description: args.description,
    15          url: args.url,
    16        },
    17      });
    18      return newLink;
    19    },
    20  },
    21};
    22
    23// ApolloServerをインスタンス化する
    24const server = new ApolloServer({
    25  typeDefs,
    26  resolvers,
    27});
    28
    29// startStartaloneServer関数にApolloServerインスタンスを渡す
    30const { url } = await startStandaloneServer(server, {
    31  // contextを追加し、リゾルバに渡す
    32  context: async ({ req, res }) => ({
    33    prisma,
    34  }),
    35  listen: { port: 4000 },
    36});

    Apollo Serverを起動して、データの取得や作成ができるか確認してみます。

    Mutation実行後、

    データが追加されました

    1npx prisma studio

    ちなみに、Prisma Studioを使用すると、データベースの中身をテーブルで確認することもできます!

    終わりに

    記事をご覧いただきありがとうございました。

    今回はバックエンドだけの実装であったことと、GraphQLの初歩的なデータ操作しか扱わなかったので、次回は、フロント側の実装や、もう少し深いところまで記事にできたら良いなと思います。

     

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    ずお(エンジニア)
    ずお(エンジニア)
    Show more...

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background