GraphQL のサーバーを 5 章までの工程で立てましたので、次に GraphQL のクライアント側を実装していきましょう。ざっくりいえば、クライアントというのはサーバーと通信するアプリケーションのことです。GraphQL は柔軟性が高いので、クライアントを作るための特定の制約はありません。ウェブブラウザのためのクライアントを作ることも、スマホ用のネイティブアプリ向けのクライアントを作ることも、冷蔵庫のディスプレイから GraphQL に問い合わせをするものも作れます。GraphQL のクライアントにおいては、どの言語で書かれるかは問題ではありません。

With your GraphQL server built, it’s now time to set up GraphQL on the client side. Very broadly, a client is just an application that communicates with a server. Because of the flexibility of GraphQL, there’s no prescription for how to build a client. You might be building apps for web browsers. You might be creating native applications for phones. You might be building a GraphQL service for a screen on your refrigerator. It also does not matter to the client in which language the service is written.

Query と Mutation を送るために必要な唯一の条件は、HTTP リクエストを投げられることだけです。そうしてデータが送り返されてきたら、そのデータをクライアント側で使用するだけです。クライアントが何でできているか、ということは問題ではありません。

All you really need to send queries and mutations is the ability to send an HTTP request. When the service responds with some data, you can use it in your client no matter what that client is.

GraphQL API を使用する

Using a GraphQL API

GraphQL API を使用する一番簡単な方法は、HTTP リクエストを自分の GraphQL エンドポイントに投げてあげる方法です。Chapter 5 で立てたテストサーバーを使ってみましょう。http://localhost:4000/graphql でサーバーを立ち上げてください。Chapter 6 用リポジトリ にクライアント側のソースは公開していますので、これも参照してください。

The easiest way to begin is just to make an HTTP request to your GraphQL endpoint. To test the server that we built in Chapter 5, make sure your service is running locally at http://localhost:4000/graphql. You can also find all of these samples running on CodeSandbox at the links found in the Chapter 6 repository.

fetch Requests

Chapter 3 でみてきたように、GraphQL サービスに対して cURL を使ってリクエストを投げることができます。以前と異なるのは以下の値だけです。

As you saw in Chapter 3, you can send requests to a GraphQL service by using cURL. All you need is a few different values:

  • クエリ: {totalPhotos, totalUsers}
  • GraphQL のエンドポイント: endpoint:http://localhost:4000/graphql
  • content type:Content-Type:application/json

その設定で terminal もしくはコマンドプロンプトから直に cURL リクエストを POST メソッドで送ることができます。

From there, you send the cURL request directly from the terminal/command prompt using the POST method:

cURL でターミナルからリクエスト
curl -X POST\
  -H "Content-Type: application/json"\
  --data '{"query":"{ totalUsers, totalPhotos}" }'\
  http:// localhost:4000/graphql

このリクエストを送ると、期待した通りの結果が返ってきます。つまり {"data":{"totalUsers":7,"totalPhotos":4}} という値が JSON 形式でターミナルに返ってきます。toralUsers と totalPhotos の値は、現状のデータが反映されているはずです。Shell Script から実行するクライアントだと考えれば、これで cURL を使って達成できましたね。

If we send this request, we should see the correct results, {"data":{"totalUsers":7,"totalPhotos":4}}, as JSON data returned in the terminal. Your numbers for totalUsers and totalPhotos will reflect your current data. If your client is a shell script, you can start building that script with cURL.

cURL を使ってクライアントができたということは、HTTP リクエストを送れるものであればなんでもクライアントとして使えるということです。fetch を使ったちょっとしたクライアントを作ることもできます。ブラウザで実行させることになります。

Because we’re using cURL, we can use anything that sends an HTTP request. We could build a tiny client by using fetch, which will work in the browser:

fetch を使ったブラウザ上のクライアントの例
var query = `{totalPhotos, totalUsers}`;
var url = "http://localhost:4000/graphql";

var opts = {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ query })
};

fetch(url, opts)
  .then(res => res.json())
  .then(console.log)
  .catch(console.error);

