apollographql / apollo-link-rest

Use existing REST endpoints with GraphQL
MIT License
789 stars 122 forks source link

Cannot query both GraphQL and Rest endpoints with variables at same time #280

Open basicdays opened 3 years ago

basicdays commented 3 years ago

Hello all 👋

Currently trying out a hybrid approach against Github's APIs using both their GraphQL and Rest APIs. Attempted to put together a test query to see if I can get this thing working before I start adopting it and ran into an issue in regards to querying both their graphql and rest queries at once. I'm just currently executing this via a Node script.

The following query will result in the error ApolloError: Variable $repositoryPage is declared by Viewer but not used:

const FULL_VIEWER_QUERY = gql`
    query Viewer(
        $repositoryLimit: Int = 10
        $repositoryCursor: String = null
        $repositoryPage: Int = 1
    ) {
        viewer {
            id
            name
            repositories(first: $repositoryLimit, after: $repositoryCursor) {
                edges {
                    node {
                        id
                        name
                    }
                }
                pageInfo {
                    endCursor
                    hasNextPage
                }
            }
        }
        restViewer @rest(type: "RestUser", path: "user") {
            id
            name
            reposUrl @export(as: "reposUrl")
            repos(per_page: $repositoryLimit, page: $repositoryPage)
                @rest(
                    type: "[RestRepository]"
                    path: "{exportVariables.reposUrl}?{args}"
                    endpoint: "nested"
                ) {
                id
                name
            }
        }
    }
`;

If I instead query viewer and restViewer fields in separate GraphQL queries, then this error does not occur. I would expect that the act of including a top level GraphQL field would not cause variables only used within rest fields to error out.

For reference, here is the client configuration:

"use strict";
const {
    ApolloClient,
    InMemoryCache,
    createHttpLink,
    from,
} = require("@apollo/client/core");
const { RestLink } = require("apollo-link-rest");
const { default: fetch, Headers } = require("cross-fetch");

global.Headers = Headers;

/**
 * @param {string} ghToken
 */
function getGithubClient(ghToken) {
    return new ApolloClient({
        name: "github",
        link: from([
            new RestLink({
                endpoints: {
                    nested: " ",
                },
                uri: "https://api.github.com/",
                headers: {
                    "User-Agent": "hybrid-test",
                    Accept: "application/vnd.github.v3.raw+json",
                    Authorization: `Token ${ghToken}`,
                },
                customFetch: fetch,
            }),
            createHttpLink({
                uri: "https://api.github.com/graphql",
                headers: {
                    Authorization: `Bearer ${ghToken}`,
                },
                fetch: fetch,
            }),
        ]),
        cache: new InMemoryCache(),
    });
}
exports = module.exports = getGithubClient;

For the sake of easily replicating this, I've added a repository that reproduces this: https://github.com/basicdays/ghtest

Notes:

fbartho commented 3 years ago

This is a high value bug that I've seen symptoms of over the years.

My team hasn't been using a hybrid environment yet -- only apollo-link-state and apollo-link-rest so far -- but we're hoping to get to it in January.

Do you think you might be interested in helping fix this issue? Hybrid queries are definitely intended to be supported.

basicdays commented 3 years ago

I can see if I can look into this one a bit. I get the feeling this specific one may be a bit complex under the hood. Will likely have a series of questions about it when I get into it, ha.

vaibhavcpgeek commented 3 years ago

We have both graphQl and REST endpoint in our project and I am able to use achieve this using apollo-link-rest library. Basically you need to route your requests based on some context and can split them in httplink depending on that context.

vaibhavcpgeek commented 3 years ago

This is a high value bug that I've seen symptoms of over the years.

My team hasn't been using a hybrid environment yet -- only apollo-link-state and apollo-link-rest so far -- but we're hoping to get to it in January.

Do you think you might be interested in helping fix this issue? Hybrid queries are definitely intended to be supported.

We have both graphQl and REST endpoint in our project and I am able to use achieve this using apollo-link-rest library. Basically you need to route your requests based on some context and can split them in httplink depending on that context. Not sure your use case is same or different.

fbartho commented 2 years ago

While this does have a workaround (mentioned by @vaibhavcpgeek), I am interested in seeing improvements to the library around this. I do agree it's likely to be a bit complex however!