Zpět na kurz

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.

David Kojecký

David Kojecký

Programátor ve společnosti Codefit a vývojář pro Mobilní lékárna CZ

´