Closed4

Graphql導入のために、urqlを使ってみる

tawachantawachan

Graphqlを使ってみている。フロントからアクセスするためのクライアントは、

  • apollo
  • relay
  • urql

などがあり、いまいちどれがいいのかわからない。

とりあえず、urqlを試していっているメモ。

https://github.com/urql-graphql/urql

tawachantawachan

graphql-codegenで生成する

https://the-guild.dev/graphql/codegen

configはこんな感じにしている

// codegen.ts
import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
  overwrite: true,
  schema: "http://localhost:3000/query",
  documents: "./graphql/graphql/*.graphql",
  generates: {
    "./graphql/generated.ts": {
      plugins: ["typescript", "typescript-operations", "typescript-urql"],
      config: {
        fetcher: "fetch",
        isReactHook: true,
        exposeQueryKeys: true,
        scalars: {
          DateTime: "string", // ← Datetimeをanyでなくする設定
        },
      },
    },
    "./graphql/graphql.schema.json": {
      plugins: ["introspection"],
    },
  },
};

export default config;

Datetimeがanyになる問題は、次を参考に修正

https://qiita.com/takano-h/items/cf17ec515b9d850b4923

tawachantawachan

clientはhooksにして雑に作るようにしてみた

import { useMemo } from "react";
import { Client, cacheExchange, fetchExchange } from "urql";

const GRAPHQL_URL =
  process.env.NEXT_PUBLIC_GRAPHQL_URL || "http://localhost:3000/query";

const createUrqlClient = (token?: string) =>
  new Client({
    url: GRAPHQL_URL,
    exchanges: [cacheExchange, fetchExchange],
    fetchOptions: () => {
      return {
        headers: { authorization: token ? `Bearer ${token}` : "" },
      };
    },
  });

export const useUrqlClient = (token?: string) => {
  const client = useMemo(() => createUrqlClient(token), [token]);
  return client;
};

認証機構まだ作っていないのでよくわからないけどtokenが変わればclientが洗い変わる想定

exchangesがいまいちよくわかっていない

あとは適当にProviderに渡す

// _app.tsx
import { ChakraProvider } from "@chakra-ui/react";
import type { AppProps } from "next/app";
import { Provider as UrqlProvider } from "urql";
import { useUrqlClient } from "~/lib/graphql/urql";

import { theme } from "~/lib/theme";
export default function App({ Component, pageProps }: AppProps) {
  const ComponentElement = Component as any;
  const urqlClient = useUrqlClient();
  return (
    <ChakraProvider theme={theme}>
      <UrqlProvider value={urqlClient}>
        <ComponentElement {...pageProps} />
      </UrqlProvider>
    </ChakraProvider>
  );
}
tawachantawachan

使うときはこんな感じ

export const TopContainer: FC = () => {
  const [{ data: authorsData }] = useListAuthorsQuery();
  const [{ data, fetching }, createAuthor] = useCreateAuthorMutation();

  const onClick = async () => {
    await createAuthor({ firstName: "aaaa", lastName: "test" });
  };
...省略

hooksとして生成されると、データ変換どこでやればいいんだろう

graphqlのtypeをそのまま使わず、フロント用のentityを保持したほうが良さそうだけど、変換機構どこに入れるのが適切なんだろうか

hooksをいちいちラップするのか?

このスクラップは2023/10/20にクローズされました