Next.js 9で3分で1からTypeScriptのReactサーバーとGraphQLサーバを立てよう


概要



  • Next.js 9のAPI RouteにGraphQLのエンドポイントを生やします

  • Next.jsもGraphQLもTypescriptで書けます


やり方


1. 必要なパッケージをインストール


terminal

yarn add apollo-server-micro graphql micro next@latest react@latest react-dom@latest

yarn add -D typescript @types/react


2. テキトーにメインページを作る

pages/index.tsxを作り、テキトーにメインページを立ちあげる。拡張子をtsxにしておくと、Next.js 9は勝手にTypescriptのtsconfig.jsonを用意してくれる

速さ⚡️を求めるならば、tsconfig.jsonを書く前に、サーバーを立ち上げる。

テキトーなメインページの例👇


pages/index.tsx

export default ()=>(

<p>ほげ</p>
)

Reactのコンポーネントをexport defaultすればそれが配信される。画像などのファイルは/static配下に単に配置すれば配信される。


サーバー立ち上げ


terminal

yarn next



初回のターミナルのログの例


terminal

~/W/next9 graphql ❯❯❯ yarn next

yarn run v1.15.2
warning package.json: No license field
$ '/███████████/██████████/next9 graphql/node_modules/.bin/next'
[ wait ] starting the development server ...
[ info ] waiting on http://localhost:3000 ...
We detected TypeScript in your project and created a tsconfig.json file for you.

Your tsconfig.json has been populated with default values.

[ info ] bundled successfully, waiting for typecheck results ...
[ ready ] compiled successfully (ready on http://localhost:3000)


http://localhost:3000

スクリーンショット 2019-07-09 13.55.19.png

※ Next.js 9からサーバーでプレレンダリングできていると、右下に⚡️マークがつくようになりました。


3. テキトーにGraphQLサーバーを作る

/pages/api配下にはAPIのエンドポイントを生やせる。GraphQLのモックサーバを立てよう。


/pages/api/index.ts

import { ApolloServer, gql } from 'apollo-server-micro';

// ここからGraphQLのモックの定義
const typeDefs = gql`
type Query {
hello: String
}
`
;

const resolvers = {
Query: {
hello: () => 'world',
},
};

const apolloServer = new ApolloServer({ typeDefs, resolvers });

// ここから先はNext.jsが読みに行く領域
export default apolloServer.createHandler({path:"/api"});
export const config = {
api: {
bodyParser: false,
},
};


サーバー再起動するまでもなく、APIが立ち上がる。

http://localhost:3000/api

スクリーンショット 2019-07-09 13.59.28.png

💃🕺嬉しい💃🕺

ここから、ApolloClientを入れるなり、モックじゃないGraphQLサーバーをこしらえるなりすると良い。

参考: Apollo Client + React 入門


終わり



ポイント


tsconfig書く前に、サーバー立ち上げてしまおう。

Next.js 9からは、tsxをNext.jsが見えるどこかにおけば、勝手に以下のtsconfig.jsonが用意されてしまう。tsc --initしたのが書き変わるのでさっさと立ち上げたいなら、nextを先にする方が早い。

短絡的に言えば、pages/index.tsx書けばオッケー。


tsconfig.json

{

"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"exclude": [
"node_modules"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
}


apollo-serverはmicro用のやつを使う。

pages/api配下で (req, res)を受け取る関数をexport defaultすれば、APIサーバが立つという寸法。

export default (req, res) => {

res.setHeader('Content-Type', 'application/json')
res.statusCode = 200
res.end(JSON.stringify({ name: 'Nextjs' }))
}

デフォルトのres,req(ただし幾らかミドルウェアが入っている)をいじるより、Zeit▲のmicroでマイクロサービスを/pages/apiにもさもさ生やせば、賑やかになると思う。これはご機嫌。

参考:next.js/examples/api-routes-micro/

ということで、apollo-server-ナンチャラは、apollo-server-microを使うっぽいなあってのは、API Routeの見た目にわかった。しかし、GraphQLサーバを立たせるに当たって2点ハマりポイントがあった。


ハマり1. graphQLサーバのパスをちゃんと指定する。

apollo-serverはデフォルトでlocalhost:3000/graphqlにサーバーを立たせようとする。

一方で、Next.js 9はAPIを単純な設定ならばlocalhost:3000/api配下にしか生やせない。したがって、apollo-server-microcreateHandlerにオプションを指定する。

const apolloServer = new ApolloServer({ typeDefs, resolvers });

const handler = apolloServer.createHandler({path:"/api"});

このhandlerexport defaultすれば、graphQLサーバが立つもんだと思ったらそうはいかない。


ハマり2. export const config={option}ちゃんとする

export default handler;

したところでGraphQL Playgroundが動いているので、見た感じAPIが機能しているように思えるが、スキーマをダウンロードできない、クエリを投げられないで、まともに動いていない。

これは、Next.js 9が自動で設定しているbodyParserが原因らしい。数時間時間を潰してしまった。

Next.js 9のAPI routesは備え付けで少しのミドルウェア(cokkieやquery、bodyをreqに生やすことができるやつ)が入っており、その中で、bodyParserはデフォルトでonであり、reqをパースしてしまう。

しかし、API配下で、Next.js 9に設定を伝える方法があるのでこのようにすると、クエリも投げられるし、スキーマもダウンロードできるようになる。以下のconfigは決め打ちで。

export default apolloServer.createHandler({path:"/api"});

export const config = {
api: {
bodyParser: false,
},
};

参考 next.js/examples/api-routes-graphql/


まとめ


  • 恐ろしく楽チンにNextのサーバーとGraphQLのサーバを立てられるようになった。