0

I'm using Apollo to call a rest endpoint that takes variables from query string:

/api/GetUserContainers?showActive=true&showSold=true

I'm having trouble figuring out how to pass variables to the query, so it can then call the correct url. From looking at apollo-link-rest docs and a few issues I think I'm supposed to use pathBuilder but this is not documented and I haven't been able to get it working.

So far I've defined my query like this:

getUserContainersQuery: gql`
  query RESTgetUserContainers($showActive: Boolean, $showSold: Boolean, $pathBuilder: any) {
    containerHistory @rest(type: "ContainerHistoryResponse", pathBuilder: $pathBuilder) {
      active @type(name: "UserContainer") {
        ...ContainerFragment
      }
      sold @type(name: "UserContainer") {
        ...ContainerFragment
      }
    }
  }
  ${ContainerFragment}
`

and calling it in my component like this, which does not work:

import queryString from 'query-string'

// ...

const { data } = useQuery(getUserContainersQuery, {
  variables: {
    showActive: true,
    showSold: false,
    pathBuilder: () => `/api/GetUserContainers?${queryString.stringify(params)}`,
  },
  fetchPolicy: 'cache-and-network',
})

The only way I got this to work was by passing the fully constructed path to the query from the component:

// query definition

getUserContainersQuery: gql`
  query RESTgetUserContainers($pathString: String) {
    containerHistory @rest(type: "ContainerHistoryResponse", path: $pathString) { // <-- pass path here, instead of pathBuilder
      // same response as above
    }
  }
`

// component

const params = {
  showActive: true,
  showSold: false,
}

const { data } = useQuery(getUserContainersQuery, {
  variables: {
    pathString: `/api/GetUserContainers?${queryString.stringify(params)}`,
  },
  fetchPolicy: 'cache-and-network',
})

These seems to me like a really hacky solution which I'd like to avoid.

What is the recommended way to handle this query string problem?

samzmann
  • 2,286
  • 3
  • 20
  • 47

1 Answers1

1

You shouldn't need to use the pathBuilder for simple query string params. You can pass your params directly as variables to useQuery then pass then directly into teh path using the {args.somearg} syntax. The issue I see is you've not defined the variables your using for you query containerHistory bu only in the query alias RESTgetUserQueries. If updated is should look like this:


// query definition

getUserContainersQuery: gql`
  query RESTgetUserContainers($showActive: Boolean, $showSold: Boolean) {
    // pass the variables to the query
    containerHistory(showActive:$showActive, showSold:$showSold) @rest(type: "ContainerHistoryResponse", path:"/api/GetUserContainers?showActive={args.showActive}&showSold={args.showTrue}") { 

     //.. some expected reponse

    }
  }
`

// component

const params = {
  showActive: true,
  showSold: false,
}

const { data } = useQuery(getUserContainersQuery, {
  variables: {
    showActive, 
    showSold
  },
  fetchPolicy: 'cache-and-network',
})
Rennzie
  • 172
  • 2
  • 9
  • Thanks for the answer, this solved my problem. Do you know where this might be documented? – samzmann Nov 19 '20 at 11:08
  • It’s cryptically documented here: https://www.apollographql.com/docs/link/links/rest/ under the @rest directive full options section. Admittedly it’s not 100% clear even from their example that it works this way! – Rennzie Nov 21 '20 at 09:22
  • @Rennzie what if we have a condition where if a query params is undefined it should not be sent. Any idea how can we achieve that?? – Gardezi Oct 06 '22 at 08:52