Lekce 3: Práce s daty a API routes
V této lekci se naučíme, jak pracovat s daty. Next.js nám umožňuje vytvořit vlastní **API endpointy**, což jsou vlastně jednoduché serverové funkce, které vracejí data. Díky tomu si můžeme snadno vytvořit malý backend přímo v našem projektu. Následně si ukážeme, jak tato data číst a zobrazovat na frontendu.
Shrnutí lekce:
Probereme klíčové aspekty práce s daty a API, které jsou nezbytné pro každou reálnou aplikaci. Níže najdete odkazy na jednotlivé části lekce:
Co jsou API routes v Next.js
API routes vám umožní vytvořit **API endpoint** přímo v Next.js projektu, aniž byste museli spouštět samostatný backend server. Jsou umístěny v adresáři app/api/ a každá metoda (GET, POST, atd.) je definována ve vlastním souboru.
// app/api/products/route.ts
import { NextResponse } from 'next/server';
// Mock data pro jednoduchý příklad
const products = [
{ id: 1, name: 'Notebook', price: 15000 },
{ id: 2, name: 'Telefon', price: 10000 },
];
export async function GET() {
return NextResponse.json(products);
}
GET endpoint – vrácení seznamu produktů
Pro GET request (získání dat) vytvořte soubor app/api/products/route.ts a do něj přidejte funkci GET(). Tato funkce bude reagovat na HTTP GET požadavek a vrátí JSON s daty.
// app/api/products/route.ts
// Kód je v sekci výše
Tento endpoint bude dostupný na adrese /api/products.
POST endpoint – přidání produktu
Pro POST request (přidání dat) přidáte do stejného souboru funkci POST().
// app/api/products/route.ts
import { NextResponse } from 'next/server';
const products = [
{ id: 1, name: 'Notebook', price: 15000 },
{ id: 2, name: 'Telefon', price: 10000 },
];
export async function POST(request: Request) {
const newProduct = await request.json();
const newId = products.length > 0 ? products[products.length - 1].id + 1 : 1;
const productWithId = { ...newProduct, id: newId };
products.push(productWithId);
return NextResponse.json(productWithId, { status: 201 });
}
Fetchování dat v server komponentě
Díky Next.js můžete data získávat přímo v **server komponentách** pomocí nativní funkce fetch(). To je velká výhoda, protože se data načtou na serveru ještě před odesláním stránky do prohlížeče.
// app/products/page.tsx
interface Product {
id: number;
name: string;
price: number;
}
async function getProducts(): Promise<Product[]> {
const res = await fetch('http://localhost:3000/api/products');
if (!res.ok) {
throw new Error('Failed to fetch products');
}
return res.json();
}
export default async function ProductsPage() {
const products = await getProducts();
return (
<div>
<h1>Naše produkty</h1>
<ul>
{products.map(product => (
<li key={product.id}>{product.name} - {product.price} Kč</li>
))}
</ul>
</div>
);
}
Server Components vs. Client Components
Next.js má dva typy komponent. Server komponenty (výchozí) se vykreslují na serveru a nemohou používat hooks jako useState nebo useEffect. Client komponenty (označené 'use client') se vykreslují v prohlížeči a jsou ideální pro interaktivní UI.
| Typ komponenty | Klíčové vlastnosti | Kdy je použít |
|---|---|---|
| Server Component (výchozí) | Vykresleno na serveru, přístup k souborovému systému, žádné hooks. | Pro statické části UI, fetchování dat. |
Client Component ('use client') |
Vykresleno na straně klienta, interaktivita, hooks jako useState a useEffect. |
Pro formuláře, buttony, jakoukoli interaktivitu. |
Použití SWR pro revalidaci dat
**SWR** (Stale-While-Revalidate) je React hook, který se skvěle hodí pro klient-side fetchování dat a automatickou revalidaci.
// app/products/client-page.tsx
'use client';
import useSWR from 'swr';
interface Product {
id: number;
name: string;
price: number;
}
const fetcher = (url: string) => fetch(url).then(res => res.json());
export default function ProductsClientPage() {
const { data, error, isLoading } = useSWR<Product[]>('/api/products', fetcher);
if (error) return <div>Failed to load</div>;
if (isLoading) return <div>Načítám...</div>;
return (
<div>
<h1>Produkty (SWR)</h1>
<ul>
{data?.map(product => (
<li key={product.id}>{product.name} - {product.price} Kč</li>
))}
</ul>
</div>
);
}
Globální typy – Product interface
Pro usnadnění práce s TypeScriptem je dobré si definovat globální typy pro vaše datové modely.
// types/product.ts
export interface Product {
id: number;
name: string;
price: number;
}
Environment proměnné
Citlivé informace, jako jsou API klíče, se neukládají přímo v kódu, ale v **environment proměnných** v souboru .env.local.
# .env.local
API_URL=http://localhost:3000/api
A použijete je v kódu takto: process.env.API_URL.
Konfigurace projektu (next.config.js)
Soubor next.config.js slouží pro pokročilou konfiguraci projektu.
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
};
module.exports = nextConfig;
Skvělá práce! Nyní už víte, jak pracovat s daty, což je naprosto zásadní dovednost. Dokážete si vytvořit vlastní API endpointy a číst z nich data jak na serveru, tak na klientu.
´