Giter Club home page Giter Club logo

Comments (7)

jerelmiller avatar jerelmiller commented on August 27, 2024 1

Thanks for the reproduction @jer-k! I'm hoping to take a look at this soon.

I'll play around with the reproduction to see if I can get @defer working. If not, I'm sure we have a graph around somewhere that has defer support that I can swap in 😄.

from apollo-client.

jer-k avatar jer-k commented on August 27, 2024 1

Hi @jerelmiller I got a reproduction of this issue completed in https://github.com/jer-k/graphql-rsc-dashboard. However that project and the reproduction relies on apollo-server-integrations/apollo-server-integration-next#203 which hasn't been reviewed yet.

I've been really enjoying building my little demo project and figuring out how to get this all running. I would like to make an attempt to figure out what is going on in this issue, however I'm having trouble figuring out how to get Apollo Client running locally. I found https://github.com/apollographql/apollo-client/blob/main/CONTRIBUTING.md#wiring-a-checkout-into-an-application but it appears these instructions are out of date. Is there any information anywhere on how to get Apollo Client running locally? Thank you

from apollo-client.

jerelmiller avatar jerelmiller commented on August 27, 2024

Oh man it does look like we haven't looked at that for quite some time. I'll add an action item for us to review that and discuss at our next team meeting.

In the mean time, if you want to run it outside of our testing suite, I'd recommend using yalc which I found to be super useful checking against an existing app without some of the weirdness I've seen with npm link. I've run this with our spotify showcase to try out new things on a bigger app, but you may have an app you prefer to use. If you need something more out-of-the-box, you might also consider our error template as a starting point, though that one is pretty basic and might not be best if you need something more complex.

Let me know if yalc works for you in the mean time though!

from apollo-client.

jer-k avatar jer-k commented on August 27, 2024

Thank you, got it all set up with some help from others in the discord.

Going to add some comments here as I debug things just so I can keep track of what I'm finding.

I added some logging, specifically around what is being returned from diffQueryAgainstStore https://github.com/apollographql/apollo-client/blob/main/src/cache/inmemory/readFromStore.ts#L294-L298

and what is being passed into executeSelectionSet https://github.com/apollographql/apollo-client/blob/main/src/cache/inmemory/readFromStore.ts#L162C10-L163

Findings with no @defer

I have set up two pages and two queries.

Page 1 + Query 1

const BOOKS_STORES_QUERY = gql`
  query BOOKS_DEFERRED_STORES_QUERY($isbn: String!) {
    book(isbn: $isbn) {
      id
      title
      dateAdded
      isbn
      author {
        id
        name
      }
      stores {
        id
        name
      }
    }
  }
`;

Page 2 + Query2

const BOOKS_STORES_MANAGERS_QUERY = gql`
  query BOOKS_DEFERRED_STORES_MANAGERS_QUERY($isbn: String!) {
    book(isbn: $isbn) {
      id
      title
      dateAdded
      isbn
      author {
        id
        name
      }
      stores {
        id
        name
        address
        hours {
          monday
          tuesday
          wednesday
          thursday
          friday
          saturday
          sunday
        }
        managers {
          id
          name
        }
      }
    }
  }
`;

Key pieces here are just adding nested data below stores.

Assume we have loaded the first page and that everything from the first query is stored in the cache.

I can see that when I transition from the first page to second page that a set of data is fetched from the cache matching the first query, but we can see that complete is marked as false.

returning execResult.result, complete {book: {…}} false
Note that there is no hours data here at stores.hours
image

Eventually more logs

inside executeSelectionSet, what are options
...
enclosingRef: 
{__ref: 'Store:5002'}
objectOrReference: {__ref: 'Store:5002'}

...
inside executeSelectionSet, what are options 
enclosingRef: {__ref: 'Store:5002'}
objectOrReference: {__typename: 'StoreHours', monday: 'all-day', tuesday: 'all-day', wednesday: 'all-day', thursday: 'all-day', …}

...

returning execResult.result, complete {book: {…}} true
what is data? {book: {…}} false

So complete is set to true once we've finally selected all the nested data under stores in query 2 and the what is data? log is coming from my React component to indicate that data has been returned from useQuery and that loading is now false. This is expected as the query has gotten all of its data and rendered.

Findings with @defer

With the same logging in place, it was pretty apparent what was happening with the defer.

returning execResult.result, complete {book: {
book: 
  author: {__typename: 'Author', id: '100', name: 'Hofstadter, Douglas R.'}
  dateAdded: "2024-05-05 03:08:03"
  id: "2015"
  isbn: "9780465026562"
  stores: (2) [
    0: {__typename: 'Store', id: '5001', name: 'First Store'}
    1: {__typename: 'Store', id: '5002', name: 'Second Store'}
  ]
  title: "GODEL ESCHER BACH : ETERNAL GOLDEN BRAID / 20TH ANNIVERSARY ED"
__typename: "Book"
}} false

...

what is data? {book: {…}} false // book here is the same as the book expanded above

When navigating from page 1 to page 2, what I see is that we immediately get a cache hit on the data requested from query 1 and that data ends up being returned from useQuery. You can see in the logs above that data structure being printed out.

So I guess my question before diving any deeper into this would be what should be expected behavior be? It appears right now that Apollo attempts to fill in as much of the query as possible, including deferred fields, and return it from the cache. Reading deferred fields from the cache makes sense because if a full cache hit can be found, then the presumed long request time associated with the defer can be avoided.

What isn't clear is if there is a partial cache hit for deferred fields, such as I've shown above, should Apollo return anything? It feels like only full cache hits should be returned from the cache (whether deferred or not) and partial hits should be omitted. What are your thoughts?

from apollo-client.

jerelmiller avatar jerelmiller commented on August 27, 2024

@jer-k thats a great question! Let me bring this up in our next team meeting to see what we all think here. FWIW my personal opinion is like yours; the client shouldn't return partial data on deferred fields unless you've set returnPartialData: true.

The example you have here is great by the way! For brevity, would you mind posting the query with @defer in it so I understand exactly which fields are deferred here? Is it the entire stores field or only the missing subfields within store?

from apollo-client.

jer-k avatar jer-k commented on August 27, 2024

Here are the two deferred queries. Sorry I was running out of time yesterday and rushing a little. I am deferring the entire stores field

const BOOKS_DEFERRED_STORES_QUERY = gql`
  query BOOKS_DEFERRED_STORES_QUERY($isbn: String!) {
    book(isbn: $isbn) {
      id
      title
      dateAdded
      isbn
      author {
        id
        name
      }
      ... @defer {
        stores {
          id
          name
        }
      }
    }
  }
`;
const BOOKS_DEFERRED_STORES_MANAGERS_QUERY = gql`
  query BOOKS_DEFERRED_STORES_MANAGERS_QUERY($isbn: String!) {
    book(isbn: $isbn) {
      id
      title
      dateAdded
      isbn
      author {
        id
        name
      }
      ... @defer {
        stores {
          id
          name
          address
          hours {
            monday
            tuesday
            wednesday
            thursday
            friday
            saturday
            sunday
          }
          managers {
            id
            name
          }
        }
      }
    }
  }
`;

from apollo-client.

jerelmiller avatar jerelmiller commented on August 27, 2024

Awesome, thank you!!

from apollo-client.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.