データがうまく fetch できると、コンソールに期待した結果が表示されるはずです。

After we fetch the data, we’ll see the expected result logged in the console:

レスポンスの内容
{
  "data": {
    "totalPhotos": 4,
    "totalUsers": 7
  }
}

得られた結果をアプケーションで使用することができます。totalUsers と totalPhotose のリストを DOM に直接反映される、非常に基礎的なコードの例をみてみましょう。

We can use the resulting data on the client to build applications. Let’s consider a basic example to see how we might list totalUsers and totalPhotos directly in the DOM:

リクエストの結果を DOM に直接書き込む
var query = `{totalPhotos, totalUsers}`;
var url = "http://localhost:4000/graphql";

var opts = {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ query })
};

fetch(url, opts)
  .then(res => res.json())
  .then(
    ({ data }) => `
        <p>photos: ${data.totalPhotos}</p>
        <p>users: ${data.totalUsers}</p>
  `
  )
  .then(text => (document.body.innerHTML = text))
  .catch(console.error);

結果を console に表示する代わりに、HTML のテキストを構築するために使用しました。値を使って document の body に直接書き込んだわけです。(注意してほしいのですが、このアプリケーションは、リクエストが完了すると、それ以前に body にあったものを全て上書きします。)

Instead of logging the results to the console, we use the data to build some HTML text. We can then take that text and write it directly to the document’s body. Be careful: it’s possible to overwrite anything that was in the body after the request is complete.

HTTP リクエストを投げれるお気に入りのクライアントがあれば、もうすでに GraphQL API と通信するために必要な道具は揃っているということです。

If you already know how to send HTTP requests using your favorite client, you already have the tools necessary to build a client application that communicates with any GraphQL API.

graphql-request

cURL や fetch でももちろんうまくいくのですが、 GraphQL の一連の手続きをして API に送ってくれるフレームワークを使うこともできます。一番有名なのは graphql-request です。graphql-request は Promise ベースの fetch request をラップしていて、GraphQL サーバーにリクエストをすることができます。リクエストの詳細部分や、受け取った値のパースといったことをあなたの代わりにやってくれます。

Though cURL and fetch work well, there are other frameworks that you can use to send GraphQL operations to an API. One of the most notable examples of this is graphql-request. graphql-request wraps fetch requests in a promise that can be used to make requests to the GraphQL server. It also handles the details of making the request and parsing the data for you.

graphql-request を使い始めるにあたって、まずは次のものをインストールしましょう。

To get started with graphql-request, you first need to install it:

インストール
npm install graphql-request

これで module を import してリクエストのために使用できます。Photo service を port 4000 で動かしておくことを忘れないでください。

From there, you import and use the module as request. Be sure to keep the photo service running on port 4000:

import { request } from "graphql-request";
const query = `
  query listUsers { 
    allUsers { 
      name 
      avatar 
    } 
  } 
`;

request(" http:// localhost: 4000/ graphql", query)
  .then(console.log)
  .catch(console.error);

request 関数は url と query を引数として受けとってサーバーにリクエストを出し、受け取ったデータを返り値として戻します。返ってきたデータは、期待通り JSON 形式で users の情報が全て入ったものになっているはずです。

The request function takes in url and query, makes the request to the server, and returns the data in one line of code. The data returned is, as expected, a JSON response of all of the users:

本当は JSON。これは JS Object
const json = {
  allUsers: [
    { name: "sharon adams", avatar: "http://..." },
    { name: "sarah ronau", avatar: "http://..." },
    { name: "paul young", avatar: "http://..." }
  ]
};

さてこれでクライアントから data を使う準備ができました。

We can begin using this data in our client straight away.

もちろん graphql-request を使って mutation を送ることもできます。

You can also send mutations with graphql-request:

mutation を送る例
import { request } from "graphql-request";

var url = "http://localhost:4000/graphql";

var mutation = `
mutation populate($count: Int!) {
  addFakeUsers(count:$count) {
    githubLogin
    name
  }
}
`;

var variables = { count: 3 };

