Movatterモバイル変換


[0]ホーム

URL:


エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

GraphQL入門 - React.js & Express.js & Apollo の簡単チュートリアル

M3 ではグローバル CTO の Brian が、サービスの海外展開や技術基盤の共通化などを積極的に進めています。その中のプロジェクトの1つとして、アメリカで提供している医療ニュースのリニューアルにチャレンジしています。2018 年 5 月には日本オフィス所属のイギリス人エンジニア@christophrowley と日本人のエンジニア (筆者)が 1 ヶ月ほどニューヨークに出張してリニューアルの検討をしてきました。

f:id:ke-mori:20180612092457j:plain( ↑ Chrisが撮影してくれた NY の写真 )

今回の記事は、リニューアルで採用を検討している GraphQL をApollo +JavaScript で作るチュートリアルです。

TL;DR

  • Apollo を使って、クライアントサイド、バックエンドを作るチュートリアルを紹介
  • 英語・海外での開発に挑戦したいエンジニアを絶賛募集中です。もし興味があればランチ行きましょう!

GraphQL の概要

GraphQL はFacebook が発表した、クライアントアプリがサーバから柔軟にデータを取得できるように設計されたクエリ言語です。

GraphQL の概要を知るのにHow to GraphQL (英語)がオススメです。GraphQL の初心者向けの説明資料や 40 分ほどの動画を掲載されています。React.js やRuby での実装チュートリアルなどもあります。GraphQL の概要を知るのに最適なサイトです。

GraphQL にトライ

GraphQL API Explorer ではGitHub が公開している GraphQL のAPI を簡単に試すことができます。GraphQL がいったいどういうものかを触ってみるのにちょうど良いサンプルです。右上の「Docs ボタン」をクリックすると GraphQL のドキュメントを見ることができるので、参考にしつつクエリを書いてみてください。

GraphQL のメリット

一般的な GraphQLのメリット

GraphQL を採用するメリットは次のようなものがあります。

  • 複数のAPI リクエストを一つにまとめることができ、リソースを無駄なく取得できる
  • Web/iOS/Android の共通したバックエンドを効率的に開発ができる
  • スキーマファースト、ドキュメントファーストで開発ができる
  • 既存・新規アプリや外部サービスのAPI を束ねるAPIGateway として活用できる

M3 US におけるメリット

M3 US で GraphQL を採用したいと考えている理由は:

  • USの開発チームは人数が少ないため、ContentfulOkta のような外部サービスを利用したい。 GraphQLはそういった外部サービス、既存・新サービスのAPIGateway として活用できそう
  • USは利用者のスマートフォン比率が高いので、バックエンドをGraphQLにしてスマホアプリの開発を加速させたい (バックエンドとフロントエンドが非同期に開発しやすかったり、仕様と一致したドキュメントを整備しやすいなど)

Apollo プロジェクトについて

Apollo GraphQLMeteor.js を開発しているチームが中心となって 開発している GraphQL のためのOSS、サービスです。

代表的なツールとしては、

  • Apollo Client
    • React や Vue.js、スマホネイティブ(Swift/Java)のための GraphQL クライアント。GraphQLAPI へのクエリリクエストをサポートしてくれます。
  • Apollo Server
    • Node.js で GraphQLAPI を構築するOSS で、既存のREST API やバックエンドからデータを取得する仕組みを構築できます。
  • Apollo Engine
    • GraphQL クエリの実行状況を監視したり、エラートラッキング、キャッシュの利用状況の監視などを行うツールとクラウドサービスです。

チュートリアル

今回は Node.js による GraphQL バックエンドと、GraphQL を使ってデータを表示する React フロントエンドのチュートリアルを紹介します。動作検証はnode.js v8.11.2で行っています。

GraphQL バックエンド

プロジェクトの初期状態の構築

Express.js を使って、GraphQL のバックエンドを構築します。ターミナルで次のコマンドを実行してください。

# プロジェクトのフォルダを作成して移動mkdir express-graphql && cd express-graphql# Nodeプロジェクトの初期状態を構築npm init# ライブラリをインストールnpm install --save express body-parser cors graphql apollo-server-express graphql-tools graphql-tag

ちなみにインストールしたライブラリは次の通りです。

そしてpackage.jsonscriptを次のように変更します。

"scripts":{  "start": "node ./index.js"}

GraphQL サーバアプリの作成

次にindex.jsを作成して次のように記述します。

