ゼロからGraphQLと簡単なWebアプリの練習環境を整える
最近、少しだけ GraphQL に触れる機会がありました。過去に少しだけ経験したことがありましたが、久しぶりに練習しようと思い立ち、GraphQL を使う環境と具体的にどう使えるのか確認するための Web アプリを作成してみました。
今回試した環境
- MacBook Air M1 (Darwin Kernel Version 23.5.0)
- orbstack: 1.6.4_17192
- docker: Docker version 26.1.3, build b72abbb
- docker compose: Docker Compose version v2.27.3
今回作るお試しシステム環境について
まず、どのようなシステム構成でお試し環境を作るかを説明します。目標は以下の通りです。
一般的な 3 層アーキテクチャを docker compose
で実現します。
せっかくなので、GraphQL を便利に使いこなすため、今回は少し複雑な場合を想定してみます。具体的には、ドキュメント DB である MongoDB とリレーショナル DB である PostgreSQL の両方をデータソースとして統合し、GraphQL から操作できる環境を作ります。
今回は効率や理想的な設計については考慮せず、GraphQL が PostgreSQL や MongoDB など異なる種類の DB を扱えるよということを確認できることを目標とします。
想定するシステムの要件と動作
なるべく単純にして下記を想定します。
- 書店は PostgreSQL で管理されている
- 本は MongoDB で管理されている
- 書店と本のつながりは一旦 PostgreSQL で管理する
- DB に対する操作として Create と Read のみを想定する
- ユーザーは web アプリから下記操作できる
- 本一覧を表示する
- 書店を検索して書店にある本の在庫を表示する
- 書店に本の在庫を追加する
PostgreSQL と MongoDB の ER 図は下記のとおりです。
GraphQL を MongoDB と PostgreSQL で利用したい
今回作る構成
├── docker-compose.yml ... mongo, postgresql, graphql server, web appを検証として立ち上げるためのdocker compose
├── mongodb ... mongodb のデータ保管用
├── postgresql ... postgresql のデータ保管用
├── server ... GraphQL Server (Apollo Server)
│ ├── Dockerfile
│ ├── dist
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── src
│ └── tsconfig.json
└── web-client ... webアプリ(react-vite)
├── Dockerfile
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── public
├── src
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
Apollo Server と MongoDB の環境を作る
まずは server ディレクトリを作成して、Apollo Serverのチュートリアルに従ってセットアップします。
上記サイト Step 8 まで実行したら、今後の作業のために index.ts
を少し整理して全体的にわかりやすくします。
まずは typeDef.ts
の内容を切り出して、schema.graphql
として切り出します。想定しているシステムでは「本」に対して Create と Read を行いたいので、 GraphQL の mutation を追加します。
type Book {
title: String
author: String
}
type Query {
books: [Book]
}
type AddBookMutationResponse {
code: String!
success: Boolean!
message: String!
book: Book
}
type Mutation {
addBook(title: String, author: String): AddBookMutationResponse
}
GraphQL のスキーマから自動的に TypeScript のタイプを生成するために、追加のパッケージをインストールして、初期設定します(参考)。
npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers
➜ npx graphql-code-generator init
Welcome to GraphQL Code Generator!
Answer few questions and we will setup everything for you.
? What type of application are you building? Backend - API or server
? Where is your schema?: (path or url) ./schema.graphql
? Pick plugins: TypeScript (required by other typescript plugins), TypeScript Resolvers (strongly typed resolve functions)
? Where to write the output: src/generated/graphql.ts
? Do you want to generate an introspection file? Yes
? How to name the config file? codegen.ts
? What script in package.json should run the codegen? codegen
Fetching latest versions of selected plugins...
Config file generated at codegen.ts
$ npm install
To install the plugins.
$ npm run codegen
To run GraphQL Code Generator.
+ "scripts": {
+ "codegen": "graphql-codegen --config codegen.ts",
+ "compile": "npm run codegen && tsc",
+ "start": "npm run compile && node ./dist/src/index.js"
+ },
次に、 index.ts
の resolvers の内容を別ファイルに切り出します。
MongoDB に対しての ORM として、今回は mongoose を利用して Book スキーマのモデルを作成します。
import mongoose from "mongoose";
const bookSchema = new mongoose.Schema({
title: String,
author: String,
});
export const Book = mongoose.model("Book", bookSchema);
続いて、 server/src/graphql/resolvers.ts
に GraphQL の Resolver を作ります。
import { AddBookMutationResponse } from "generated/graphql.js";
import { Book } from "../models/book.js";
export const resolvers = {
Query: {
books: async () => await Book.find(),
},
Mutation: {
addBook: async (_, { title, author }): Promise<AddBookMutationResponse> => {
const book = new Book({ title, author });
try {
await book.save();
return {
createdAt: new Date().toISOString(),
message: "added",
success: true,
book: book,
};
} catch (error) {
return {
createdAt: null,
message: "failed",
success: false,
book: null,
};
}
},
},
};
この状態で、 一旦 MongoDB をバックエンドとして、 GraphQL を叩くための環境を docker compose
で確認できるようにします。
今回使用する Dockerfile は適当なので、 docker compose up --build
を多用しますのであしからず。
FROM node:22.3-slim
WORKDIR /apollo-server
COPY package*.json ./
RUN npm ci
COPY . .
CMD [ "npm", "run", "start" ]
また、DB に対する環境変数などを server/.env
として定義しておきます。
MONGO_URL="mongodb://mongodb:27017"
MONGO_INITDB_DATABASE="mydatabase"
MONGO_USER="root"
MONGO_PASS="root_password"
services:
mongodb:
image: mongo:latest
ports:
- 27017:27017
restart: unless-stopped
container_name: mongodb
volumes:
- ./mongodb/data:/data/db
env_file:
- path: ./server/.env
apolloserver:
build:
context: ./server
depends_on:
- mongodb
さらに Apollo Server から MongoDB に接続できるように server/index.ts
を変更します。
dotenv
を使用して環境変数読み込み、mongoose
使ってデータソースとして接続します。
import { ApolloServer } from "@apollo/server";
import { startStandaloneServer } from "@apollo/server/standalone";
import { resolvers } from "./graphql/resolvers.js";
import { readFileSync } from "node:fs";
import mongoose from "mongoose";
import "dotenv/config";
const MONGO_URL = process.env.MONGO_URL as string;
const MONGO_INITDB_DATABASE = process.env.MONGO_INITDB_DATABASE as string;
const MONGO_USER = process.env.MONGO_USER as string;
const MONGO_PASS = process.env.MONGO_PASS as string;
const typeDefs = readFileSync("./schema.graphql", { encoding: "utf-8" });
const connection = await mongoose.connect(
MONGO_URL,
{
user: MONGO_USER,
pass: MONGO_PASS,
dbName: MONGO_INITDB_DATABASE,
}
);
console.log("🚀 Server ready at MongoDB");
const server = new ApolloServer({
typeDefs,
resolvers,
});
const { url } = await startStandaloneServer(server, {
listen: { port: 4000 },
});
console.log(`🚀 Server ready at: ${url}`);
ひとまずこれで、 docker compose up
で立ち上げて、 Apollo Server が用意してくれている GraphQL playground から GraphQL を実行・確認できるようになります。
下記は GraphQL playground の動作している様子です(books query 実行後の結果にあるデータは addBook
の mutation で適当に突っ込んだものです)。
確認したら一旦 container を落として次に進みます。
Apollo Server と PostgreSQL の環境を作る
続いて、「書店」に関する Shop スキーマを定義して、PostgreSQL をデータソースとして接続します。
「本」のときと同様に Create と Read ができるようにして、さらに「本を在庫として書店に追加する」mutation と「書店から本の在庫を取得する」query を作ります。
+ type Shop {
+ name: String
+ stock: [Book]
+ }
+
+ type AddShopMutationResponse {
+ createdAt: String!
+ success: Boolean!
+ message: String!
+ shop: Shop
+ }
+
+ type AddBookStockToShopMutationResponse {
+ createdAt: String!
+ success: Boolean!
+ message: String!
+ book: Book
+ shop: Shop
+ }
+
+ input BookToShopInput {
+ bookName: String
+ shopName: String
+ }
+
type Mutation {
addBook(title: String, author: String): AddBookMutationResponse
+ addShop(name: String): AddShopMutationResponse
+ addBookToShop(input: BookToShopInput): AddBookStockToShopMutationResponse
}
+
type Query {
books: [Book]
+ shops: [Shop]
+ getStock(name: String): [Book]
}
また、今回は PostgreSQL のデータモデルがすでに存在しているという状態を想定して init.sql
を作ります。
-- 店情報
CREATE TABLE shop (
id SERIAL PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
-- 店情報とリレーションのある本の在庫情報
CREATE TABLE rel_shop_book (
shopid INTEGER NOT NULL,
bookid VARCHAR(24) NOT NULL,
PRIMARY KEY (shopid, bookid),
CONSTRAINT fk_shop
FOREIGN KEY (shopid)
REFERENCES shop(id)
ON DELETE CASCADE
);
CREATE INDEX idx_rel_shop_book_shopid ON rel_shop_book(shopid);
PostgreSQL のための情報も env ファイルに追記します。このとき一旦接続先を localhost
にしておきます(理由は後述)。
+ POSTGRES_USER="testadmin"
+ POSTGRES_PASSWORD="testadmin"
+ POSTGRES_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/"
services:
+ postgres:
+ image: postgres
+ restart: always
+ env_file:
+ - path: ./server/.env
+ volumes:
+ - ./postgresql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
+ - ./postgresql/data:/var/lib/postgresql/data
+ tty: true
+ ports:
+ - 5432:5432
続いて、PostgreSQL への ORM としてPrisma を導入します。
Prisma が使えるように Apollo Server の Dockerfile をちょこっと変えています。
+ # Install necessary libraries for Prisma
+ RUN apt-get update && \
+ apt-get install -y openssl libssl-dev zlib1g libgcc1 libc6 && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
npm install -D prisma
でインストールを行い、npx prisma init
で初期化しようとしたのですが、OrbStack の環境だと下記のエラーが発生したので、指示通り schema.prisma
を修正しました。
apolloserver-1 | PrismaClientInitializationError: Prisma Client could not locate the Query Engine for runtime "linux-arm64-openssl-3.0.x".
apolloserver-1 |
apolloserver-1 | This happened because Prisma Client was generated for "darwin-arm64", but the actual deployment required "linux-arm64-openssl-3.0.x".
apolloserver-1 | Add "linux-arm64-openssl-3.0.x" to `binaryTargets` in the "schema.prisma" file and run `prisma generate` after saving it:
apolloserver-1 |
apolloserver-1 | generator client {
apolloserver-1 | provider = "prisma-client-js"
apolloserver-1 | binaryTargets = ["native", "linux-arm64-openssl-3.0.x"]
apolloserver-1 | }
+ generator client {
+ provider = "prisma-client-js"
+ binaryTargets = ["native", "linux-arm64-openssl-3.0.x"]
+ }
datasource db {
provider = "postgresql"
url = env("POSTGRES_URL")
}
この状態で一旦 docker compose up --buiid
して PostgreSQL の container を立ち上げておき、npx prisma db pull
で PostgreSQL のスキーマ情報から Prisma モデルをインポートしてスキーマを作ります(公式)。
このとき、datasource の url が localhost
となるように server/.env
を設定しましたが、prisma db pull
ができるように localhost
にしていました。
+ /// The underlying table does not contain a valid unique identifier and can therefore currently not be handled by Prisma Client.
+ model rel_shop_book {
+ shopid Int
+ bookid String @db.VarChar(24)
+ shop shop @relation(fields: [shopid], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "fk_shop")
+
+ @@id([shopid, bookid])
+ @@index([shopid], map: "idx_rel_shop_book_shopid")
+ }
+ model shop {
+ id Int @id @default(autoincrement())
+ name String @db.VarChar(30)
+ rel_shop_book rel_shop_book[]
+ }
PostgreSQL のスキーマ情報が schema.prisma
にインポートされたら container を落とします。
続いて Apollo Server で Prisma を使って開発するために、npx prisma generate
で Prisma Client のコードを生成します(詳細はこちら)。
npm run codegen
を実行して、schema.graphql
に追加した Shop のスキーマのタイプを生成したら、いよいよ Prisma 用の Resolver を作っていきます。
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
export const resolvers = {
Query: {
// 一旦面倒なので、shopsはstockを返すように作っていません、、、
+ shops: async () => await prisma.shop.findMany(),
+ getStock: async (_, { name }): Promise<Books> => {
+ const shopWithBooks = await prisma.shop.findFirst({
+ where: {
+ name: name,
+ },
+ select: {
+ id: true,
+ rel_shop_book: {
+ select: {
+ bookid: true,
+ },
+ },
+ },
+ });
+
+ const bookObjectIds = shopWithBooks.rel_shop_book.map(
+ (book) => book.bookid
+ );
+
+ return Book.find({
+ _id: {
+ $in: bookObjectIds,
+ },
+ });
+ }
},
Mutation: {
+ addShop: async (_, { name }): Promise<AddShopMutationResponse> => {
+ const shop = await prisma.shop.create({
+ data: {
+ name: name,
+ },
+ });
+ return {
+ createdAt: new Date().toISOString(),
+ message: "added",
+ success: true,
+ shop: shop,
+ };
+ },
+ addBookToShop: async (
+ _,
+ {input}: MutationAddBookToShopArgs
+ ): Promise<AddBookStockToShopMutationResponse> => {
+ const isExistBook = await Book.findOne({ title: input.bookName });
+ const isExistShop = await prisma.shop.findFirst({
+ where: {
+ name: input.shopName,
+ },
+ });
+ if (isExistBook !== null && isExistShop !== null) {
+ const res = await prisma.rel_shop_book.create({
+ data: {
+ bookid: String(isExistBook._id),
+ shopid: isExistShop.id,
+ },
+ });
+ return {
+ createdAt: new Date().toISOString(),
+ message: "added",
+ success: true,
+ book: isExistBook,
+ shop: isExistShop,
+ };
+ }
+ },
},
};
Apollo Server と Prisma を使って PostgreSQL が接続できるようになったので、動作確認を GraphQL playground から行うのですが、prisma db pull
のために POSTGRES_URL
を localhost
に変えていたので server/.env
を修正します。
- POSTGRES_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/"
+ POSTGRES_URL="postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/"
docker compose up --build
して GraphQL playground から動作確認を行います。
まずは BookShop1
を登録します。
続いてこの BookShop1
に MongoDB にて登録した本 hogehoge
を追加します。
最後に、BookShop1
に hogehoge
が登録されているか、getStock
で確認します。
これで Apollo Server に MongoDB と PostgreSQL 複数のデータソースを利用できる環境が完成しました。
実際の Web アプリの構築
ここまで来たら web-client 側を作り込み、Apollo Server へ GraphQL のリクエストを試せる環境を作ります。
適当にさっさと組みたいので、今回は Vite + React の構成です(https://vitejs.dev/guide/#getting-started)
npm create vite@latest web-client -- --template react-ts
web-client で使う GraphQL の 型を簡単生成する準備
稼働中の Apollo Server から型や定義などを取得して Apollo Client で開発できるようにします。
公式に従えば基本的に問題ないです。
下記必要な package をインストールします。
npm i -D typescript graphql @graphql-codegen/cli @graphql-codegen/client-preset @graphql-typed-document-node/core
続いて、 docker compose up --build
して Apollo Server を立ち上げておき codegen.ts
を作ります。
Apollo Server は localhost:4000
で待ち受けているので、schema
を Apollo Server に設定しておきます。
const config: CodegenConfig = {
schema: "http://localhost:4000/",
// this assumes that all your source files are in a top-level `src/` directory - you might need to adjust this to your file structure
documents: ["src/**/*.{ts,tsx}"],
generates: {
"./src/__generated__/": {
preset: "client",
plugins: [],
presetConfig: {
gqlTagName: "gql",
},
},
},
ignoreNoDocuments: true,
};
export default config;
{
"scripts": {
+ "compile": "graphql-codegen",
+ "watch": "graphql-codegen -w"
},
}
あとは graphql-codegen
を実行すれば(npm run compile
)、 codegen.ts
で設定したディレクトリに GraphQL の型が生成されているので、これを使って web-client 側で作り込みます。
Apollo Client を利用してサーバー側に接続してコンポーネントを作り込む
Apollo Client を利用して web アプリから稼働中の Apollo Server へ接続し、 UI とかを作って GraphQL のリクエストを試します。
Apollo Client は、web-client のコンポーネントツリー全体で接続情報を使用できるように ApolloProvider
を提供していて、これを React App に wrap すればコンポーネントのどこからでも接続して利用できます。(参考)
今回はお試しなので、 React App 全体に ApolloProvider
を wrap します。
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
+ import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
+ const client = new ApolloClient({
+ uri: "http://localhost:4000/graphql",
+ cache: new InMemoryCache(),
+ });
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
+ <ApolloProvider client={client}>
<App />
+ </ApolloProvider>
</React.StrictMode>
);
続いて、前節で GraphQL の型を簡単に生成できる準備しましたが、React コンポーネントを作っていく際にどのように生成された型を利用して、開発を進めていくか地道にやってみたいと思います。
まずは適当なコンポーネント名でファイルを作って、最初自動生成した型からそのコンポーネントが取得したい情報の query を先に書きます。
例えば、 GetAllBooks.tsx
というコンポーネントだったら、下記のように books
を使って GraphQL ドキュメントを書けば、欲しい情報が取得できそうだなと判断できます(下記は自動生成された Query
の型)。
export type Book = {
__typename?: 'Book';
author?: Maybe<Scalars['String']['output']>;
title?: Maybe<Scalars['String']['output']>;
};
export type Query = {
__typename?: 'Query';
books?: Maybe<Array<Maybe<Book>>>;
getStock?: Maybe<Array<Maybe<Book>>>;
shops?: Maybe<Array<Maybe<Shop>>>;
};
上記から GraphQL ドキュメントを一旦コンポーネントに書き出しておいて、
+ import { gql } from "../__generated__";
+
+ const allBookQuery = gql(`
+ query allbooks {
+ books {
+ title
+ author
+ }
+ }
+ `);
この状態で再度 npm run compile
(graphql-codegen
) すると、web-client 側で開発に使用するための GraphQL ドキュメントの型が自動生成されます。
+ export type AllbooksQueryVariables = Exact<{ [key: string]: never; }>;
+ export type AllbooksQuery = { __typename?: 'Query', books?: Array<{ __typename?: 'Book', title?: string | null, author?: string | null } | null> | null };
+ export const AllbooksDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"allbooks"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"books"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"author"}}]}}]}}]} as unknown as DocumentNode<AllbooksQuery, AllbooksQueryVariables>;
このように、欲しい情報を書いたら compile して GraphQL ドキュメントの型をどんどん生成しながらコンポーネントを作り込んでいきます。
watch モードを使えばどんどん生成できるので詳細は公式を参照いただければと思いますが、今回は泥臭くやっていきます。
GraphQL ドキュメントの型が生成されたので、これを使ってコンポーネントを完成させます(typescript-react-apollo
のプラグインもあるのでこちらを利用したほうがスッキリします)。
+ import { useLazyQuery } from "@apollo/client";
+ import {
+ AllbooksDocument,
+ AllbooksQuery,
+ } from "../__generated__/graphql";
+ export function GetAllBooks() {
+ const [books, { loading, error, data }] =
+ useLazyQuery<AllbooksQuery>(AllbooksDocument);
+
+ return (
+ <div className="max-w-md mx-auto p-4">
+ <h1 className="text-2xl font-bold mb-4">Book Search</h1>
+ <div className="mb-4">
+ <button
+ onClick={() => books()}
+ className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
+ >
+ 本一覧
+ </button>
+ </div>
+ <ul className="list-disc pl-5">
+ {!loading && !error && data?.books && data.books.length > 0 ? (
+ data.books.map((book) => {
+ if (book !== null) {
+ return <li
+ key={book.title}
+ >{`タイトル: ${book.title} (著者: ${book.author})`}</li>
+ }
+ })
+ ) : (
+ <li>本一覧はまだありません。</li>
+ )}
+ </ul>
+ </div>
+ );
+ }
本一覧を取得するだけのボタンが付いた適当な UI ですが、動けばなんでもいいです。
npm run dev
でささっと動作確認します。
ボタンを押したらちゃんと本一覧が取得できていることが確認できます。
これ以降はコードを省略しますが、「書店の検索」や「本を書店に追加する」ような UI も作ります。
現在 MongoDB と PostgreSQL に登録されている情報が取得できることを確認します。
書籍名が test
の本を店舗名 BookShop1
に追加してみます。
追加のボタンを押すと、メッセージである added
が表示されます。
最後に、改めて BookShop1
で在庫検索すると、下記の通り見事に本が追加されていることが確認できました。
以上で web アプリ自体の動作確認も完了できたので、最後に web-client も docker compose で動くようにいい感じにしていきます。
このままだと npm run build
したときに、コンポーネントに定義していた使用する GraphQL ドキュメントが unused variable で error になってしまうので、これを schema として別出しします。
具体的には、それぞれのコンポーネントの gql
で定義しているものを .graphql
として定義し直します。
- import { gql } from "../__generated__";
-
- const allBookQuery = gql(`
- query allbooks {
- books {
- title
- author
- }
- }
- `);
query allbooks {
books {
title
author
}
}
src/libs/
└── graphql
├── mutations
│ └── addBookToShop.graphql
└── queries
├── allbooks.graphql
└── getStock.graphql
そして、codegen.ts
についても graphql
の拡張子でも生成できるように設定します。
const config: CodegenConfig = {
schema: "http://localhost:4000/",
- documents: ["src/**/*.{ts,tsx}"],
+ documents: ["src/**/*.{ts,tsx,graphql}"],
generates: {
},
ignoreNoDocuments: true,
};
最後に web-client の Dockerfile を作って、 ApolloProvider の接続先も Apollo Server のコンテナ名にして完了です。
FROM node:22.3-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD [ "npm", "run", "preview"]
+ web-client:
+ build:
+ context: ./web-client
+ depends_on:
+ - apolloserver
+ ports:
+ - 8080:8080
本番では https 化や CORS への対応などが発生しますが、今回はお試し開発環境なので vite proxy を設定して同一オリジンとして接続します。(公式のHTTPS対応とCORSへの対応)
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: {
host: true,
+ proxy: {
+ "/graphql": {
+ target: "http://apolloserver:4000",
+ changeOrigin: true,
+ secure: false,
+ },
+ },
},
});
const client = new ApolloClient({
- uri: "http://apolloserver:4000/graphql",
+ uri: "/graphql",
cache: new InMemoryCache(),
});
お疲れ様でした。これで docker compose up
だけで、MongoDB・PostgreSQL・GraphQL Server・Web アプリを試す環境を作ることができました。
最後に
今回は、GraphQL の練習のために MongoDB + PostgreSQL の DB Apollo Server の環境を構築して Web アプリを作って動作確認までできました。
まだまだ GraphQL は修行中の身ですが、今回のような練習できる環境を立ち上げることで、GraphQL によって異なるデータベースを扱える方法について理解を深めることができました。
今後の展望としては、今回の基礎環境をさらに発展させ、より高度な実践に近い機能を持つ Web アプリを題材としてやっていけたら楽しいかなと思っています。具体的には subscription とか CORS とかの機能とかを試したり N+1 問題とかに対応してみたりしたいですね。
参考文献
- mongooseを使ってmongoDBを記述する #MongoDB - Qiita
- Apollo+MongoDBを使って最小限の使い方を学んでみた
- How to Build A GraphQL API with Node.js, Apollo-Server, and MongoDB Atlas - DEV Community
- [Part2] TypeScript, PostgreSQL, Next.js, Prisma & GraphQLでApp作成
- Handling the N+1 Problem | Apollo GraphQL Docs
- GraphQLスキーマを外部ファイルとして読み込む方法 #Node.js - Qiita
Discussion