request(url, mutation, variables)
  .then(console.log)
  .catch(console.error);

request 関数は API の URL、mutation、それから三番目の引数として変数を受け取ります。この変数は単なる JavaScript のオブジェクトで、field と value を持ち、クエリに必要となる値を持っています。このリクエストを立てることで、addFakeUsers を mutation を発行しています。

The request function takes in the API URL, the mutation, and a third argument for variables. This is just a JavaScript object that passes in a field and value for the query variables. After we invoke request, we issue the addFakeUsers mutation.

graphql-request は UI libraries や frameworks と連携するための仕組みは特に用意していませんが、とても簡潔にそれを成し遂げることができます。ためしにデータを React Component に流し込んでレンダーしてみましょう。

Though graphql-request doesn’t offer any formal integration with UI libraries and frameworks, we can incorporate a library fairly simply. Let’s load some data into a React component using graphql-request, as demonstrated in Example 6-1.

graphql-request と React の連携
import React from "react";
import ReactDOM from "react-dom";
import { request } from "graphql-request";

var url = "http:// localhost: 4000/ graphql";
var query = `
  query listUsers { 
    allUsers { 
      avatar
      name 
    } 
  }
`;

var mutation = `
  mutation populate ($count:Int!) {
    addFakeUsers(count:$count) {
      githubLogin
    } 
  } 
`;

const App = ({ users = [] }) => (
  <div>
    {users.map(user => (
      <div key={user.githubLogin}>
        <img src={user.avatar} alt="" /> {user.name}{" "}
      </div>
    ))}
    <button onClick={addUser}> Add User</button>
  </div>
);

const render = ({ allUsers = [] }) =>
  ReactDOM.render(<App users={allUsers} />, document.getElementById(" root"));

const addUser = () =>
  request(url, mutation, { count: 1 })
    .then(requestAndRender)
    .catch(console.error);

const requestAndRender = () =>
  request(url, query)
    .then(render)
    .catch(console.error);

requestAndRender();

コードの冒頭でまず ReactReactDOM を読み込んでいます。次に App オンポーネントを作ります。App コンポーネントは props として受け取った users を map して div 要素を作っています。そしてその div 要素の中に user の avatar と username を値として持ちます。render 関数は App コンポーネントを #root 要素にレンダーします。その際に property として allusers を渡します。

Our file starts with an import of both React and ReactDOM. We then create an App component. App maps over the users that are passed as props and creates div elements containing their avatar and username. The render function renders the App to the #root element and passes in allUsers as a property.

requestAndRender 関数は graphql-request 由来の request 関数を実行します。これによってクエリが発行され、データを受け取ることができ、そのあとに render 関数を実行しています。この際に data が App コンポーネントへと渡されます。

From there, requestAndRender calls request from graphql-request. This issues the query, receives the data, and then calls render, which provides the data to the App component.

この小さなアプリケーションは mutation も扱っていますね。App コンポーネントにボタンがありますが、このボタンは onClick イベントを受けると、addUser 関数を実行します。この関数が起動すると、mutation を送り、その後 requestAndRender を実行するので、新しく GraphQL API にリクエストをして user を取得し、それを App へとレンダーします。

This little app also handles mutations. In the App component, the button has an onClick event that calls the addUser function. When invoked, this sends the mutation and then calls requestAndRender to issue a new request for the services users and rerenders the with the new list of users.

さあ、GraphQL を使ったクライアントアプリケーションを、立てる方法をいくつかみてきました。シェルスクリプトの cURL を使って書くこともできます。fetch を使ったウェブページを書くこともできます。graphql-request を使うことで少し作業を早くすることもできます。もちろんこれで十分ではありますが、さらに強力な GraphQL クライアントのためのツールがあるのです。ではみていきましょう!

So far, we’ve looked at a few different ways to begin building client apps using GraphQL. You can write shell scripts with cURL. You can build web pages with fetch. You can build apps a little faster with graphql-request. You could stop right there if you wanted to, but there are even more powerful GraphQL clients available. Let’s go for it.