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

urql not parsing response if payload is present in the first element (apollo federation) #3763

Open
3 tasks done
SkArchon opened this issue Mar 12, 2025 · 3 comments
Open
3 tasks done

Comments

@SkArchon
Copy link

SkArchon commented Mar 12, 2025

Describe the bug

While testing our backend with urql, we noticed that the urql code seemed to work only if the first element did not contain payload. (see attached screenshot). This is related to subscriptions when using multipart.

Image

It seems that after result is not null, payload can be used as the root element

Image

Related To: #3499

Reproduction client

const { Client, cacheExchange, fetchExchange } = require('@urql/core');

const client = new Client({
  url: 'http://localhost:3002/graphql',
  exchanges: [
    cacheExchange, fetchExchange
  ],
  fetchSubscriptions: true,
  fetchOptions: () => {
    return {
      headers: {
        accept: 'multipart/mixed;boundary="graphql"'
      },
    };
  },
});

async function query() {
  const QUERY = `
     subscription Test {
    countEmp2(max: 5, intervalMilliseconds: 1000)
  }
  `;
  const { unsubscribe } = client.subscription(QUERY).subscribe(result => {
    result.data
    console.log(result.data); // { data: ... }
  });
}

query();

Reproduction

Reproduction Is In Description, don't have a backend available to share atm

Urql version

@urql/core, 5.1.1

Validations

  • I can confirm that this is a bug report, and not a feature request, RFC, question, or discussion, for which GitHub Discussions should be used
  • Read the docs.
  • Follow our Code of Conduct
@SkArchon SkArchon changed the title urql not parsing payload if payload is present in the first element urql not parsing response if payload is present in the first element (apollo federation) Mar 12, 2025
@JoviDeCroock
Copy link
Collaborator

JoviDeCroock commented Mar 12, 2025

payload as a property on response is not valid when it comes to the GraphQL specification https://spec.graphql.org/October2021/#sec-Response-Format - it's likely that you're reaching out to a sub-graph without a supergraph in between which could lead to this discrepancy. After reading your code, you seem to allude only to subscriptions, which support for was added in #3499 feel free to make a reproduction test of the failing case as a PR. This issue does not contain a reproduction so...

@SkArchon
Copy link
Author

SkArchon commented Mar 14, 2025

Hey yes, apologies. I forgot to explicitly mention it is related to when using subscriptions with multipart. I will try and get a reproduction out sometime next week.

It is just that the first response fails when it is wrapped with "payload" for multipart, however after the first response urql can handle the response when it is wrapped with "payload".

@kitten
Copy link
Member

kitten commented Mar 15, 2025

You can probably reproduce this in our unit tests, if that's more convenient: https://github.com/urql-graphql/urql/blob/e850c988aaa0dc4e0707dbb589c4bf65bc0b473f/packages/core/src/utils/result.test.ts

This doesn't have much to do with the multipart transport protocol, but instead with the "Incremental Delivery" spec that defines how incremental (defer/stream) results are formatted and delivered to clients.

None of the spec, as it's currently been submitted, requires the payload wrapper, and I think, if I recall correctly, that must either be an old version of the spec, or a transport wrapping payload that's not specified.
The whole situation is confusing and frustrating as there's multiple versions of the Incremental Delivery proposal spec, it's been changed without a history, implemented without versions/references to specs, there's no exact spec docs for some versions, etc etc.

I suspect that Apollo has basically stuck to one version on the server (which likely differs, for example, what GraphQL Yoga stuck to).

You can specifically see that the payload property is often Federation specific: #3499
There's a lot of references to (result.payload || result).data for example. It's possible changes have been made that we're not aware of or that there's a specific condition that the result transformation doesn't account for.

But if this can't be traced back to the Apollo Federation spec-addition, then it'd be best to capture what the result format is from your actual server, compare that to the tests, track the changes, and document the failure/difference

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