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
- Forenklet udvikling: Skriv både frontend- og backend-kode inden for det samme projekt.
- Serverløs arkitektur: Udnyt serverløse funktioner for skalerbarhed og omkostningseffektivitet.
- Nem implementering: Implementer din frontend og backend sammen med en enkelt kommando.
- Forbedret ydeevne: Server-side rendering og datahentningsfunktioner forbedrer applikationshastigheden.
- Forbedret sikkerhed: Følsomme data forbliver på serveren, beskyttet mod eksponering på klientsiden.
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:
req
: En instans afhttp.IncomingMessage
plus nogle forudbyggede middlewares.res
: En instans afhttp.ServerResponse
plus nogle hjælpefunktioner.
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:
- Vercel: Vercel er den anbefalede platform til implementering af Next.js-applikationer. Det giver problemfri integration med Next.js og optimerer automatisk din applikation til ydeevne.
- Netlify: Netlify er en anden populær serverløs platform, der understøtter Next.js-implementeringer. Det tilbyder lignende funktioner som Vercel, såsom automatiske implementeringer og CDN-integration.
- AWS Lambda: AWS Lambda er en serverløs computer service, der giver dig mulighed for at køre kode uden at provisionere eller administrere servere. Du kan implementere dine Next.js API-ruter som Lambda-funktioner ved hjælp af værktøjer som Serverless Framework eller AWS SAM.
- Google Cloud Functions: Google Cloud Functions er et serverløst udførelsesmiljø, der lader dig oprette og forbinde cloudtjenester. Du kan implementere dine Next.js API-ruter som Cloud Functions ved hjælp af værktøjer som Firebase CLI eller Google Cloud SDK.
- Azure Functions: Azure Functions er en serverløs computer service, der giver dig mulighed for at køre kode on-demand uden at administrere infrastruktur. Du kan implementere dine Next.js API-ruter som Azure Functions ved hjælp af værktøjer som Azure Functions Core Tools eller Azure CLI.
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.