An URQL exchange to compute data using resolvers and entities.
$ npm i urql-computed-exchange
First, create your entities and their resolvers:
// entities.js
import { createEntity, mergeEntities } from 'urql-computed-exchange';
const Pokemon = createEntity('Pokemon', {
numberOfEvolutions: {
dependencies: gql`
fragment _ on Pokemon {
evolutions {
id
}
}
`,
resolver: (pokemon) => {
return (pokemon.evolutions && pokemon.evolutions.length) ?? 0;
},
},
});
export default mergeEntities(Pokemon);
Then, add it to the list of exchanges in URQL when setting up the client:
// client.js
import { computedExchange } from 'urql-computed-exchange';
import {
createClient,
cacheExchange,
dedupExchange,
fetchExchange,
} from 'urql';
import entities from './entities';
const client = createClient({
url: 'https://graphql-pokemon.now.sh/',
exchanges: [
dedupExchange,
cacheExchange,
computedExchange({ entities }),
fetchExchange,
],
});
export default client;
Finally, use the @computed
directive when declaring your GraphQL queries. Don't forget to indicate the corresponding type
:
// App.js
import React from 'react';
import { useQuery } from 'urql';
import gql from 'graphql-tag';
const PokemonQuery = gql`
query PokemonQuery {
pokemon(name: "charmander") {
id
name
numberOfEvolutions @computed(type: Pokemon)
}
}
`;
const App = () => {
const [ res ] = useQuery({
query: PokemonQuery,
});
if (res.fetching) {
return 'Loading...';
}
return (
<pre>
{JSON.stringify(res.data, null, 2)}
</pre>
);
};
export default App;