React Server Components should fetch directly from functions on the server when possible. Instead of calling internal APIs, call data-getter functions directly.

Both of the following RSCs fetch the same data, and they both (sort of) work, but it is an anti-pattern to use an internal API to fetch data in an RSC. Of course, if the API is external, have at it!

Fetch Directly
server
node.js
Ron Johnston's avatar

Ron Johnston

International Interactions Producer

Dr. Oliver Runolfsson's avatar

Dr. Oliver Runolfsson

Dynamic Program Supervisor

Mr. Ricardo Weissnat's avatar

Mr. Ricardo Weissnat

Investor Configuration Architect

Fetch Internal API
server
node.js
Fetching Directly
Good! 👍
// do this
export async function FetchDirect() {
const users = await getSampleData();
return <Users users={users} />;
}

// or even
export async function FetchSQL() {
const query = 'SELECT * FROM users';
const users = await db.query(query);
return <Users users={users} />;
}
Fetching from internal API
Bad! 👎
// don't do this
export async function FetchAPI() {
// this API implements getSampleData()
const url = process.env.APP_URL + "/api/sampleData";
const response = await fetch(url);
const users = (await response.json()) as UserType[];
return <Users users={users} />;
}

This may feel strange coming from the client-side world, but the benefits are clear:

  • Faster as there is no network request
  • More secure as you don't need to expose an API
  • Improved DX as it is just like importing a module
  • TypeScript types will be included
  • Easier to test / maintain / debug

And that's not to mention that your local API server won't be running during the build step, so you don't get the benefits of SSG. Just say "no" to using an internal API to fetch data in an RSC.

Next, let's look at what Next.js can do with caching strategies.