NextJS - conditionally pull data from an external API with getServerSideProps - reactjs

I need to pull data from an external third-party API, and the request to the API has to come from the server-side rather than the client-side (the API will reject client-side requests).
I'm looking to use getServerSideProps, since according to the NextJS API it " only runs on server-side and never runs on the browser" which is exactly what I need.
However, once I pull the data from the API, I won't need to re-pull the data for another 15-30 minutes. During that time, I would use the previous response.
For this, swr sounds good, since it can be made into a reusable hook and "there will be only 1 request sent to the API, because they use the same SWR key and the request is deduped, cached and shared automatically."
The page's flow would look like:
User navigates to page and requests data
If the data does not already exist from a prior pull, use getServerSideProps to pull and store the data
If the data does exist and was pulled within the last 30 minutes, use swr (or some other method) to call an internal API and process the existing data, thereby avoiding another external API request.
The problem with this is getServerSideProps "must be exported as a standalone function — it will not work if you add getServerSideProps as a property of the page component", and it will run every time the page is requested.
Is there a way I can use getServerSideProps but only run it conditionally? Or is there another way that is more appropriate for this situation?

use getStaticProps which only runs during build-time. HTML will be created and will be placed into cache. when first request comes, html will be served from the cache
export async function getStaticProps(context) {
const data = await fetchData(args);
return {
props: {
// make sure you do not return undefined. it does not get serialized
myProp: data,
},
// first request will be returned from cache
// then data will be revalidated and cache will be updated
revalidate: 10*60, // In seconds. 10 minutes
};
}

Related

How to get data from api routes in next js

Hi i am having api routes which listens to incoming request ,
Code looks something like this
async function handler(req, res) {
// Run the middleware
await runMiddleware(req, res, cors)
// Rest of the API logic
res.json({ message: 'Hello Everyone!' })
console.log(req.body)
}
export default handler
whenever this request comes in , how can i interact with this data and use these on pages?
If you need this data before the page is rendered then you would not use API routes. You can (and should) use all kinds of things directly inside getServerSideProps OR getStaticProps. This basically means that you could query your DB directly inside this functions. No need to go to the "server" to do that. It's a big context switch. Speaking of context, you can get url information and all sorts of things as argument to those functions mentioned above.
If you need this data after the page is rendered then you should use client-side fetch calls to get data. You can read up on that, it's basic react data fetching.
Relevant links
Context: https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#context-parameter (for accessing stuff like params, query) before the page loads
React data fetching: https://www.robinwieruch.de/react-hooks-fetch-data/

Next.js: what is the difference between using the "revalidate" option in the getStaticProps and using the SWR package?

Next.js has this "revalidate" option out of the box:
export async function getStaticProps(context) {
const data = await getData();
if (!data) {
return {
notFound: true,
};
}
return {
props: { data },
revalidate: 60,
}
}
The above code will make sure that a page is regenerated after 60 seconds from the moment we requested the updated data (first refresh to make a request for the new data, second refresh to update page). This is based on the Incremental Static Regeneration, so the site doesn't need to be rebuilt.
From the SWR docs:
If your page contains frequently updating data, and you don’t need to
pre-render the data, SWR is a perfect fit and no special setup needed:
just import useSWR and use the hook inside any components that use the
data.
So, does it mean that in this case, useSWR is basically the same as the next.js "revalidate" option? It seems to be doing the same thing but how often does the revalidation occur then? Is there any advantage to using one over the other?
No, they are not the same and fit different use-cases.
useSWR is a data fetching hook that provides caching and automatic revalidation mechanisms (which you can control) to keep the data fresh on the client-side. The data revalidation will happen on the client and will only benefit that single user.
Using revalidate and Incremental Static Regeneration allows you to regenerate static pages on the server-side. The entire page gets generated again on the server and is statically cached. Any subsequent requests (from any user) will be served the regenerated page.
Using one or the other depends entirely on your requirements, and they're not mutually exclusive - you can use both at the same time.

Next.js : getStaticProps with context API

I'm currently building my first next app (e-commerce with Shopify Storefront API).
In order to avoid multiple query to the db and upgrade performance, I want to store all datas once a user sees a page:
1- first loading (by page): the method getStaticProps fetch the necessary datas and put everything in a context ShopContext
2- when the user hits the page another time: instead of getStaticProps re-fetch the datas, just use the data in the context.
Is it something logical to do that? And if yes, is it possible to avoid data fetching when a loading page occurs?
Many thanks for your responses ! :)

getServerSideProps vs fetching directly in React

I am getting a bit confused with the getServerSideProps of NextJS.
In the docs you can find this explanation.
For example, suppose that your page needs to pre-render frequently
updated data (fetched from an external API). You can write
getServerSideProps which fetches this data and passes it to Page
My confusing is why would you use getServerSideProps if you could simply fetch the data every x sec in your React component itself (after getting the initials data via getStaticProps).
Is there an advantage of using getServerSideProps over just the React way ?
so like this for example :
useEffect(() => {
const interval=setInterval(()=>{
const fetchdata = async () => {
const res = await fetch("url")
const data = await res.json()
setsongs(data)
}
fetchdata()
},15000)
return()=>clearInterval(interval)
}, [])
Due to the documentation, getServerSideProps fetches the API data on every request. So, there is a difference between requesting with a time interval ( like you mentioned in the react version), or using getServerSideProps.
Also, remember that getServerSideProps is implemented on the server-side and might be useful in cases that SEO is important. However, if the server goes down in the cases that you use getServerSideProps the whole page would not be served anymore.
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
Meanwhile, Fetching data on the client side (or the React way) is useful when SEO is not relevant, the page doesn’t need to be pre-rendered.
https://nextjs.org/docs/basic-features/data-fetching#fetching-data-on-the-client-side
In my opinion, it would be better if you use getServerSideProps when the displayed data is changing frequently and the user should see the most updated one, SEO is vital and a longer Time to first byte (TTFB) is acceptable.
There are useCases for all of them. You can use useEffect if SEO is not a concern and you want data to be updated in real-time.
You can use getServerSideProps when you want to have a better SEO ranking in your page.
Sure You can use getStaticProps which is way faster but know that getStaticProps is best used if your page contents don't change and stay the same like in a e-commerce website's product detail page.

SWR vs Isomorphic-unfetch for data fetch Next.Js?

While reading the Next.Js tutorial in the Routing API I learned about fetching data with these 2 libs.
The fetch object from Isomorphic-unfetch, is used within the getInitialProps async function to call an external API. Then in the Route API part, the SWR along with the { useRouter } from 'next/router; shapes the call to an internal API developed within the same Next.Js server with a lot of flexibility to query the req params.
Other than these 2 aspects, what other differences are between these 2 approaches?
isomorphic-unfetch allows you to make fetch calls on both the client and the server, which is why it's shown in examples that use getInitialProps.
Generally speaking, you fetch data on the server using getInitialProps. This will be blocking – meaning the markup will not be returned until your data has been fetched. Consider a product page for an e-commerce site. It's important that we return the product name, price, and other information from the server and not on the client-side.
SWR is similar, but a bit different. It first returns the data from cache (stale), then sends the fetch request (revalidate), and finally comes with the up-to-date data again. A real-world example of where you'd use something like SWR is on a dashboard page. You don't want to fetch all the data in getInitialProps in a blocking manner, so you render out the dashboard "shell" in a loading state, and then use SWR to fetch the data client side. You can view an example of this here.
Source - Creator of Mastering Next.js 😄

Resources