Skip to content

Kapitel 10: API-Routen entwickeln

📖 Lernziele

In diesem Kapitel lernen Sie:

  • ✅ API-Routen im App Router erstellen (route.js)
  • ✅ Verschiedene HTTP-Methoden (GET, POST, PUT, DELETE) implementieren
  • ✅ Router-Parameter und Anfrage-Body verarbeiten
  • ✅ Middleware für Authentifizierung verwenden
  • ✅ Eine einfache Datenbankverbindung herstellen

10.1 API-Routen Grundlagen

🎯 Was sind API-Routen?

API-Routen ermöglichen es Next.js, Backend-Funktionalität ohne einen separaten Server zu bieten.

📂 Dateistruktur (App Router)

app/
└── api/
    └── users/
        └── route.js    →  /api/users (GET, POST)
        └── [id]/
            └── route.js →  /api/users/[id] (GET, PUT, DELETE)

📝 Beispiel: Einfache GET-Route

Datei: app/api/hello/route.js

javascript
export async function GET() {
  return Response.json({ message: 'Hallo von der API!' });
}

Zugriff: http://localhost:3000/api/hello

Ergebnis (JSON):

json
{
  "message": "Hallo von der API!"
}

10.2 HTTP-Methoden implementieren

📝 GET (Daten abrufen)

javascript
// app/api/users/route.js
let users = [
  { id: 1, name: 'Max' },
  { id: 2, name: 'Anna' },
];

export async function GET() {
  return Response.json(users);
}

📝 POST (Daten erstellen)

javascript
// app/api/users/route.js
export async function POST(request) {
  const body = await request.json(); // Body parsen
  
  // Validierung
  if (!body.name) {
    return Response.json(
      { error: 'Name ist erforderlich' },
      { status: 400 }
    );
  }
  
  const newUser = {
    id: Date.now(),
    name: body.name,
  };
  
  // In echter Anwendung: In Datenbank speichern
  users.push(newUser);
  
  return Response.json(newUser, { status: 201 });
}

📝 PUT (Daten aktualisieren)

javascript
// app/api/users/[id]/route.js
export async function PUT(request, { params }) {
  const { id } = params;
  const body = await request.json();
  
  // In echter Anwendung: Datenbank aktualisieren
  const userIndex = users.findIndex(u => u.id === parseInt(id));
  
  if (userIndex === -1) {
    return Response.json(
      { error: 'Benutzer nicht gefunden' },
      { status: 404 }
    );
  }
  
  users[userIndex] = { ...users[userIndex], ...body };
  
  return Response.json(users[userIndex]);
}

📝 DELETE (Daten löschen)

javascript
// app/api/users/[id]/route.js
export async function DELETE(request, { params }) {
  const { id } = params;
  
  // In echter Anwendung: Aus Datenbank löschen
  users = users.filter(u => u.id !== parseInt(id));
  
  return new Response(null, { status: 204 }); // No Content
}

10.3 Router-Parameter & Anfrage-Body

🎯 URL-Parameter (params)

Datei: app/api/users/[id]/route.js

javascript
export async function GET(request, { params }) {
  const { id } = params;
  
  const user = users.find(u => u.id === parseInt(id));
  
  if (!user) {
    return Response.json(
      { error: 'Benutzer nicht gefunden' },
      { status: 404 }
    );
  }
  
  return Response.json(user);
}

🎯 Query-Parameter (searchParams)

URL: /api/users?role=admin

javascript
export async function GET(request) {
  const { searchParams } = new URL(request.url);
  const role = searchParams.get('role'); // "admin"
  
  let filteredUsers = users;
  
  if (role) {
    filteredUsers = users.filter(u => u.role === role);
  }
  
  return Response.json(filteredUsers);
}

🎯 Anfrage-Body verarbeiten

JSON-Body:

javascript
export async function POST(request) {
  const body = await request.json();
  // body = { name: "Max", email: "max@example.com" }
}

Form-Data:

javascript
export async function POST(request) {
  const formData = await request.formData();
  const file = formData.get('file');
  const name = formData.get('name');
  
  // Datei speichern...
}

