LoginSignup
24
14

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-07-09

概要

  • 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のサーバを立てられるようになった。
24
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
14