HASURA+React Queryで「by pk」でデータ取得しようとして出来なかった時の解決策

HASURA+GraphQL+ReactQueryに入門中。

複数データの取得はできるのに、同じようにid指定して1件だけ取得しようとすると上手く行かなかった。

めっちゃハマって試行錯誤したけど結果的にHASURAとReactQueryに慣れてよかった。
結論からいうとgraphql-requestのリクエストに対する返り値のオブジェクトのKeyが違ってたので、そこを修正したら直りました。

半分はHasuraの知識不足、もう半分はTypescriptにまだまだ弱いことが原因。

エラーになっていたコード

interface UserRes {
  user: User
}
export const fetchUserById = async (id) => {
  const { User: data } = await request<UserRes>(
    process.env.NEXT_PUBLIC_HASURA_ENDPOINT,
    GET_USERBY_ID_PK,
    { id: id }
  )
  return data
}
export const useQueryUsers = (user_id) => {
  return useQuery<User, Error>({
    queryKey: ['user', user_id],
    queryFn: () => fetchUserById(user_id),
    staleTime: Infinity,
  })
}

hooksの中に書いた、GraphQLを直接叩く部分。
クエリが GET_USERBY_ID_PK で、idを指定してひとつ1件だけデータを取得しようとしてます。

修正後のコード

interface UserRes {
  users_by_pk: User
}
export const fetchUserById = async (id) => {
  const { users_by_pk: data } = await request<UserRes>(
    process.env.NEXT_PUBLIC_HASURA_ENDPOINT,
    GET_USERBY_ID_PK,
    { id: id }
  )
  return data
}
export const useQueryUsers = (user_id) => {
  return useQuery<User, Error>({
    queryKey: ['user', user_id],
    queryFn: () => fetchUserById(user_id),
    staleTime: Infinity,
  })
}

interface UserResの中のオブジェクト名を「user」から「users_by_pk」に変えて、requestの返り値も同様に修正したら、ちゃんとfetchできました。

というかfetch自体はHASURAのログを見るとちゃんと出来ていたのですが、フロントエンドで受け取る側の型が違っていたため、返り値がundefinedになってしまっていた模様。

このへんもTS側でエラー検知してくれると良いなと思いましたが難しいんですかね。

他に試したこと

以下、直接エラー解消に結びつかなかったけどやったこと / 学んだこと / 調べたこと。

****_by_pk するときの変数$idの型は「uuid!」

String!とかだとby_pkで取得できないみたいです。

headerで「x-hasura-admin-secret」がチェックされていてpermissionでanonymousの権限をしていしていないとfieldがありませんとなる

あたりまえ。

Typescriptもがっつりやり込みたい

いままで騙し騙しでやってきて知らない人に説明できるレベルとかではないので、TSも自然に読み書きできるレベルまでやっていきたいなと思いました。
今回の件もTSに慣れてたらもっと早く解決した気がする。

今回はここまで。
ではまた!