以前の記事でGraphQLとPrismaを使用してAPIを作成してきたのと同じくらい、クライアント側のアプリにカスタムバックエンドを実際に適用したことはありません。 この記事では、 Apollo Boost を使用して、クエリやミューテーションを通じてユーザーがバックエンドを操作できるようにする方法を学習します。これは、Apolloクライアントを使用するためのすべてをすぐに利用できるパッケージです。

インストール

もっと一般的なアプローチを取り、ReactやVueのような他のライブラリなしでApolloを使用しようと思います。 したがって、 parcel bundler を含むHTMLおよびJavaScriptファイルが必要になるだけで、webpackをいじくり回すことなく最新のJavaScript機能を使用できるようになります。 babel-polyfillをスローすると、 async /awaitにアクセスできるようになります。

$ npm install parcel-bundler apollo-boost graphql babel-polyfill

バックエンドのセットアップ

バックエンドに集中しすぎないように、このスターターをいくつかのリゾルバーで作成しました。 Postgresデータベースのセットアップが必要です。これはここでを読み、envファイルにクレデンシャルを追加できます。

これを実行して、別のターミナルでプロジェクトを開始することを忘れないでください。

$ cd prisma
$ docker-compose up -d 
$ prisma deploy 
$ cd ../
$ yarn get-schema 
$ yarn start

または、カスタムバックエンドをいじりたくない場合は、 GraphCMS をチェックして、試してみる投稿モデルを作成することをお勧めします。

クエリ

バックエンドへの接続はこれ以上簡単なことではありません。URIをApolloBoostに投げ込むだけで、すべてが夢中になります。 これまでにGatsbyを使用したことがある場合は、gqlタグ関数に精通している必要があります。 gqlといくつかのバックティックを使用すると、GraphQLPlaygroundの場合とまったく同じようにリクエストを構造化できます。

これで、サーバーのqueryメソッドがリクエストを受け取り、promiseを返します。 すべてをdivにプッシュすると、レンダリングが実行されます。 これはまだすべてフロントエンドコードであるため、DOM要素に直接アクセスすることに注意してください。

index.js
import "babel-polyfill";
import ApolloBoost, { gql } from 'apollo-boost';

const server = new ApolloBoost({
  uri: 'http://localhost:4000/' // Or to you GraphCMS API
});

const query = gql`
  query {    
    posts {
      title 
      body
    }
  }
`;

const render = posts => {
  let html = '';

  posts.data.posts.forEach(post => {
    html += `
      <div>
      <h3>${post.title}</h3>
      <p>${post.body}</p>
      </div>
    `;
  });
  document.querySelector('#posts').innerHTML = html;
};

const getPosts = async query => {
  const server = new ApolloBoost({ uri: 'http://localhost:4000/' });

  const posts = await server.query({ query });
  render(posts);
};

getPosts(query);
index.html
<body>
  <div id="posts"></div>
</body>

突然変異

ミューテーションは想像するのと同じくらい簡単です。通常どおりにミューテーションを作成し、サーバーのmutateメソッドに渡します。 これはすべてクライアント側であるため、標準サーバーを設定しなくても、フォームを使用してデータを送信することもできます。

index.html
<body>
  <form id="form">
    <input type="text" name="title" placeholder="Title" />
    <input type="text" name="body" placeholder="Body" >
    <div class="controls">
      <button type="submit" id="submit">Submit</button>
      <button type="button" id="clearPosts">Clear All</button>
    </div>
    </form>

  <div id="posts"></div>
</body>
index.js
const addPost = async data => {
  const mutation = gql`
    mutation {
      addPost(data: {
        title: "${data.title}",
        body: "${data.body}"
      }) {
        title
      }
    }
  `;

  await server.mutate({ mutation });
  getPosts(query);
};

const submit = document.querySelector('#submit');
const form = document.querySelector('#form');

submit.addEventListener('click', e => {
  e.preventDefault()

  addPost({
    title: form.elements.title.value,
    body: form.elements.body.value
  })

  form.reset()
});
const clearAll = async () => {
  const mutation = gql`
  mutation {
    clearPosts {
      count
    }
  }`;

  const count = await server.mutate({ mutation });
  console.log(`${count.data.clearPosts.count} item removed`);
  getPosts(query);
};

const clearBtn = document.querySelector('#clearPosts');
clearBtn.addEventListener('click', () => clearAll());

まとめ

残念ながら、Apollo Boostはサブスクリプションではあまり役に立ちません。これは、非常に複雑なプロセスであることがわかります。 しかし、全体として、Apolloクライアントはfetchリクエストをいじり回しているように見えます🔥。