Published on

vercelとnext.jsでgraphqlのapiサーバをたてる方法

Authors
  • avatar
    Name
    ssu
    Twitter

graphqlのapiを作って、vercelで提供する方法を紹介します。 また例ではわかりやすいように、果物を返すAPIとしています。

では、まずtypescriptが使えるnext.jsを作ります。

npx create-next-app graphql-api --ts

次に、作成したgraphql-apiに移動します。

cd graphql-api

そうしたら、今回のプロジェクトで必要になるライブラリをインストールします。 micro-corsはtypeもインストールしてあげます。

yarn add graphql apollo-server-micro micro-cors micro yarn add -D @types/micro-cors

次に、graphqlのディレクトリを作り、schema.tsとresolver.tsを作成します。 schemaはgraphqlの型を定義します(データベースのschemaと同じです。) そして、resolverでは、graphqlでqueryが呼ばれたときにどのデータを返すかというロジックを記載するところになります。

mkdir graphql touch graphql/schema.ts touch graphql/resolver.ts

それでは、schemaを書いていきます。 schemaは下記のようにtypeでデータの型をそれぞれ定義し、queryでどのようなクエリに対応するのかを定義します。queryはrest APIを定義する作業に似ているかと思います。

// graphql/schema.ts import { gql } from 'apollo-server-micro' export const typeDefs = gql` type Fruit { id: Int name: String } type Query { fruits: [Fruit] } `

次は, resolverを作成します。今回はdbはただのobjectの配列ですが、fruitsというqueryが来たときには、全て返、fruit(id)とfruitとidが指定されたときは、それに合致するものを返すようにしています。

// graphql/resolver.ts interface Fruit { id: number; name: string; price: number; } const db: Fruit[] = [ { id: 1, name: "apple", price: 100}, { id: 2, name: "banana", price: 130}, { id: 3, name: "orange", price: 110}, { id: 4, name: "grape", price: 140}, ] export const resolvers = { Query: { fruits: () => db, fruit: (id: number) => db.find(fruit => fruit.id == id) } }

最後のapiのところです。api配下にgraphql.tsをかき、そこに次のようなコードを記載します。 ここでは、const cors = Cors()でcors(Cross-Origin Resource Sharing)のライブラリで、 Cors()とすると全てのリクエストに対してオープンになります。実際には、API tokenなどを発行するのが望ましいとおもいます。ただ、今回は飛ばします。

これでセットアップは完了です。

pages/api/graphql.ts import { ApolloServer } from 'apollo-server-micro' import { typeDefs } from '../../graphql/schema' import { resolvers } from '../../graphql/resolvers' import Cors from 'micro-cors' import { MicroRequest } from 'apollo-server-micro/dist/types' import { ServerResponse } from 'http' const cors = Cors() const apolloServer = new ApolloServer({ typeDefs, resolvers }) const startServer = apolloServer.start() export default cors(async (req: MicroRequest, res: ServerResponse) => { if (req.method === 'OPTIONS') { res.end() return false } await startServer await apolloServer.createHandler({ path: '/api/graphql', })(req, res) }) export const config = { api: { bodyParser: false, }, }

次に、yarn run devをしてhttp://localhost:3000/api/graphqlにアクセスしたら、 下記のような画面が出ると思います。

そしたら、query your serverをクリックして、下記のようにqueryを書いて、 runしたら、データが返ってくると思います!

query { fruits { id name price } }

これでおしまいです。 あとは、vercelと連携して、git pushしたら終わりです!

ちなみに、完成形のtreeの構造はこんな形になります。

➜ graphql-api git:(main) ✗ tree -I node_modules . ├── README.md ├── graphql │   ├── resolvers.ts │   └── schema.ts ├── next-env.d.ts ├── next.config.js ├── package-lock.json ├── package.json ├── pages │   ├── _app.tsx │   ├── api │   │   └── graphql.ts │   └── index.tsx ├── public │   ├── favicon.ico │   └── vercel.svg ├── styles │   ├── Home.module.css │   └── globals.css ├── tsconfig.json └── yarn.lock

また、React.js側(クライアント)からGraphQLを使ってデータを取得する方法はこちらを参考にしてみてください。

参考: Fullstack App With TypeScript, PostgreSQL, Next.js, Prisma & GraphQL: GraphQL API

How To Build A GraphQL Server Using Next.js API Routes