Dansk

Udforsk Next.js API-ruter og lås op for full-stack udviklingsmuligheder inden for dine React-applikationer. Lær mønstre, bedste praksisser og implementeringsstrategier.

Next.js API-ruter: Full-Stack Udviklingsmønstre

Next.js har revolutioneret React-udvikling ved at levere et robust framework til opbygning af performante og skalerbare webapplikationer. En af dets nøglefunktioner er API-ruter, som gør det muligt for udviklere at skabe backend-funktionalitet direkte i deres Next.js-projekter. Denne tilgang strømliner udviklingen, forenkler implementeringen og åbner op for kraftfulde full-stack muligheder.

Hvad er Next.js API-ruter?

Next.js API-ruter er serverløse funktioner skrevet direkte i din /pages/api-mappe. Hver fil i denne mappe bliver et API-endepunkt, der automatisk dirigerer HTTP-anmodninger til dens tilsvarende funktion. Dette eliminerer behovet for en separat backend-server, hvilket forenkler din applikationsarkitektur og reducerer driftsomkostningerne.

Tænk på dem som miniature serverløse funktioner, der lever inde i din Next.js-app. De reagerer på HTTP-anmodninger som GET, POST, PUT, DELETE og kan interagere med databaser, eksterne API'er og andre server-side ressourcer. Afgørende er det, at de kun kører på serveren, ikke i brugerens browser, hvilket sikrer sikkerheden af følsomme data som API-nøgler.

Vigtigste fordele ved API-ruter

Kom godt i gang med API-ruter

Det er ligetil at oprette en API-rute i Next.js. Opret blot en ny fil i /pages/api-mappen. Filnavnet bestemmer rutens sti. For eksempel vil oprettelse af en fil med navnet /pages/api/hello.js oprette et API-endepunkt, der er tilgængeligt på /api/hello.

Eksempel: En simpel hilsen-API

Her er et grundlæggende eksempel på en API-rute, der returnerer et JSON-svar:


// pages/api/hello.js

export default function handler(req, res) {
  res.status(200).json({ message: 'Hello from Next.js API Route!' });
}

Denne kode definerer en asynkron funktion handler, der modtager to argumenter:

Funktionen sætter HTTP-statuskoden til 200 (OK) og returnerer et JSON-svar med en besked.

Håndtering af forskellige HTTP-metoder

Du kan håndtere forskellige HTTP-metoder (GET, POST, PUT, DELETE osv.) i din API-rute ved at kontrollere egenskaben req.method. Dette giver dig mulighed for nemt at oprette RESTful API'er.


// pages/api/todos.js

export default async function handler(req, res) {
  if (req.method === 'GET') {
    // Fetch all todos from the database
    const todos = await fetchTodos();
    res.status(200).json(todos);
  } else if (req.method === 'POST') {
    // Create a new todo
    const newTodo = await createTodo(req.body);
    res.status(201).json(newTodo);
  } else {
    // Handle unsupported methods
    res.status(405).json({ message: 'Method Not Allowed' });
  }
}

Dette eksempel demonstrerer, hvordan man håndterer GET- og POST-anmodninger for et hypotetisk /api/todos-endepunkt. Det inkluderer også fejlhåndtering for ikke-understøttede metoder.

Full-Stack Udviklingsmønstre med API-ruter

Next.js API-ruter muliggør forskellige full-stack udviklingsmønstre. Her er nogle almindelige anvendelsestilfælde:

1. Datahentning og -manipulation

API-ruter kan bruges til at hente data fra databaser, eksterne API'er eller andre datakilder. De kan også bruges til at manipulere data, såsom oprettelse, opdatering eller sletning af poster.

Eksempel: Hentning af brugerdata fra en database


// pages/api/users/[id].js
import { query } from '../../../lib/db';

export default async function handler(req, res) {
  const { id } = req.query;

  try {
    const results = await query(
      'SELECT * FROM users WHERE id = ?',
      [id]
    );

    if (results.length === 0) {
      return res.status(404).json({ message: 'User not found' });
    }

    res.status(200).json(results[0]);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Internal Server Error' });
  }
}

Dette eksempel henter brugerdata fra en database baseret på det bruger-ID, der er angivet i URL'en. Det bruger et databaseforespørgselsbibliotek (antages at være i lib/db) til at interagere med databasen. Bemærk brugen af parametriserede forespørgsler for at forhindre SQL-injektionssårbarheder.

