1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

こぼのフロントエンドレビュー帳Advent Calendar 2022

Day 16

【フロントエンド】GraphQLを導入する時はFragmentを理解しよう

Posted at

はじめに

GraphQLを用いたフロントエンド開発は多くなってきているように思います。
フロントエンドから柔軟にデータを取ってくることができるということは、今までバックエンドが担保してきていた部分をフロントエンドが担わないといけなくなった

ということを意味します。
保守性をちゃんと考えないといけない。

ということですね。

今回は、Fragmentについての話

Fragmentとは?

GraphQLにおけるFragmentとは複雑なクエリを小さくまとめ上げるために生み出されました。

これはとてもComponentの概念に似ていますね。
僕たちはComponentという小さな単位に分割し、それを組み合わせることで複雑なアプリケーションを構築しています。

これと同じです。
データをFragmentという小さな単位に分割し、複雑なクエリを役割ごとに分割してやろう
という話です。

どうやって実現する?

親コンポーネントで子コンポーネントを呼び出すのと同じように、親のクエリで子のfragmentを呼び出します。

fragment.ts
fragment UserFragment on User {
  name
  age
  profile_picture(scale: 2) {
    uri
  }
}
query.ts
query UserQuery($id: ID!) {
  user(id: $id) {
    id
    name
    ...UserFragment
  }
}

こんな感じにUserFragmentという共通化を行います。

ただ、このように共通化をおこなっていくと、問題が発生してきます。
みなさんも知っているように、共通化というのは保守性を上げる時もあれば、下げる時もあります。

下手に共通化をおこなっていくと、「オーバーフェッチ」を招いてしまうんです。

Fragmentによるオーバーフェッチとは

Fragmentを使うことでクエリの一部を共通化することができます。

ここで発生してしまうのはFragmentの乱用です。
ユーザーの情報を全て取得してくるUserDetailFragmentをユーザー一覧のページでも利用してしまう。

こういうことが発生してしまいます。

今回はオーバーフェッチについて取り上げましたが、TypeScriptを用いていない場合、型エラーが発生せず、アンダーフェッチ(必要な値が足りない)みたいなことも発生しうるかと思います。

そこで生まれたのがFragment Colocationという概念です。

Fragment Colocationとは?

Colocationというのは一緒の場所において管理する。
みたいな意味合いを持っています。

何と一緒において管理するのかというと、コンポーネントです。

データを欲するコンポーネントに、そのコンポーネントが欲しいだけのデータを一緒にFragmentとして書きましょう。

と言う話です。

UserDetail.tsx
import type {UserComponent_user$key} from 'UserComponent_user.graphql';

const React = require('React');

const {graphql, useFragment} = require('react-relay');

type Props = {
  user: UserComponent_user$key,
};

function UserDetail(props: Props) {
  const data = useFragment(
    graphql`
      fragment UserComponent_user on User {
        name
        profile_picture(scale: 2) {
          uri
        }
      }
    `,
    props.user,
  );

  return (
    <>
      <h1>{data.name}</h1>
      <div>
        <img src={data.profile_picture?.uri} />
      </div>
    </>
  );
}

module.exports = UserComponent;

このように、コンポーネントと一対一でFragmentを定義することで、下手に共通化されることを防ごうという概念です。

Fragment Colocationと呼ばれることが多いですが、GraphQLの公式ガイドにもRelayの公式ガイドにもColocationという言葉は載っていない気がします。
正確な呼び名はあまりないのかもしれません。

まとめ

最後までご覧いただきありがとうございました。
今回はGraphQLを導入する上で必要になってくるFragmentという知識について書かせていただきました。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?