Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A better apollo integration #27

Open
Sytten opened this issue Nov 11, 2020 · 5 comments
Open

A better apollo integration #27

Sytten opened this issue Nov 11, 2020 · 5 comments

Comments

@Sytten
Copy link
Member

Sytten commented Nov 11, 2020

Now I am not sure where to post that since there doesn't seem to be big community around the project, but I wrote a better integration for apollo:

import { ApolloServerPlugin } from 'apollo-server-plugin-base'
import { RewriteHandler, Rewriter } from 'graphql-query-rewriter'

import { Context } from '~/context'

// An optimization that could be done is avoiding a query parsing
// and reprinting in the input. Not sure how to do this.
export const GraphQLQueryRewriter = (
  rewriters: Rewriter[]
): ApolloServerPlugin<Context> => ({
  requestDidStart(reqCtx) {
    const { request } = reqCtx

    const handler = new RewriteHandler(rewriters)
    const rewrittenRequest = handler.rewriteRequest(request.query!, request.variables)
    request.query = rewrittenRequest.query
    request.variables = rewrittenRequest.variables

    return {
      willSendResponse: resCtx => {
        const { response } = resCtx

        const newData = handler.rewriteResponse(response.data)
        response.data = newData
      },
    }
  },
})
@chanind
Copy link
Collaborator

chanind commented Nov 11, 2020

This is a lot cleaner than the current implementation, thank you for doing this! I didn't realize Apollo directly allows rewriting responses like this so easily. Pending resolution of #28, I'll get a repo set up either in this org or in a new org and work on getting this merged!

@Sytten
Copy link
Member Author

Sytten commented Nov 11, 2020

I faced an issue with the response, it duplicates the response payload for some reason for arrays. DO NOT USE until I fix it.

@Sytten
Copy link
Member Author

Sytten commented Nov 12, 2020

Fixed in #29

@igrayson
Copy link

igrayson commented Jan 28, 2021

This implementation has worked well for us, notably overcoming graphql-query-rewriter/express-graphql-query-rewriter#6

However, it has one important bug: it throws an error within willSendResponse, when the response has no data (such as when the response only has application errors).

Fixed by adding a one-line check:

import { ApolloServerPlugin } from 'apollo-server-plugin-base'
import { RewriteHandler, Rewriter } from 'graphql-query-rewriter'

import { Context } from '~/context'

// An optimization that could be done is avoiding a query parsing
// and reprinting in the input. Not sure how to do this.
export const GraphQLQueryRewriter = (
  rewriters: Rewriter[]
): ApolloServerPlugin<Context> => ({
  requestDidStart(reqCtx) {
    const { request } = reqCtx

    const handler = new RewriteHandler(rewriters)
    const rewrittenRequest = handler.rewriteRequest(request.query!, request.variables)
    request.query = rewrittenRequest.query
    request.variables = rewrittenRequest.variables

    return {
      willSendResponse: resCtx => {
        const { response } = resCtx
        if (!response.data) return

        const newData = handler.rewriteResponse(response.data)
        response.data = newData
      },
    }
  },
})

An alternative fix would be to update RewriteHandler.rewriteResponse() to passthrough falsey response objects without inspecting them.

@Sytten
Copy link
Member Author

Sytten commented Jan 28, 2021

Thanks for that, I will create an official package when I have time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants