mercurius-js / mercurius

Implement GraphQL servers and gateways with Fastify
https://mercurius.dev/
MIT License
2.34k stars 234 forks source link

feat: @defer support #898

Open igrlk opened 1 year ago

igrlk commented 1 year ago

Hi everyone ✋ As some of you may have noticed, apollo and graphql-js added support for @defer directive, so it's time to do the same in Mercurius!

🤔 What is @defer and why do we need that?

@defer is a directive that allows you to receive query data incrementally. There is a bunch of information about it but a decent source is Apollo Docs @defer.

⌛ Current state of things

📦 What this PR does

It uses the new GraphQL incremental api (if it's available! otherwise we use old api for backwards-compatibility) to execute queries. The incremental api itself does all the magic for us and returns either the classic response (body.data.myField) or the incremental one with stream (see more in the api type definitions)

Client should send us the following header accept: multipart/mixed; deferSpec=20220824 in order to get a stream response back. Otherwise, the error is thrown that doesn't allow client to get the data.

The PR also moves to a new signature of GraphQLError since the old one is deprecated and its support is removed in graphql@17

Additionally, it bumps the graphql-js to 17.0.0-alpha.2 (latest available right now). Once PR has all the tests passed and feedback incorporated, it's going to be cut off to a separate release branch, instead of getting merged to master directly because of graphql@17 which is still in alpha

🧰 Local development / testing

If you wish to see how it's going to look like in a real app, I've put together an Apollo Client/Server + Mercurius setup that allows you to run a query with @defer against either:

⚠️ Things that aren't yet done

:octocat: Please take into account that all the things I mentioned in the PR are my suggestions based on what I've read and heard. I am open to the ideas you might have, especially because it's my first PR to this repository.

I want to give a huge shoutout to the Mercurius team for their amazing hard work maintaining this project and to Apollo team who were the first in @defer implementation, and whose examples I've used to implement the changes in this repo.

Cheers ✌️

mcollina commented 1 year ago

How could I ship this today and keep the current dependency at graphql@16?

igrlk commented 1 year ago

How could I ship this today and keep the current dependency at graphql@16?

I didn't update any gql-related dependencies in package.json and the whole change is not breaking, since the new functionality only works if graphql@17 is installed.

So I think it's safe to ship this once I incorporate the feedback and CI is green. Appreciate if you can help with the things you mentioned - otherwise I'll do this later today 🙂

igrlk commented 1 year ago

@mcollina I believe you saw my issue in graphql-jit - looking forward to hearing back from them re graphql 17 support. Should we keep this PR open until they give us more details?

mcollina commented 1 year ago

It's likely better to wait until we hear back, I might be wrong but there is no urgency to ship given graphl@17 is still in alpha.

glasser commented 1 year ago

Apollo-Server changes are not yet in main branch, but in the next major version branch

Just to clarify: we have released support for defer/stream in Apollo Server 4 (which is now the current major version), but we are considering it experimental for now for various reasons including that it requires unreleased graphql-js.

Exciting to see Mercurius implementing it as well! Happy to see you're also requiring the client to opt in with deferSpec so that the whole ecosystem can cleanly adjust to any final changes that may show up before the GraphQL spec receives the final version.

igrlk commented 1 year ago

I've rebased this on top of the next branch. We can land as soon as the tests pass

Thanks! I've made more changes that you requested.

I'm going to check if we can get the response from graphql-jit team or I can maybe make the necessary changes in their project, since we're blocked by that.

igrlk commented 1 year ago

I didn't get any response from graphql-jit so decided to make a PR to migrate it to graphql@17 - hopefully someone will respond on it. https://github.com/zalando-incubator/graphql-jit/pull/185

BorisTB commented 1 year ago

Hi! What needs to be done here to merge this? I’d really like to use this feature so I’ll gladly help.

mcollina commented 1 year ago

I think a public release of GraphQL v17?