const express = require("express");const bodyParser = require("body-parser");const cors = require("cors");const{ graphqlExpress, graphiqlExpress} = require("apollo-server-express");const{ makeExecutableSchema} = require("graphql-tools");// モックデータconst books =[{    title:"Harry Potter and the Sorcerer's stone",    author:"J.K. Rowling",    price: 2000},{    title:"Jurassic Park",    author:"Michael Crichton",    price: 3000}];// GraphQLのスキーマ情報const typeDefs = `  type Query{ books:[Book]}  type Book{ title:String, author:String, price: Int}`;// resolver(データ処理)の設定// DBからデータを取得したり、APIを呼び出したりする処理もここで記述const resolvers ={  Query:{ books: () => books}};// GraphQL の Schema 設定const schema = makeExecutableSchema({  typeDefs,  resolvers});// Expressの初期化const app = express();// Cross-origin resource sharing (CORS) の設定const corsOptions ={  origin:"http://localhost:3000",  optionsSuccessStatus: 200// some legacy browsers (IE11, various SmartTVs) choke on 204};// GraphQLのエンドポイントの追加app.use("/graphql",  bodyParser.json(),  cors(corsOptions),  graphqlExpress({ schema}));// GraphiQLのエンドポイントの追加 (テストで使う GraphQLのWeb GUI)app.use("/graphiql", graphiqlExpress({ endpointURL:"/graphql"}));// サーバの起動app.listen(4000, () =>{  console.log("Go to http://localhost:4000/graphiql to run queries!");});module.exports = app;

GraphQL サーバアプリの動作確認

先程作成した Express.js のアプリを起動するために、ターミナルで次のコマンドを実行してください。

npm run start

http://localhost:4000/graphiqlにアクセスできれば成功です。ちなみに、これは GraphQL のクエリを簡単に試すことができる Web 上のエディタです。例えば、

{  books {    title    author  }}

を左側のペインに入力して再生ボタン(Execute Query)を押すと GraphQL からデータを結果を取得できます。

React フロントエンド

React アプリの初期構築

create-react-app を使って、React フロントエンドのアプリを構築します。ターミナルで次のコマンドを実行します。

# create-react-app のインストール (インストール済の場合はスキップ)npm install -g create-react-app# create-react-app を使って、プロジェクトを作成してそのフォルダに移動create-react-app react-graphql && cd react-graphql# ライブラリのインストールnpm install# 動作確認npm run start

http://localhost:3000 にアクセスして以下の画面が表示されたら成功。

Apollo Client の導入

Apollo Client で使うライブラリをインストールして、GraphQL にアクセスできるようにします。

npm install apollo-boost graphql-tag graphql react-apollo --save
  • apollo-boost :Apollo Client を設定なしで使えるようにしたライブラリセット
  • graphql-tag : GraphQL クエリ記述をサポート
  • graphql : GraphQL のリファレンス実装で、graphql を使うときに利用
  • react-apollo : React.js でApollo を簡単に使えるようにするライブラリ

GraphQL サーバからデータを取得

次に、./src/App.jsを次のように変更します。

import React,{ Component} from"react";import ApolloClient from"apollo-boost";import{ ApolloProvider} from"react-apollo";import Books from"./Books";const client =new ApolloClient({ uri:"http://localhost:4000/graphql"});class Appextends Component{  render(){return (      <ApolloProvider client={client}>{/* ↑ Apolloクライアント(GraphQLのクエリ)を使えるように設定 */}        <div>          <h2>My first Apollo app</h2>          <Books />        </div>      </ApolloProvider>    );}}exportdefault App;

次に、./src/Books.jsを作成して、GraphQL から書籍bookの情報を取得します。

import React from"react";import{ Query} from"react-apollo";import gql from"graphql-tag";const Books = () => (  <Query    query={/* GraphQLのクエリ */      gql`{          books{            title            author            price}}      `}  >{/* GraphQLのクエリの実行結果の処理、成功したら結果を表示 */}{({ loading, error, data}) =>{if (loading)return <p>Loading...</p>;if (error)return <p>Error</p>;return data.books.map(course => (        <div key={course.title}>          <p>title:{`${course.title}`}</p>          <p>author:{`${course.author}`}</p>          <p>price:{`${course.price}`}</p>          <hr />        </div>      ));}}  </Query>);exportdefault Books;

React アプリの動作確認

作成した React フロントエンドを起動するために、ターミナルで次のコマンドを実行してください。

# React フロントエンド(react-graphql)フォルダで以下のコマンドを実行npm run start

ブラウザで、http://localhost:3000/にアクセスして、GraphQL サーバのデータを取得できていれば成功です。

Apollo Engine

GraphQL のパフォーマンスの監視などを行うサービスとしてApollo Engine があります。このサービスは、GraphQL のクエリの実行日時、処理時間、処理時間の内訳、エラーの発生率やキャッシュヒット率などを確認できます。100 万クエリ / 月までは無料で利用することができます。

まずはApollo Engine の Web 画面からAPI KEYを取得します。

次にapollo-engine と環境変数を管理するdotenv をインストールします。

# Apollo Server(Express.js)のフォルダへ移動cd express-graphql# apollo-engine dotenv をインストールnpm install --save apollo-engine dotenv# .env に先程取得したAPI KEYを設定echo "APOLLO_ENGINE_API_KEY=XXX" > .env

Apollo Server(Express.js)のプロジェクトのindex.jsを次のように変更。

require("dotenv/config");// .envの環境変数の読み込みconst express = require("express");const bodyParser = require("body-parser");const cors = require("cors");const{ ApolloEngine} = require("apollo-engine");const{ graphqlExpress, graphiqlExpress} = require("apollo-server-express");const{ makeExecutableSchema} = require("graphql-tools");const{ APOLLO_ENGINE_API_KEY} = process.env;// モックデータconst books =[{    title:"Harry Potter and the Sorcerer's stone",    author:"J.K. Rowling",    price: 2000},{    title:"Jurassic Park",    author:"Michael Crichton",    price: 3000}];// GraphQLのスキーマ情報const typeDefs = `  type Query{ books:[Book]}  type Book{ title:String, author:String, price: Int}`;// resolver(データ処理)の設定// DBからデータを取得したり、APIを呼び出したりする処理もここで記述const resolvers ={  Query:{ books: () => books}};// GraphQL の Schema 設定const schema = makeExecutableSchema({  typeDefs,  resolvers});// Expressの初期化const app = express();// Cross-origin resource sharing (CORS) の設定const corsOptions ={  origin:"http://localhost:3000",  optionsSuccessStatus: 200// some legacy browsers (IE11, various SmartTVs) choke on 204};// GraphQLのエンドポイントの追加app.use("/graphql",  bodyParser.json(),  cors(corsOptions),  graphqlExpress({ schema}));// GraphiQLのエンドポイントの追加 (テストで使う GraphQLのWeb GUI)app.use("/graphiql", graphiqlExpress({ endpointURL:"/graphql"}));// Apollo Engineのインスタンスの作成const engine =new ApolloEngine({  apiKey: APOLLO_ENGINE_API_KEY,// メモリキャッシュの設定  stores:[{      name:"inMemEmbeddedCache",      inMemory:{        cacheSize: 104857600// 100 MB、デフォルトは50MB}}],  logging:{    level:"INFO"// ログの設定変更。DEBUGにするとより細かい情報を確認できます}});// サーバの起動engine.listen({  port: 4000,  expressApp: app});module.exports = engine;

これで Express.js を再起動して、画面をリロードしてみます。ターミナルで以下を実行してください。

# express-graphqlフォルダで npm run start を実行したターミナルでCtrl + C 。その上で再度以下を実行npm run start

そうするとApollo Engine にパフォーマンス情報などを送信するようになります。React側の画面にもう一度アクセスをしたあとに数秒おいてApollo Engine をリロードしてみてください。

実際に GraphQL のAPI を運用する場合はこういった情報を使ってパフォーマンスを計測したり、必要に応じてリゾルバやキャッシュの改善を行う必要があると考えています。

GitHub レポジトリ

今回のチュートリアルのコードをGitHub に公開しています。良ければ参考にお使いください。

https://github.com/m3dev/graphql-apollo-sample

今後の課題

今回のチュートリアルでは GraphQL のAPI を簡単に構築できることを紹介しました。実際に本番で運用する場合には次のような課題を検討・解決していく必要があると考えています。

  • AWS App Sync のような仕組みを使うべきか、自前で GraphQL アプリを開発すべきか?
  • 不特定多数のクライアントに GraphQL のAPI を公開する場合は、クエリの実行権限管理や事前にクエリのコストを見積もる仕組みの整備が必要
  • Web 画面のフォームのバリデーションと、GraphQL 側のバリデーションをどう整合性を取るか?などのアプリ開発での実践的なノウハウ

海外で一緒に働いてもらえるエンジニアを募集中

M3 ではアメリカやイギリス(EU)のビジネスの拡大に伴い、一緒に働いてもらえるエンジニアを募集しています!

また社内や グループ会社のメビックス でもGraphQL や Vue.js を使ったプロジェクトが着々と進行中です!GraphQLの開発に興味がある方もぜひエンジニア向けフォーム からお気軽にご連絡ください!

GraphQL 関連のおすすめサイト

Apollo Blog

Apllo を開発しているチームの Blog (英語)です。セキュリティやキャッシュ、負荷対策など GraphQL を本番で使うために必要な実践的な知識を紹介してくれており、大変参考になります。

おまけ:便利そうなサービス・ツール

その他、GraphQL を調査している段階で面白そうなサービスをいくつか見つけたのでその紹介です。

Prisma & graphql-yoga

Postgraphile

PostreSQL のフロントで GraphQL を提供してくれるOSS、既存の DB に対して簡単に GraphQL を提供できるのが面白い。

参考リンク

検索
注目記事

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp