I'm currently learning Next.js 13 and I'm trying to fetch data from a PocketBase database to display in a table. I've created an API route that connects to the database and retrieves the data. However, I'm having trouble fetching this data in a server ponent.
Here's the structure of my project:
app/
api/
ingresos/
route.ts
ponents/
tablaIngresosCliente.tsx
ingresos/
page.tsx
...
In route.ts
, I connect to the PocketBase database and fetch the data:
// app/api/ingresos/route.ts
import { NextResponse } from 'next/server';
import PocketBase from 'pocketbase';
export async function GET(request: Request) {
const pb = new PocketBase('http://127.0.0.1:8090');
try {
const records = await pb.collection('ingresos').getFullList({
sort: '-created',
});
return NextResponse.json(records);
} catch (error) {
console.error(error)
return new Response('Could not fetch', { status: 500 })
}
}
In tablaIngresosCliente.tsx
, I'm trying to fetch the data from the API route:
// app/ponents/tablaIngresosCliente.tsx
export default async function TablaIngresos() {
const res = await fetch('/api/ingresos');
const ingresos = await res.json();
return (
<div className="flex flex-col">
<div className="overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full py-2 sm:px-6 lg:px-8">
<div className="overflow-hidden">
<table className="min-w-full text-center text-sm font-light">
<thead className="border-b bg-neutral-800 font-medium text-white dark:border-neutral-500 dark:bg-neutral-900">
<tr>
<th scope="col" className=" px-6 py-4">#</th>
<th scope="col" className=" px-6 py-4">Fuente</th>
<th scope="col" className=" px-6 py-4">Cantidad</th>
<th scope="col" className=" px-6 py-4">Fecha</th>
</tr>
</thead>
<tbody>
{ingresos.map((item, index) => (
<tr key={index} className="border-b dark:border-neutral-500">
<td className="whitespace-nowrap px-6 py-4 font-medium">{index + 1}</td>
<td className="whitespace-nowrap px-6 py-4">{item.fuente}</td>
<td className="whitespace-nowrap px-6 py-4">{item.cantidad}</td>
<td className="whitespace-nowrap px-6 py-4">{item.fecha}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}
With this setup, I'm able to get the correct response when I visit the /api/ingresos
route in my browser. However, I'm still unsure about how to use this API route in my tablaIngresosCliente.tsx
page ponent to fetch the data.
I'm aware that I could potentially use server ponent actions, but I chose this approach because I plan to use a client ponent to make a POST request to add new data to the database. I thought that using the API route would be a good way to handle both GET and POST requests.
I'm wondering if this is the correct approach for fetching data in Next.js 13. Is it remended to fetch data from an API route in a server ponent, or is there a better way to fetch and display data in Next.js 13?
Any guidance would be greatly appreciated. Thank you!
I'm currently learning Next.js 13 and I'm trying to fetch data from a PocketBase database to display in a table. I've created an API route that connects to the database and retrieves the data. However, I'm having trouble fetching this data in a server ponent.
Here's the structure of my project:
app/
api/
ingresos/
route.ts
ponents/
tablaIngresosCliente.tsx
ingresos/
page.tsx
...
In route.ts
, I connect to the PocketBase database and fetch the data:
// app/api/ingresos/route.ts
import { NextResponse } from 'next/server';
import PocketBase from 'pocketbase';
export async function GET(request: Request) {
const pb = new PocketBase('http://127.0.0.1:8090');
try {
const records = await pb.collection('ingresos').getFullList({
sort: '-created',
});
return NextResponse.json(records);
} catch (error) {
console.error(error)
return new Response('Could not fetch', { status: 500 })
}
}
In tablaIngresosCliente.tsx
, I'm trying to fetch the data from the API route:
// app/ponents/tablaIngresosCliente.tsx
export default async function TablaIngresos() {
const res = await fetch('/api/ingresos');
const ingresos = await res.json();
return (
<div className="flex flex-col">
<div className="overflow-x-auto sm:-mx-6 lg:-mx-8">
<div className="inline-block min-w-full py-2 sm:px-6 lg:px-8">
<div className="overflow-hidden">
<table className="min-w-full text-center text-sm font-light">
<thead className="border-b bg-neutral-800 font-medium text-white dark:border-neutral-500 dark:bg-neutral-900">
<tr>
<th scope="col" className=" px-6 py-4">#</th>
<th scope="col" className=" px-6 py-4">Fuente</th>
<th scope="col" className=" px-6 py-4">Cantidad</th>
<th scope="col" className=" px-6 py-4">Fecha</th>
</tr>
</thead>
<tbody>
{ingresos.map((item, index) => (
<tr key={index} className="border-b dark:border-neutral-500">
<td className="whitespace-nowrap px-6 py-4 font-medium">{index + 1}</td>
<td className="whitespace-nowrap px-6 py-4">{item.fuente}</td>
<td className="whitespace-nowrap px-6 py-4">{item.cantidad}</td>
<td className="whitespace-nowrap px-6 py-4">{item.fecha}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
);
}
With this setup, I'm able to get the correct response when I visit the /api/ingresos
route in my browser. However, I'm still unsure about how to use this API route in my tablaIngresosCliente.tsx
page ponent to fetch the data.
I'm aware that I could potentially use server ponent actions, but I chose this approach because I plan to use a client ponent to make a POST request to add new data to the database. I thought that using the API route would be a good way to handle both GET and POST requests.
I'm wondering if this is the correct approach for fetching data in Next.js 13. Is it remended to fetch data from an API route in a server ponent, or is there a better way to fetch and display data in Next.js 13?
Any guidance would be greatly appreciated. Thank you!
Share Improve this question edited Aug 8, 2023 at 7:31 Drew Reese 204k18 gold badges240 silver badges271 bronze badges asked Aug 1, 2023 at 4:51 VladimirzbVladimirzb 5173 gold badges9 silver badges28 bronze badges 1- 1 "export default async function TablaIngresos() { const ingresos: Ingreso[] = await fetch('localhost:3000/api/ingresos').then(res => res.json()); return (" This seems to work well for fetching data from my API route in a server ponent. However, I'm still curious about whether this is considered good practice in Next.js 13. Is it remended to fetch data from an API route in a server ponent like this, or is there a better way to do it? – Vladimirzb Commented Aug 1, 2023 at 5:19
3 Answers
Reset to default 2You can not fetch from API routes (rather handler - GET, POST etc. that you export from route.ts
) in server ponents. You should extract the fetching logic to util function and use that instead to fetch data in server ponent.
API routes can be called only from client ponents.
I agree, using fetch in api route is a pain, the api returns {Digest: DYNAMIC_SERVER_USAGE} instead of the server response in PROD mode, otherwise i can get data correctly in DEV mode (nextjs 13.5.6)
Try simply delete your .next folder, works for me.