2. Godkendelse og autorisation

API-ruter kan bruges til at implementere godkendelses- og autorisationslogik. Du kan bruge dem til at verificere brugerlegitimationsoplysninger, generere JWT-tokens og beskytte følsomme ressourcer.

Eksempel: Brugergodkendelse


// pages/api/login.js
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { query } from '../../lib/db';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { email, password } = req.body;

    try {
      const results = await query(
        'SELECT * FROM users WHERE email = ?',
        [email]
      );

      if (results.length === 0) {
        return res.status(401).json({ message: 'Invalid credentials' });
      }

      const user = results[0];

      const passwordMatch = await bcrypt.compare(password, user.password);

      if (!passwordMatch) {
        return res.status(401).json({ message: 'Invalid credentials' });
      }

      const token = jwt.sign(
        { userId: user.id, email: user.email },
        process.env.JWT_SECRET,
        { expiresIn: '1h' }
      );

      res.status(200).json({ token });
    } catch (error) {
      console.error(error);
      res.status(500).json({ message: 'Internal Server Error' });
    }
  } else {
    res.status(405).json({ message: 'Method Not Allowed' });
  }
}

Dette eksempel godkender brugere ved at sammenligne den angivne adgangskode med den lagrede hashede adgangskode i databasen. Hvis legitimationsoplysningerne er gyldige, genererer den et JWT-token og returnerer det til klienten. Klienten kan derefter bruge dette token til at godkende efterfølgende anmodninger.

3. Formularhåndtering og dataindsendelse

API-ruter kan bruges til at håndtere formularindsendelser og behandle data, der sendes fra klienten. Dette er nyttigt til at oprette kontaktformularer, registreringsformularer og andre interaktive elementer.

Eksempel: Indsendelse af kontaktformular


// pages/api/contact.js
import { sendEmail } from '../../lib/email';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email, message } = req.body;

    try {
      await sendEmail({
        to: 'admin@example.com',
        subject: 'New Contact Form Submission',
        text: `Name: ${name}\nEmail: ${email}\nMessage: ${message}`,
      });

      res.status(200).json({ message: 'Email sent successfully' });
    } catch (error) {
      console.error(error);
      res.status(500).json({ message: 'Failed to send email' });
    }
  } else {
    res.status(405).json({ message: 'Method Not Allowed' });
  }
}

Dette eksempel håndterer en kontaktformularindsendelse ved at sende en e-mail til administratoren. Det bruger et e-mail-afsendelsesbibliotek (antages at være i lib/email) til at sende e-mailen. Du bør erstatte admin@example.com med den faktiske modtagers e-mailadresse.

4. Webhooks og hændelseshåndtering

API-ruter kan bruges til at håndtere webhooks og reagere på hændelser fra eksterne tjenester. Dette giver dig mulighed for at integrere din Next.js-applikation med andre platforme og automatisere opgaver.

Eksempel: Håndtering af en Stripe Webhook


// pages/api/stripe-webhook.js
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

export const config = {
  api: {
    bodyParser: false, // Disable default body parsing
  },
};

async function buffer(req) {
  const chunks = [];
  for await (const chunk of req) {
    chunks.push(chunk);
  }
  return Buffer.concat(chunks).toString();
}

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const sig = req.headers['stripe-signature'];

    let event;

    try {
      const buf = await buffer(req);
      event = stripe.webhooks.constructEvent(buf, sig, process.env.STRIPE_WEBHOOK_SECRET);
    } catch (err) {
      console.log(`Webhook Error: ${err.message}`);
      res.status(400).send(`Webhook Error: ${err.message}`);
      return;
    }

    // Handle the event
    switch (event.type) {
      case 'payment_intent.succeeded':
        const paymentIntent = event.data.object;
        console.log(`PaymentIntent for ${paymentIntent.amount} was successful!`);
        // Then define and call a method to handle the successful payment intent.
        // handlePaymentIntentSucceeded(paymentIntent);
        break;
      case 'payment_method.attached':
        const paymentMethod = event.data.object;
        // Then define and call a method to handle the successful attachment of a PaymentMethod.
        // handlePaymentMethodAttached(paymentMethod);
        break;
      default:
        // Unexpected event type
        console.log(`Unhandled event type ${event.type}.`);
    }

    // Return a 200 response to acknowledge receipt of the event
    res.status(200).json({ received: true });
  } else {
    res.setHeader('Allow', 'POST');
    res.status(405).end('Method Not Allowed');
  }
}

