Closed6
koa と Apollo Server V4 で GraphQL サーバ構築
業務で GraphQL を使いだしたので、練習のために1から GraphQL サーバを構築してみる。
Apollo Server の4系が先月リリースされたっぽいのでそちらを使用。
リリースノート
サーバーサイドのライブラリは何でもよかったが、軽量かつコミニティで4系のサポートをしている koa
を採用してみる。
express
は公式でミドルウェアをサポートしてるらしい。
他のコミニティサポートはここで確認できる。
まずは、必要最低限のライブラリをインストールしてみる。
$ yarn add koa ts-node typescript
$ yarn add -D @types/koa @types/node
ディレクトリ構成は以下の通り。
(実際はモノリポ構成で同階層に frontend/
もある)
backend/
├── README.md
├── node_modules/
│ └── ...
├── .gitignore
├── package.json
├── src/
│ └── server.ts
├── tsconfig.json
└── yarn.lock
例によって Hello world 的なことをする。
koa
の README に記載してある、Hello Koa
を参考にしつつ、src/server.ts
を実装。
// src/index.ts
import Koa from "koa";
const app = new Koa();
app.use((ctx) => {
ctx.body = "Hello Koa!";
});
app.listen(3000, () => {
console.log("started server on http://localhost:3000");
});
npm scripts に "dev": "ts-node src/server.ts"
を追加して、実行してみる。
$ yarn dev
yarn run v1.22.19
> ts-node src/server.ts
started server on http://localhost:3000
3000 番ポートにアクセスできることを確認 👀
@as-integrations/koa
を参考に @apollo/server
を koa
に組み込んでみる。
足りてないライブラリをインストール。
$ yarn add koa-bodyparser @koa/cors @apollo/server graphql @as-integrations/koa
$ yarn add -D @types/koa-bodyparser @types/koa__cors
@as-integrations/koa
のサンプルは .mjs
だが .ts
でやりたいので、即時関数で囲って実行してみたら実行はできた。
型が合わなかったので、() => resolve(null)
にしてみたけどこれはいいのかは不明。
// server.ts
import http from 'http';
import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import cors from '@koa/cors';
import { ApolloServer } from '@apollo/server';
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
import { koaMiddleware } from '@as-integrations/koa';
// The GraphQL schema
const typeDefs = `#graphql
type Query {
hello: String
}
`;
// A map of functions which return data for the schema.
const resolvers = {
Query: {
hello: () => "world",
},
};
(async () => {
const app = new Koa();
const httpServer = http.createServer(app.callback());
// Set up Apollo Server
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],
});
await server.start();
app.use(cors());
app.use(bodyParser());
app.use(
koaMiddleware(server, {
context: async ({ ctx }) => ({ token: ctx.headers.token }),
})
);
await new Promise((resolve) =>
httpServer.listen({ port: 3000 }, () => resolve(null))
);
console.log(`🚀 Server ready at http://localhost:3000`);
})();
$ yarn dev
yarn run v1.22.19
> ts-node src/server.ts
🚀 Server ready at http://localhost:3000
Koa.js
でルーティングを行うには、Router が別途必要。
$ yarn add @koa/router @types/koa__router
入れたら、あとはルーティングの記述を追加するだけ。
import Router from '@koa/router';
// 略
app.use(cors());
app.use(bodyParser());
router.post(
'/graphql',
koaMiddleware(server, {
context: async ({ ctx }) => ({ token: ctx.headers.token }),
}),
);
app.use(router.routes());
app.use(router.allowedMethods());
await new Promise((resolve) =>
httpServer.listen({ port: 3000 }, () => resolve(null))
);
console.log(`🚀 Server ready at http://localhost:3000`);
これで、http://localhost:3000/graphql
がエンドポイントになる。
このスクラップは2024/01/11にクローズされました