Tommaso De Rossi
Posted on January 25, 2020
I have always used Apollo to make graphql requests inside of react, usually doing something like this
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const GET_GREETING = gql`
query getGreeting($language: String!) {
greeting(language: $language) {
message
}
}
`;
function Hello() {
const { loading, error, data } = useQuery(GET_GREETING, {
variables: { language: 'english' },
});
if (loading) return <p>Loading ...</p>;
return <h1>Hello {data.greeting.message}!</h1>;
}
The problem with this however is that Apollo has become really bloated over time, making its bundle size big and its API unfriendly.
Creating a simple grahpql client is a pain:
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
// Instantiate required constructor fields
const cache = new InMemoryCache();
const link = new HttpLink({
uri: 'http://localhost:4000/',
});
const client = new ApolloClient({
// Provide required constructor fields
cache: cache,
link: link,
// Provide some optional constructor fields
name: 'react-web-client',
version: '1.3',
queryDeduplication: false,
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network',
},
},
});
Also the bundle size is pretty big and the UX is not great.
So i decided to find a better way to call a simple Graphql API.
I found a simpler Graphql client, called grpahql-request
, with mush smaller bundle size and better UX.
import { GraphQLClient } from 'graphql-request'
const graphQLClient = new GraphQLClient('https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr', {
headers: {
authorization: 'Bearer MY_TOKEN',
},
})
const query = /* GraphQL */ `
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
graphQLClient.request(query).then(console.log)
This code is a lot simpler as you can see, the same library works in the server too so you can do sse super easily.
Then i needed a glue code that can let me use the same hooks API that Apollo uses but with any promise, so i release react-extra-hooks
on npm.
This package contains some utility hooks to be used in react, among these there is usePromise
:
import { usePromise } from 'react-extra-hooks'
import React from 'react'
import { GraphQLClient } from 'graphql-request'
const graphQLClient = new GraphQLClient('https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr',)
const query = /* GraphQL */ `
{
Movie(title: "Inception") {
releaseDate
actors {
name
}
}
}
`
const App = () => {
const { result, loading, error } = usePromise(() => graphQLClient.request(query))
if (loading) {
return <>loading</>
}
return <div>{result.Movie.releaseDate}</div>
}
As you can see the usage is similar to Apollo but we are using a general usePromise function instead of useQuery.
The same thing can be done with mutations, using another hook, useLazyPromise
:
import { usePromise } from 'react-extra-hooks'
import React from 'react'
import { GraphQLClient } from 'graphql-request'
const graphQLClient = new GraphQLClient('https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr',)
const query = /* GraphQL */ `
mutation {
createActor(name: "dsf") {
id
}
}
`
const App = () => {
const [execute, {result, loading, error }] = useLazyPromise(() => graphQLClient.request(query))
if (loading) {
return <>loading</>
}
if (result) {
return <div>{result.id}</div>
}
return (
<div>
<button onClick={execute}>execute request</button>
</div>
)
}
In my opinion this is much better than Apollo, the bundle size is smaller and the code is more general.
Posted on January 25, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.