Search code examples
javascriptreactjsgraphqlrelayjs

How to send one-off query with Relay?


I'm trying to send a one-off query using Relay. So, I don't necessarily want to use QueryRenderer but rather have a simple API to send a query without binding the result to a React component.

Previously, this was possible with the fetch method on network:

const checkVoteQueryText = `
  query CheckVoteQuery($userId: ID!, $linkId: ID!) {
    viewer {
      allVotes(filter: {
        user: { id: $userId },
        link: { id: $linkId }
      }) {
        edges {
          node {
            id
          }
        }
      }
    }
  }`
const checkVoteQuery = { text: checkVoteQueryText }
const result = await this.props.relay.environment._network.fetch(checkVoteQuery, {userId, linkId})

It seems however that fetch has been deprecated in some newer version of Relay. Is there an alternative that can be used now?

If Relay doesn't allow for one-off queries, I'd probably just graphql-request or plain JS fetch to get the job done. But it would be nice to be able to use Relay for this as it already knows my endpoint.


Solution

  • Ah this was actually rather simple to achieve. In fact, calling fetch on this.props.relay.environment._network only reused the function that's passed into the Network when it's created. So, it's possible to just reuse this function, in my case it's called fetchQuery:

    Environment.js

    import {GC_AUTH_TOKEN} from './constants'
    import { SubscriptionClient } from 'subscriptions-transport-ws'
    
    const {
      Environment,
      Network,
      RecordSource,
      Store,
    } = require('relay-runtime')
    
    const store = new Store(new RecordSource())
    
    // Export it here so it can be reused in other files
    export const fetchQuery = (operation, variables) => {
      return fetch('https://api.graph.cool/relay/v1/cj9h5g99s24fb0100nsp81d4y', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${localStorage.getItem(GC_AUTH_TOKEN)}`
        },
        body: JSON.stringify({
          query: operation.text,
          variables,
        }),
      }).then(response => {
        return response.json()
      })
    }
    
    const network = Network.create(fetchQuery)
    
    const environment = new Environment({
      network,
      store,
    })
    
    export default environm
    

    ent