1
1

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.

ApolloClientのベストプラクティスがあったので自分でまとめてみた

Posted at

全てのオペレーションに名前をつける

  • 利点
    • 意図したオペレーションをフロントとバックエンドで共有ができる
    • 予期せぬエラーの回避
    • デバックでフロントとバックエンドのどちらに原因があるかを特定するのに役だつ
# 推奨 ✅
query GetBooks {
  books {
    title
  }
}

# 非推奨 ❌
query {
  books {
    title
  }
}

変数を利用して引数を提供する

  • 実行するuseQueryからvariavlesオプションを利用することで変数を提供することが可能
// 推奨 ✅
query GetDog($dogId: ID!) {
  dog(id: $dogId) {
    name
    breed
  }
}

// 非推奨 ❌
query GetDog {
  dog(id: "5") {
    name
    breed
  }
}

function Dog({ id }) {
  const { loading, error, data } = useQuery(GET_DOG, {
    variables: {
      dogId: id
    },
  });
  // ...render component...
}

注意

ハードコードされた引数が引き起こすデメリット(変数に比べて他の欠点)
・キャッシュの効果を下げる
・プライバシーが表示されるためセキュリティの低下につながる

ハードコーディングとは?
分けておいた方が良い処理や値をコードに直書きしてしまうこと

必要な場所で、必要なデータのみ取得する

REST APIを上回るメリットがここであるからこそ、無駄にデータを取得するクエリ(フィールド)を書かずに正確にクエリを書きましょう。

# Not recommended ❌
query GetGlobalStatus {
  stores {
    id
    name
    address {
      street
      city
    }
    employees {
      id
    }
    manager {
      id
    }
  }
  products {
    id
    name
    price {
      amount
      currency
    }
  }
  employees {
    id
    role
    name {
      firstName
      lastName
    }
    store {
      id
    }
  }
  offers {
    id
    products {
      id
    }
    discount {
      discountType
      amount
    }
  }
}

フラグメントで再利用性のあるフィールドを作成

再利用性はカプセル化ともいう

良い例

viewerとuserのフィールドが同じクエリ

query QueryTwoUsers {
# viewerとuserのフィールドが同じ
  viewer {
    login       # ログインID
    name        # ユーザー名
    url         # ユーザーの GitHub ホームページ
  }

  user(login: "ログイン中のusrID") {
    login
    name
    url
  }
}

そこでフラグメントを利用する

query QueryTwoUsers {
  viewer {
  # 「...」は反復可能オブジェクトであるuserFragmentを展開
    ...userFragment
  }

  user(login: "ログインID") {
  # 「...」は反復可能オブジェクトであるuserFragmentを展開
    ...userFragment
  }
}
#フラグメントを定義
fragment userFragment on User {
  login      
  name       
  url      
}
# フラグメントが長くなったらこのように1列にもできるみたい
fragment userFragment on User {
  login name url
}

注意

可読性を下げてしまう可能性がある

  • フラグメントを使いすぎる
query GetAttendees($eventId: ID!) {
  attendees(id: $eventId) {
    id
    rsvp
    ...NameParts
    profile {
      ...VisibilitySettings
      events {
        ...EventSummary
      }
      avatar {
        ...ImageDetails
      }
    }
  }
}
  • 非ロジカルなフラグメント
# 推奨 ✅
fragment NameParts on Person {
  title
  firstName
  middleName
  lastName
}

# 非推奨 ❌
fragment SharedFields on Country {
  population
  neighboringCountries {
    capital
    rivers {
      name
    }
  }
}

グローバルデータとローカルデータを混合させない

よくない例

query GetAllElements {
  # グローバルで活用するデータ
  elements {
    atomicNumber
    name
    symbol
  }
  # ローカルで活用するデータ
 myDocuments {
    id
    title
    url
    updatedAt
  }
}

よい例

query GetAllElements {
  elements {
    atomicNumber
    name
    symbol
  }
}
query GetMyDocuments {
  myDocuments {
    id
    title
    url
    updatedAt
  }
}

参考

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?