<

Trying Data Transformation with urql

When using a GraphQL client, don't you want to transform the data after fetching it? I do. I found that exchanges in the GraphQL client urql can be used for data transformation, so I will share that.

The sample code is placed in the following repository.

https://github.com/silverbirder/urql-exchange-transform

Exchanges

Exchanges, quoting from the official page.

The Client itself doesn't actually know what to do with operations. Instead, it sends them through "exchanges". Exchanges are akin to middleware in Redux and have access to all operations and all results. Multiple exchanges are chained to process our operations and to execute logic on them, one of them being the fetchExchange, which as the name implies sends our requests to our API.

In a nutshell, it's a mechanism that can access the GraphQL communication flow (request/response). Because it can access the response, you can also transform the data. Exchanges take on the task of data transformation, so you don't have to write the transformation code over and over again on the query issuing side, such as useQuery.

Transform exchange

Before introducing the sample code, I will use Pokemon as a data source for GraphQL. The URL and query to use are as follows.

  • url
    • https://trygql.formidable.dev/graphql/basic-pokedex
query Pokemons {
  pokemons {
    id
    name
  }
}

The data transformation is written in the following code. The part of the map is the actual data transformation. This time, I'm toLowerCase the name.

export const transformExchange = ({ forward }) => {
  return (ops$) =>
    pipe(
      ops$,
      forward,
      // Sample transform code
      map((result) => {
        const { data } = result;
        if (!data || !data.pokemons) {
          return result;
        }
        const { pokemons } = data;
        result.data.pokemons = pokemons.map((pokemon) => {
          pokemon["name"] = pokemon.name.toLowerCase();
          return pokemon;
        });
        return result;
      })
    );
};

Pass the transformExchange function to the urql client.

import { createClient, fetchExchange } from "urql";
import { transformExchange } from "./transformExchange";

client = createClient({
  url: "https://trygql.formidable.dev/graphql/basic-pokedex",
  exchanges: [transformExchange, fetchExchange],
});

If you don't specify any exchanges, defaultExchanges will be used. This time, for the minimum necessary explanation, I only used fetchExchange from defaultExchanges.

After that, you just need to fetch the data with useQuery as in the following code. The data after fetching is the result of data transformation.

import { useQuery } from "urql";

const PokemonsQuery = `
  query Pokemons {
    pokemons {
      id
      name
    }
  }
`;

export const Pokemons = () => {
  const [result] = useQuery({
    query: PokemonsQuery,
  });

  const { data, fetching, error } = result;

  if (fetching) return <p>Loading...</p>;
  if (error) return <p>Oh no... {error.message}</p>;

  return (
    <ul>
      {data.pokemons.map((pokemon) => (
        <li key={pokemon.id}>{pokemon.name}</li>
      ))}
    </ul>
  );
};

pokemon.name has been toLowerCase.

In conclusion

urql's exchanges depend on a library called wonka written in the Reason language, so it was a bit of a struggle to investigate.

Sure, please paste the Markdown content you want to translate. I'll do my best to provide an accurate translation while adhering to your guidelines.

If it was helpful, support me with a ☕!

Share

Related tags