Dette eksempel håndterer en Stripe-webhook ved at verificere signaturen og behandle hændelsesdataene. Det deaktiverer standard body parser og bruger en brugerdefineret bufferfunktion til at læse den rå anmodningskrop. Det er afgørende at deaktivere standard body parser, fordi Stripe kræver den rå krop til signaturverifikation. Husk at konfigurere dit Stripe webhook-endepunkt i dit Stripe-dashboard og indstille miljøvariablen STRIPE_WEBHOOK_SECRET.

Bedste praksisser for API-ruter

For at sikre kvaliteten og vedligeholdeligheden af dine API-ruter skal du følge disse bedste praksisser:

1. Modulariser din kode

Undgå at skrive store, monolitiske API-ruter. Opdel i stedet din kode i mindre, genanvendelige moduler. Dette gør din kode lettere at forstå, teste og vedligeholde.

2. Implementer fejlhåndtering

Håndter fejl korrekt i dine API-ruter. Brug try...catch-blokke til at fange undtagelser og returnere passende fejlsvar til klienten. Log fejl for at hjælpe med fejlfinding og overvågning.

3. Valider inputdata

Valider altid inputdata fra klienten for at forhindre sikkerhedssårbarheder og sikre dataintegritet. Brug valideringsbiblioteker som Joi eller Yup til at definere valideringsskemaer og håndhæve databegrænsninger.

4. Beskyt følsomme data

Gem følsomme data, såsom API-nøgler og databasers legitimationsoplysninger, i miljøvariabler. Commit aldrig følsomme data til dit koderepository.

5. Implementer ratbegrænsning

Beskyt dine API-ruter mod misbrug ved at implementere ratbegrænsning. Dette begrænser antallet af anmodninger, som en klient kan foretage inden for en given periode. Brug ratbegrænsningsbiblioteker som express-rate-limit eller limiter.

6. Sikre API-nøgler

Eksponer ikke API-nøgler direkte i klient-side kode. Proxy altid anmodninger gennem dine API-ruter for at beskytte dine API-nøgler mod uautoriseret adgang. Gem API-nøgler sikkert i miljøvariabler på din server.

7. Brug miljøvariabler

Undgå at hårdkode konfigurationsværdier i din kode. Brug i stedet miljøvariabler til at gemme konfigurationsindstillinger. Dette gør det lettere at administrere din applikation i forskellige miljøer (udvikling, staging, produktion).

8. Logføring og overvågning

Implementer logføring og overvågning for at spore ydeevnen af dine API-ruter. Log vigtige hændelser, såsom fejl, advarsler og vellykkede anmodninger. Brug overvågningsværktøjer til at spore metrikker som anmodningsforsinkelse, fejlfrekvenser og ressourcebrug. Tjenester som Sentry, Datadog eller New Relic kan være nyttige.

Implementeringshensyn

Next.js API-ruter er designet til at blive implementeret på serverløse platforme. Populære implementeringsmuligheder inkluderer:

Når du implementerer din Next.js-applikation med API-ruter, skal du sikre dig, at dine miljøvariabler er korrekt konfigureret på implementeringsplatformen. Overvej også koldstarttiden for serverløse funktioner, som kan påvirke den indledende svartid for dine API-ruter. Optimering af din kode og brug af teknikker som provisioneret samtidighed kan hjælpe med at afbøde problemer med koldstart.

Konklusion

Next.js API-ruter giver en kraftfuld og praktisk måde at bygge full-stack applikationer med React. Ved at udnytte serverløse funktioner kan du forenkle udviklingen, reducere driftsomkostningerne og forbedre applikationsydelsen. Ved at følge de bedste praksisser, der er beskrevet i denne artikel, kan du oprette robuste og vedligeholdelige API-ruter, der driver dine Next.js-applikationer.

Uanset om du bygger en simpel kontaktformular eller en kompleks e-handelsplatform, kan Next.js API-ruter hjælpe dig med at strømline din udviklingsproces og levere enestående brugeroplevelser.

Yderligere læring

Next.js API-ruter: Full-Stack Udviklingsmønstre | MLOG