-
Notifications
You must be signed in to change notification settings - Fork 27.3k
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
Improve with-apollo example to more closely align to Next.js standards #21984
Comments
Follow up from this PR: #21956 |
Hey @leerob I think it actually does. Inside |
Hey, I'm a little confused by the current with-apollo example. Midway through last year before the example was updated to use SSG it looked significantly different (Old method). It seems that the main difference between the old method and your current method is that the current requires you to manually import any queries that are used in the page and run them inside getServerSideProps, while the old method did a double render - first to run any queries and populate the cache (using getDataFromTree) and then to actually render the components. The old method was really nice in how you there were no extra steps, you write queries wherever they are needed and it just works. This new method seems like a lot more work for no real benefit. What am I missing here? Is this new method better? And if so why? Thanks in advance for the help! |
@Francesco-Lanciana Overall, the older solution was brittle and error-prone. It was also very confusing for beginners. The new approach is much better IMO. |
@Francesco-Lanciana The old method relied on But your approach of using |
@leerob what was brittle and error-prone about it? I definitely agree it was very confusing for beginners but this could have been fixed with better documentation. And the gDFT approach means you have to write a lot less boilerplate code once it was up and running. Not only that but this current example still relies on priming apollos cache during getServerSideProps to work, you don't actually make use of the props passed to the page directly. That's still going to confuse beginners. @filipesmedeiros why do you think that this approach is better in general? You still had to pass ssr: true to the withApollo function in the previous approach to opt into SSR, and you didn't have to query things twice (once in getServerSideProps and once in the component). It just feels like all this new approach does is make it slightly more explicit as to what data is being fetched server side at the expense of more boilerplate code. This might be useful if you want to selectively run only some queries when SSRing but I don't know why you would want to do that. And once you understand whats happening and your app becomes larger using gDFT seems like a natural next step to avoid this boilerplate. 100% the withApollo function with the gDFT approach was more involved but it's not like you should be having to modify that file often, and again with some extra documentation I don't think this extra render + gDFT method is hard to explain. |
It does, and I think that it shouldn't
Agreed
Disagree with "slightly" (everything is inside Another benefit is no extra render, like you said (it can be bad, but don't think it generally will be. Also, I just don't feel it feels Nexty ahah |
Wow, this example just wasted hours because you guys forgot to actually pass the props down. Here I am thinking there is some magical implementation here that can replace implicitly populate useQuery from cache in real time. FWIW I do not think this example is correctly titled. Should simply call this 'with-apollo-cache-rehydration' and leave the other one as 'with-apollo-GDT' |
@mansoor292 What do you mean? This is an issue, there's no implementation here |
The way the with-Apollo example is written, the ssr page is not doing any ssr at all. The data itself is being cached and sent to client, and being rendered by/in the browser. Since it is also using a new Apollo client in getSSP, you don't even get to use the cache created server side. On first read it seems like there is a 'magical' implementation. After 2 hours you find out the magic was there is no implementation at all. This is essentially a security demo. How to not expose graphql api endpoint to a client. Kinda opinionated and not well documented. My use case for next is to serve fast landing pages but then hydrate a full client side app. |
@mansoor292 Having data pre-fetched on page load and directly showing data without loading state IS indeed SSR. SSR does not only mean "rendering html", but also mean prefetched data |
While i think it’s definitely used as such, rendering cannot mean data
fetching. To render means ‘cause to become’. Are we causing JavaScript to
become a webpage by just preloading data? I personally don’t agree.
In any case it’s a semantic discussion, better documentation, or better
still just setting up the props to render the page would be better.
…On Tue, May 11, 2021 at 12:01 AM Alvin Li ***@***.***> wrote:
@mansoor292 <https://github.com/mansoor292> Having data pre-fetched on
page load and directly showing data without loading state IS indeed SSR.
SSR does not only mean "rendering html", but also mean prefetched data
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#21984 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADPRYXWGBY2MQRJDYYIS5LTNCTZJANCNFSM4XKHFBOQ>
.
|
@mansoor292 Not sure to understand 🤔 The ssr page in the current |
I think some more documentation could definitely help here. I was surprised to find (with the help of To explain this a little better...in order for the server to return the initial HTML for the
Is there no way that the server couldn't simply reuse the existing instance instead of creating a new one and having to restore the cache? All the above steps happen as part of the same HTTP request. |
@mbrowne The client is in memory, you have to instantiate it in the browser in some way ahah You can't share instances between server and client (as far as I know ofc) |
@filipesmedeiros I'm not talking about the browser at all. Both instances of ApolloClient I'm talking about are created on the server (and only exist on the server). |
Ahh didn't get that. Ok that's my bad. And I guess shouldn't happen yeah |
The tricky part would be to detect when to return a new ApolloClient and when not to. You definitely don't want to end up reusing the same ApolloClient on the server across multiple requests—that can cause cached data to leak from one page to another and cause hard-to-trace bugs. That's why there's this comment in the example code:
It would be helpful to have some understanding of next.js internals (certainly more than I have) to know how to improve the example, if possible. From what I can gather, |
Correct me if I am wrong, I think the tricky part is to make |
You can probably get access to some sort of request ID? And hopefully it's also accessible on the Page component? Just guessing though |
I have being using the old example for some long time (maybe a couple of years) on production of massive sites and using This change forces developers to imperatively fetch and know how to fetch any content needed to fullfil the page's data to render, also the execution of queries out of the components (or containers) will create a new layer of coupling outside of it creating a lot of boilerplate. Maybe for a small site with a couple of pages and simple components which don't need to render on server the new example seems ok, though I don't see how it could scale when adding more complex components. On the case of SSG the next-with-apollo module solves it by removing the I think a new example should be created with two different goals, one with the new simple and flexible way and another with better SSR DX (in my opinion) using |
…ons/next (#42771) Closes #42769 ## Description This PR address #42769 by updating the `api-routes-apollo-server`, `api-routes-apollo-server-and-client` and `api-routes-apollo-server-and-client-auth` examples to use Apollo Server 4 and [@as-integrations/next](https://github.com/apollo-server-integrations/apollo-server-integration-next), which is the Apollo Server Next integration package. The PR also updates the three examples to use Typescript. The functionality of the examples is the same. ## Documentation / Examples - [X] Make sure the linting passes by running `pnpm build && pnpm lint` - [X] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) closes #33545 closes #30082 closes #21984 closes #10413
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
What example does this report relate to?
with-apollo
What version of Next.js are you using?
latest
What version of Node.js are you using?
latest
What browser are you using?
any
What operating system are you using?
any
How are you deploying your application?
any
Describe the Bug
The current
with-apollo
example fetches data and adds it to the cache, but never returns that data insidegetStaticPaths
/getSeverSideProps
.Expected Behavior
All other usage of
getStaticProps
/getServerSideProps
show forwarded the data to the component via props (hence the names). This seems really confusing to me. I think we should use props here instead.To Reproduce
View the
with-apollo
exampleThe text was updated successfully, but these errors were encountered: