apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.34k stars 2.66k forks source link

Missing field while writing result #12082

Closed mandeerson closed 4 days ago

mandeerson commented 4 days ago

Using the apollo client with nextjs I am receiving the following messages:

Missing field 'size' while writing result

Missing field 'number' while writing result

even though these variables were never returned in the query

Could you help me understand what the problem would be?

"next": "14.2.5" "@apollo/client": "3.11.8"

image image image image image image
jerelmiller commented 4 days ago

Hey @mandeerson 👋

In one of your screenshots, you have an extend type Query with some types there. I see size and number in your Subcategories type there, but its difficult to tell how that extended schema fits into what you're actually querying. Can you provide some more detail?

mandeerson commented 4 days ago

thanks for the quick response.

In my tests, I never returned the size and number variables populated, they are declared but I did not return them from spring boot, removing them from the type in spring boot the error stops, my doubt would be, even and never returning the merge from the cache says that they are missing.

in my case, they are variables that can return null

image
jerelmiller commented 4 days ago

I'm very sorry, I'm not sure I'm following 😅. What is the actual query you're sending to the server?

You'll see that error if the query document contains fields that the returned data does not have. Since both cache-first and network-only fetch policies write data to the cache after the response comes back, you'll see this error in that situation.

You can replicate this warning by doing something like the following:

client.writeQuery({
  query: gql`
    query {
      searchSubcategories {
        totalElements
        totalPages

        # note that size and number are here in the document
        size
        number
      }
    }
  `,
  data: {
    searchSubcategories: {
      __typename: "Subcategories",
      totalElements: 10,
      totalPages: 10,
      // But if we DON'T provide data for `size` or `number` here... 
      // This results in the warning!
    }
  }
})

Does the query/data look something like this? If this is the case, that is your problem.

mandeerson commented 4 days ago

Let me try to explain better.

The Subcategories type has the size and number variables with the int type defined, but in some cases they may not actually return, even if I request them because they are null in the backend.

If they do not return, my frontend code treats a default value for them.

I know that if I set them to Int! would be required to return, but removing the ! should be optional.

The message I see in the console is an error, shouldn't it be a warning or something similar?

I know I'm not returning them

English is not my native language, I am trying my best to explain my doubt. :D

jerelmiller commented 4 days ago

@mandeerson no problem at all! That makes a bit more sense to me. This was the part I wasn't sure about before:

they may not actually return, even if I request them

This is actually against the GraphQL spec. If they are nullable, the keys should exist in the response with the value set to null rather than omitting those keys entirely.

Per 2.4 Selection Sets of the spec (emphasis mine):

An operation selects the set of information it needs, and will receive exactly that information and nothing more, avoiding over-fetching and under-fetching data.

Note that "under-fetching" is mentioned here which is what your server is currently doing by omitting those fields in the response.

Apollo Client like almost all client-side libraries expect that the response from the GraphQL server contains a response with the exact shape as specified in the query document. We provide that warning in the library to help detect this sort of problem, either because the server returns a malformed response, or you're performing cache writes yourself and forgot to include a field's data.


Something I'll note is that if you're using a GraphQL library in your Spring Boot application, you might consider contacting the library maintainers as omitting keys from the response is not GraphQL compliant and can provide a lot of trouble for client-side libraries. If you're hand-rolling it, totally fine, just make sure to include those fields with the value set to null rather than omitting them.

Hope this helps!

jerelmiller commented 4 days ago

The message I see in the console is an error, shouldn't it be a warning or something similar?

Oh and I should mention about this, it is a warning, but we're using console.error instead of console.warning here to provide a bit more attention in your console.

We aren't throwing that error however, so your app will still continue to function.

mandeerson commented 4 days ago

I understand, the backend doesn't actually return them, see the request using Postman.

Even requesting them, it does not return the variables in the response, as expected and the way you explained.

As I mentioned, it was confusing for me to see Error messages in the console.

But if everything is ok, we can consider the doubt as concluded.

I really appreciate your time helping me understand

image
github-actions[bot] commented 4 days ago

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

jerelmiller commented 4 days ago

Ah yep that is definitely why you're seeing that error! If your server can return a response like this instead, the error should go away 🙂

{
  "data": {
    "searchSubcategories": {
      "totalElements": 6,
      "totalPages": 1,
      "size": null,
      "number": null,
      "content": [...]
    }
  }
}

Glad this helped! Have a great rest of your day 🙂

mandeerson commented 4 days ago

Thanks for your help, I reviewed the backend and the null was being removed because of the below property defined in application.yml

have a great day

jackson:
    default-property-inclusion: NON_NULL
jerelmiller commented 4 days ago

Good to know! Hopefully this helps some other users that might experience the same thing. Thanks for sharing that!