10.4 Middleware & Authentifizierung

🎯 Route-Schutz (Einfache Überprüfung)

Beispiel: API-Route nur mit Token zugänglich

javascript
// app/api/protected/route.js
export async function GET(request) {
  // Token aus Header abrufen
  const authHeader = request.headers.get('Authorization');
  
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return Response.json(
      { error: 'Nicht autorisiert' },
      { status: 401 }
    );
  }
  
  const token = authHeader.split(' ')[1];
  
  // Token validieren (vereinfacht)
  if (token !== 'mein-geheimer-token') {
    return Response.json(
      { error: 'Ungültiges Token' },
      { status: 403 }
    );
  }
  
  // Erfolgreiche Antwort
  return Response.json({ message: 'Zugriff gewährt!' });
}

🎯 Middleware für alle Routen

Datei: middleware.js (Projekt-Root)

javascript
import { NextResponse } from 'next/server';

export function middleware(request) {
  // Alle /api/admin Routen schützen
  if (request.nextUrl.pathname.startsWith('/api/admin')) {
    const token = request.cookies.get('admin-token');
    
    if (!token) {
      return NextResponse.json(
        { error: 'Admin-Zugriff erforderlich' },
        { status: 401 }
      );
    }
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: ['/api/admin/:path*'],
};

10.5 Datenbankverbindung (Einfaches Beispiel)

🎯 MongoDB-Verbindung

Installation:

bash
pnpm add mongodb

Datei: lib/mongodb.js

javascript
import { MongoClient } from 'mongodb';

const uri = process.env.MONGODB_URI;
const options = {};

let client;
let clientPromise;

if (!global._mongoClientPromise) {
  client = new MongoClient(uri, options);
  global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;

export default clientPromise;

Verwendung in API-Route:

javascript
// app/api/posts/route.js
import clientPromise from '@/lib/mongodb';

export async function GET() {
  const client = await clientPromise;
  const db = client.db('meine-datenbank');
  const posts = await db.collection('posts').find({}).toArray();
  
  return Response.json(posts);
}

export async function POST(request) {
  const body = await request.json();
  
  const client = await clientPromise;
  const db = client.db('meine-datenbank');
  
  const result = await db.collection('posts').insertOne(body);
  
  return Response.json(
    { id: result.insertedId, ...body },
    { status: 201 }
  );
}

🎯 PostgreSQL-Verbindung (mit Prisma)

Installation:

bash
pnpm add @prisma/client prisma
npx prisma init

Verwendung:

javascript
// app/api/users/route.js
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export async function GET() {
  const users = await prisma.user.findMany();
  return Response.json(users);
}

📝 Zusammenfassung

In diesem Kapitel haben Sie gelernt:

KonzeptErklärung
API-RoutenBackend-Funktionalität in Next.js (route.js)
HTTP-MethodenGET, POST, PUT, DELETE implementieren
ParameterURL-Parameter (params) und Query-Parameter (searchParams)
BodyJSON und Form-Data verarbeiten
MiddlewareAuthentifizierung und Zugriffskontrolle
DatenbankMongoDB und PostgreSQL (Prisma) anbinden

✅ Nächste Schritte

  1. Übung: Erstellen Sie eine CRUD-API für "Todo-Items"
  2. Übung: Implementieren Sie Token-basierte Authentifizierung
  3. Weiter geht's: Kapitel 11 - Praxisprojekt: Persönlicher Blog

🎯 Selbsttest

Frage 1: Welche Datei erstellt eine API-Route im App Router?

Antwort anzeigen `route.js`

Frage 2: Wie liest man den Body einer POST-Anfrage?

Antwort anzeigen Mit `await request.json()` (für JSON) oder `await request.formData()` (für Formulare).

Frage 3: Wo platziert man die Middleware-Datei?

Antwort anzeigen Im Projekt-Root (`middleware.js`).

🚀 Weiter zu Kapitel 11: Praxisprojekt - Persönlicher Blog

Frei für alle Anfänger