Norsk

Utforsk Next.js API-ruter og lås opp full-stack utviklingsmuligheter i dine React-applikasjoner. Lær mønstre, beste praksis og utrulleringsstrategier.

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

Next.js har revolusjonert React-utvikling ved å tilby et robust rammeverk for å bygge performante og skalerbare webapplikasjoner. En av dens viktigste funksjoner er API-ruter, som lar utviklere lage backend-funksjonalitet direkte i sine Next.js-prosjekter. Denne tilnærmingen effektiviserer utviklingen, forenkler utrullingen og låser opp kraftige full-stack-muligheter.

Hva er Next.js API-ruter?

Next.js API-ruter er serverløse funksjoner skrevet direkte i din /pages/api-katalog. Hver fil i denne katalogen blir et API-endepunkt, som automatisk ruter HTTP-forespørsler til den tilhørende funksjonen. Dette eliminerer behovet for en separat backend-server, forenkler applikasjonsarkitekturen din og reduserer driftskostnadene.

Tenk på dem som miniatyr-serverløse funksjoner som bor inne i Next.js-appen din. De svarer på HTTP-forespørsler som GET, POST, PUT, DELETE, og kan samhandle med databaser, eksterne APIer og andre server-side ressurser. Avgjørende er at de bare kjører på serveren, ikke i brukerens nettleser, og sikrer sikkerheten til sensitive data som API-nøkler.

Viktige fordeler med API-ruter

Komme i gang med API-ruter

Det er enkelt å opprette en API-rute i Next.js. Bare opprett en ny fil i /pages/api-katalogen. Filnavnet vil bestemme rutens sti. For eksempel vil oppretting av en fil kalt /pages/api/hello.js opprette et API-endepunkt som er tilgjengelig på /api/hello.

Eksempel: En enkel hilsen-API

Her er et grunnleggende eksempel på en API-rute som 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 koden definerer en asynkron funksjon handler som mottar to argumenter:

Funksjonen setter HTTP-statuskoden til 200 (OK) og returnerer et JSON-svar med en melding.

Håndtere forskjellige HTTP-metoder

Du kan håndtere forskjellige HTTP-metoder (GET, POST, PUT, DELETE, osv.) i din API-rute ved å sjekke req.method-egenskapen. Dette lar deg enkelt lage RESTful APIer.


// 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 eksemplet demonstrerer hvordan du håndterer GET- og POST-forespørsler for et hypotetisk /api/todos-endepunkt. Det inkluderer også feilhåndtering for metoder som ikke støttes.

Full-Stack Utviklingsmønstre med API-ruter

Next.js API-ruter muliggjør forskjellige full-stack utviklingsmønstre. Her er noen vanlige bruksområder:

1. Datahenting og -manipulering

API-ruter kan brukes til å hente data fra databaser, eksterne APIer eller andre datakilder. De kan også brukes til å manipulere data, for eksempel å opprette, oppdatere eller slette poster.

Eksempel: Hente brukerdata 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 eksemplet henter brukerdata fra en database basert på bruker-IDen som er oppgitt i URLen. Den bruker et database-spørringsbibliotek (antas å være i lib/db) for å samhandle med databasen. Legg merke til bruken av parametriserte spørringer for å forhindre SQL-injeksjonssårbarheter.

2. Autentisering og autorisasjon

API-ruter kan brukes til å implementere autentiserings- og autorisasjonslogikk. Du kan bruke dem til å bekrefte brukerlegitimasjon, generere JWT-tokens og beskytte sensitive ressurser.

Eksempel: Brukerautentisering


// 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 eksemplet autentiserer brukere ved å sammenligne det oppgitte passordet med det lagrede hashede passordet i databasen. Hvis legitimasjonen er gyldig, genererer den en JWT-token og returnerer den til klienten. Klienten kan deretter bruke denne tokenen til å autentisere påfølgende forespørsler.

3. Skjemahåndtering og datainnsending

API-ruter kan brukes til å håndtere skjema-innsendinger og behandle data sendt fra klienten. Dette er nyttig for å opprette kontaktskjemaer, registreringsskjemaer og andre interaktive elementer.

Eksempel: Kontaktskjema-innsending


// 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 eksemplet håndterer en kontaktskjema-innsending ved å sende en e-post til administratoren. Den bruker et e-postsendingsbibliotek (antas å være i lib/email) for å sende e-posten. Du bør erstatte admin@example.com med den faktiske mottakerens e-postadresse.

