Internal API Fetch with Getserversideprops? (Next.Js)

Internal API fetch with getServerSideProps? (Next.js)

But then I read in the Next.js documentation that you should not use fetch() to all an API route in getServerSideProps().

You want to use the logic that's in your API route directly in getServerSideProps, rather than calling your internal API. That's because getServerSideProps runs on the server just like the API routes (making a request from the server to the server itself would be pointless). You can read from the filesystem or access a database directly from getServerSideProps. Note that this only applies to calls to internal API routes - it's perfectly fine to call external APIs from getServerSideProps.

From Next.js getServerSideProps documentation:

It can be tempting to reach for an API Route when you want to fetch
data from the server, then call that API route from
getServerSideProps. This is an unnecessary and inefficient approach,
as it will cause an extra request to be made due to both
getServerSideProps and API Routes running on the server.

(...) Instead, directly import the logic used inside your API Route
into getServerSideProps. This could mean calling a CMS, database, or
other API directly from inside getServerSideProps.

(Note that the same applies when using getStaticProps/getStaticPaths methods)


Here's a small refactor example that allows you to have logic from an API route reused in getServerSideProps.

Let's assume you have this simple API route.

// pages/api/user
export default async function handler(req, res) {
// Using a fetch here but could be any async operation to an external source
const response = await fetch(/* external API endpoint */)
const jsonData = await response.json()
res.status(200).json(jsonData)
}

You can extract the fetching logic to a separate function (can still keep it in api/user if you want), which is still usable in the API route.

// pages/api/user
export async function getData() {
const response = await fetch(/* external API endpoint */)
const jsonData = await response.json()
return jsonData
}

export default async function handler(req, res) {
const jsonData = await getData()
res.status(200).json(jsonData)
}

But also allows you to re-use the getData function in getServerSideProps.

// pages/home
import { getData } from './api/user'

//...

export async function getServerSideProps(context) {
const jsonData = await getData()
//...
}

Is fetch inside getStaticProps and getServerSideProps the same as the native browser fetch API?

So my doubt is we only write server-side code and node.js doesn't have a native fetch API, so what fetch API is used inside getStaticProps and getServerSideProps?

In the Node.js environment (getStaticProps, getServerSideProps and API routes) Next.js uses node-fetch to polyfill the fetch API.

nextjs: how can I do a fetch on a local path?

You can do it like this fetch('http://localhost:3000/api/get_all_prices')
or replace the base URL with a variable fetch(baseUrl + 'api/get_all_prices') which might cause error: Only absolute paths are supported.
However, you should only call local API for testing because...

You should not use fetch() to call an API route in getServerSideProps

this is mentioned in the documentation

It is recommended to write your logic directly inside getServerSideProps.
This applies to getStaticProps too.

NextJS generate page getServerSideProps to getStaticProps

I saw an article on MongoDB, here is the link, just don't use internal API and then fetch data direct to MongoDB in getStaticProps, here in my code.

BEFORE

export async function getServerSideProps() {

const response = await fetch(`${server}/api/gallery`);
const data = await response.json();

if (!data) {
return {
notFound: true,
};
}

return {
props: { data },
};
}

AFTER

export async function getStaticProps() {
await dbConnect()
//connect to mongodb
const gallery = await art.find()
//i use mongoose model to fetch data

return {
props:{
data:JSON.parse(JSON.stringify(gallery))
}
}

}

How to share data between API route and getServerSideProps?

You could use Node.js global object to share data between API routes and getServerSideProps.

For instance, you could set the data in the getServerSideProps function.

export const getServerSideProps = async () => {
// Set data in `global` object
global._SOME_DATA_ = { data: { hello: 'world' }, ttl: '3600' }
// ...
}

Then retrieve that same data at a later point in the API route.

export default async (req, res) => {
console.log(global._SOME_DATA_) // Logs: `{ data: { hello: 'world' }, ttl: '3600' }`
// ...
}


Related Topics



Leave a reply



Submit