4. Webhooks og hendelseshåndtering

API-ruter kan brukes til å håndtere webhooks og svare på hendelser fra eksterne tjenester. Dette lar deg integrere Next.js-applikasjonen din med andre plattformer og automatisere oppgaver.

Eksempel: Håndtere 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 eksemplet håndterer en Stripe webhook ved å verifisere signaturen og behandle hendelsesdataene. Den deaktiverer standard body parser og bruker en tilpasset bufferfunksjon for å lese den rå forespørselsbodyen. Det er avgjørende å deaktivere standard body parser fordi Stripe krever den rå bodyen for signaturverifisering. Husk å konfigurere Stripe webhook-endepunktet i Stripe-dashbordet ditt og angi STRIPE_WEBHOOK_SECRET-miljøvariabelen.

Beste praksis for API-ruter

For å sikre kvaliteten og vedlikeholdbarheten til API-rutene dine, følg disse beste praksisene:

1. Modulariser koden din

Unngå å skrive store, monolittiske API-ruter. Bryt i stedet ned koden din i mindre, gjenbrukbare moduler. Dette gjør koden din lettere å forstå, teste og vedlikeholde.

2. Implementer feilhåndtering

Håndter feil på riktig måte i API-rutene dine. Bruk try...catch-blokker for å fange unntak og returnere passende feilmeldinger til klienten. Logg feil for å hjelpe med feilsøking og overvåking.

3. Valider inndata

Valider alltid inndata fra klienten for å forhindre sikkerhetssårbarheter og sikre dataintegritet. Bruk valideringsbiblioteker som Joi eller Yup til å definere valideringsskjemaer og håndheve databegrensninger.

4. Beskytt sensitive data

Lagre sensitive data, som API-nøkler og databaselegitimasjon, i miljøvariabler. Ikke begå sensitive data til kodelageret ditt.

5. Implementer hastighetsbegrensning

Beskytt API-rutene dine mot misbruk ved å implementere hastighetsbegrensning. Dette begrenser antall forespørsler en klient kan gjøre i løpet av en gitt tidsperiode. Bruk hastighetsbegrensningsbiblioteker som express-rate-limit eller limiter.

6. Sikre API-nøkler

Ikke avslør API-nøkler direkte i klient-side-kode. Proxy alltid forespørsler gjennom API-rutene dine for å beskytte API-nøklene dine mot uautorisert tilgang. Lagre API-nøkler sikkert i miljøvariabler på serveren din.

7. Bruk miljøvariabler

Unngå å hardkode konfigurasjonsverdier i koden din. Bruk i stedet miljøvariabler for å lagre konfigurasjonsinnstillinger. Dette gjør det enklere å administrere applikasjonen din i forskjellige miljøer (utvikling, testing, produksjon).

8. Logging og overvåking

Implementer logging og overvåking for å spore ytelsen til API-rutene dine. Logg viktige hendelser, som feil, advarsler og vellykkede forespørsler. Bruk overvåkingsverktøy for å spore beregninger som forespørselsforsinkelse, feilrater og ressursbruk. Tjenester som Sentry, Datadog eller New Relic kan være nyttige.

Utrullingshensyn

Next.js API-ruter er designet for å rulles ut på serverløse plattformer. Populære utrullingsalternativer inkluderer:

Når du ruller ut Next.js-applikasjonen din med API-ruter, må du sørge for at miljøvariablene dine er riktig konfigurert på utrullingsplattformen. Vurder også kaldstarttiden for serverløse funksjoner, som kan påvirke den første responstiden til API-rutene dine. Optimalisering av koden din og bruk av teknikker som klargjort samtidighet kan bidra til å redusere problemer med kaldstart.

Konklusjon

Next.js API-ruter gir en kraftig og praktisk måte å bygge full-stack-applikasjoner med React. Ved å utnytte serverløse funksjoner kan du forenkle utviklingen, redusere driftskostnadene og forbedre applikasjonsytelsen. Ved å følge beste praksisene som er beskrevet i denne artikkelen, kan du opprette robuste og vedlikeholdbare API-ruter som driver Next.js-applikasjonene dine.

Enten du bygger et enkelt kontaktskjema eller en kompleks e-handelsplattform, kan Next.js API-ruter hjelpe deg med å effektivisere utviklingsprosessen og levere eksepsjonelle brukeropplevelser.

Videre læring