Ištyrinėkite Next.js API maršrutus ir atverkite „full-stack“ kūrimo galimybes savo React programose. Sužinokite apie modelius, geriausias praktikas ir diegimo strategijas.
Next.js API maršrutai: „Full-Stack“ kūrimo modeliai
Next.js sukėlė revoliuciją React kūrime, pateikdamas tvirtą karkasą našoms ir plečiamoms interneto programoms kurti. Viena iš pagrindinių jo funkcijų yra API maršrutai (API Routes), kurie leidžia programuotojams kurti backend funkcionalumą tiesiogiai savo Next.js projektuose. Šis požiūris supaprastina kūrimą, diegimą ir atveria galingas „full-stack“ galimybes.
Kas yra Next.js API maršrutai?
Next.js API maršrutai yra be serverio (serverless) funkcijos, rašomos tiesiogiai jūsų /pages/api
kataloge. Kiekvienas failas šiame kataloge tampa API galiniu tašku (endpoint), automatiškai nukreipiančiu HTTP užklausas į atitinkamą funkciją. Tai pašalina poreikį turėti atskirą backend serverį, supaprastina jūsų programos architektūrą ir sumažina operacines išlaidas.
Įsivaizduokite juos kaip miniatiūrines be serverio funkcijas, kurios gyvena jūsų Next.js programoje. Jos atsako į HTTP užklausas, tokias kaip GET, POST, PUT, DELETE, ir gali sąveikauti su duomenų bazėmis, išorinėmis API ir kitais serverio pusės resursais. Svarbiausia, kad jos veikia tik serveryje, o ne vartotojo naršyklėje, taip užtikrinant jautrių duomenų, pavyzdžiui, API raktų, saugumą.
Pagrindiniai API maršrutų privalumai
- Supaprastintas kūrimas: Rašykite tiek frontend, tiek backend kodą tame pačiame projekte.
- Be serverio architektūra: Išnaudokite be serverio funkcijų teikiamą mastelį ir ekonomiškumą.
- Lengvas diegimas: Įdiekite savo frontend ir backend kartu viena komanda.
- Pagerintas našumas: Serverio pusės generavimas ir duomenų gavimo galimybės padidina programos greitį.
- Padidintas saugumas: Jautrūs duomenys lieka serveryje, apsaugoti nuo atskleidimo kliento pusėje.
Darbo su API maršrutais pradžia
Sukurti API maršrutą Next.js yra paprasta. Tiesiog sukurkite naują failą /pages/api
kataloge. Failo pavadinimas nulems maršruto kelią. Pavyzdžiui, sukūrus failą pavadinimu /pages/api/hello.js
, bus sukurtas API galinis taškas, pasiekiamas adresu /api/hello
.
Pavyzdys: paprastas pasisveikinimo API
Štai pagrindinis API maršruto pavyzdys, kuris grąžina JSON atsakymą:
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Sveiki iš Next.js API maršruto!' });
}
Šis kodas apibrėžia asinchroninę funkciją handler
, kuri gauna du argumentus:
req
:http.IncomingMessage
egzempliorius su keliais iš anksto paruoštais tarpiniais sluoksniais (middlewares).res
:http.ServerResponse
egzempliorius su keliomis pagalbinėmis funkcijomis.
Funkcija nustato HTTP būsenos kodą į 200 (OK) ir grąžina JSON atsakymą su pranešimu.
Skirtingų HTTP metodų apdorojimas
Galite apdoroti skirtingus HTTP metodus (GET, POST, PUT, DELETE ir kt.) savo API maršrute, tikrindami req.method
savybę. Tai leidžia lengvai kurti RESTful API.
// pages/api/todos.js
export default async function handler(req, res) {
if (req.method === 'GET') {
// Gauname visus darbus (todos) iš duomenų bazės
const todos = await fetchTodos();
res.status(200).json(todos);
} else if (req.method === 'POST') {
// Sukuriame naują darbą (todo)
const newTodo = await createTodo(req.body);
res.status(201).json(newTodo);
} else {
// Apdorojame nepalaikomus metodus
res.status(405).json({ message: 'Metodas neleidžiamas' });
}
}
Šis pavyzdys demonstruoja, kaip apdoroti GET ir POST užklausas hipotetiniam /api/todos
galiniam taškui. Jame taip pat yra klaidų apdorojimas nepalaikomiems metodams.
„Full-Stack“ kūrimo modeliai su API maršrutais
Next.js API maršrutai įgalina įvairius „full-stack“ kūrimo modelius. Štai keletas dažniausiai pasitaikančių naudojimo atvejų:
1. Duomenų gavimas ir manipuliavimas
API maršrutai gali būti naudojami duomenims gauti iš duomenų bazių, išorinių API ar kitų duomenų šaltinių. Jie taip pat gali būti naudojami duomenims manipuliuoti, pavyzdžiui, kurti, atnaujinti ar trinti įrašus.
Pavyzdys: Vartotojo duomenų gavimas iš duomenų bazės
// 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: 'Vartotojas nerastas' });
}
res.status(200).json(results[0]);
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Vidinė serverio klaida' });
}
}
Šis pavyzdys gauna vartotojo duomenis iš duomenų bazės pagal URL nurodytą vartotojo ID. Jis naudoja duomenų bazės užklausų biblioteką (darant prielaidą, kad ji yra lib/db
), kad sąveikautų su duomenų baze. Atkreipkite dėmesį į parametrizuotų užklausų naudojimą, siekiant išvengti SQL injekcijos pažeidžiamumų.
2. Autentifikacija ir autorizacija
API maršrutai gali būti naudojami autentifikacijos ir autorizacijos logikai įgyvendinti. Juos galite naudoti vartotojo prisijungimo duomenims patikrinti, JWT prieigos raktams (tokens) generuoti ir jautriems resursams apsaugoti.
Pavyzdys: Vartotojo autentifikacija
// 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: 'Neteisingi prisijungimo duomenys' });
}
const user = results[0];
const passwordMatch = await bcrypt.compare(password, user.password);
if (!passwordMatch) {
return res.status(401).json({ message: 'Neteisingi prisijungimo duomenys' });
}
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: 'Vidinė serverio klaida' });
}
} else {
res.status(405).json({ message: 'Metodas neleidžiamas' });
}
}
Šis pavyzdys autentifikuoja vartotojus, palygindamas pateiktą slaptažodį su duomenų bazėje saugomu maišos (hashed) slaptažodžiu. Jei prisijungimo duomenys yra teisingi, jis sugeneruoja JWT prieigos raktą ir grąžina jį klientui. Klientas gali naudoti šį raktą vėlesnėms užklausoms autentifikuoti.
3. Formų apdorojimas ir duomenų pateikimas
API maršrutai gali būti naudojami formų pateikimams apdoroti ir iš kliento siunčiamiems duomenims tvarkyti. Tai naudinga kuriant kontaktų formas, registracijos formas ir kitus interaktyvius elementus.
Pavyzdys: Kontaktų formos pateikimas
// 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: 'Naujas pranešimas iš kontaktų formos',
text: `Vardas: ${name}\nEl. paštas: ${email}\nŽinutė: ${message}`,
});
res.status(200).json({ message: 'El. laiškas sėkmingai išsiųstas' });
} catch (error) {
console.error(error);
res.status(500).json({ message: 'Nepavyko išsiųsti el. laiško' });
}
} else {
res.status(405).json({ message: 'Metodas neleidžiamas' });
}
}
Šis pavyzdys apdoroja kontaktų formos pateikimą, siųsdamas el. laišką administratoriui. Jis naudoja el. laiškų siuntimo biblioteką (darant prielaidą, kad ji yra lib/email
) laiškui išsiųsti. Turėtumėte pakeisti admin@example.com
tikruoju gavėjo el. pašto adresu.
4. „Webhook'ų“ ir įvykių apdorojimas
API maršrutai gali būti naudojami „webhook'ams“ apdoroti ir reaguoti į įvykius iš išorinių paslaugų. Tai leidžia integruoti jūsų Next.js programą su kitomis platformomis ir automatizuoti užduotis.
Pavyzdys: Stripe „webhook'o“ apdorojimas
// pages/api/stripe-webhook.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
export const config = {
api: {
bodyParser: false, // Išjungiame numatytąjį turinio analizavimą
},
};
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 klaida: ${err.message}`);
res.status(400).send(`Webhook klaida: ${err.message}`);
return;
}
// Apdorojame įvykį
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log(`Mokėjimo ketinimas ${paymentIntent.amount} sumai buvo sėkmingas!`);
// Tada apibrėžkite ir iškvieskite metodą, skirtą sėkmingam mokėjimo ketinimui apdoroti.
// handlePaymentIntentSucceeded(paymentIntent);
break;
case 'payment_method.attached':
const paymentMethod = event.data.object;
// Tada apibrėžkite ir iškvieskite metodą, skirtą sėkmingam mokėjimo metodo pridėjimui apdoroti.
// handlePaymentMethodAttached(paymentMethod);
break;
default:
// Netikėtas įvykio tipas
console.log(`Neapdorotas įvykio tipas ${event.type}.`);
}
// Grąžiname 200 atsakymą, kad patvirtintume įvykio gavimą
res.status(200).json({ received: true });
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Metodas neleidžiamas');
}
}
Šis pavyzdys apdoroja Stripe „webhook'ą“, patikrindamas parašą ir apdorodamas įvykio duomenis. Jis išjungia numatytąjį turinio analizatorių (body parser) ir naudoja pasirinktinę buferio funkciją, kad nuskaitytų neapdorotą užklausos turinį. Būtina išjungti numatytąjį turinio analizatorių, nes Stripe reikalauja neapdoroto turinio parašo patikrinimui. Nepamirškite sukonfigūruoti savo Stripe „webhook'o“ galinio taško savo Stripe prietaisų skydelyje ir nustatyti STRIPE_WEBHOOK_SECRET
aplinkos kintamąjį.
Geriausios API maršrutų praktikos
Siekdami užtikrinti savo API maršrutų kokybę ir palaikomumą, laikykitės šių geriausių praktikų:
1. Moduliarizuokite savo kodą
Venkite rašyti didelių, monolitinių API maršrutų. Vietoj to, suskaidykite savo kodą į mažesnius, pakartotinai naudojamus modulius. Tai padaro jūsų kodą lengviau suprantamą, testuojamą ir palaikomą.
2. Įgyvendinkite klaidų apdorojimą
Tinkamai apdorokite klaidas savo API maršrutuose. Naudokite try...catch
blokus išimtims gaudyti ir grąžinkite atitinkamus klaidų atsakymus klientui. Registruokite klaidas, kad padėtumėte derinti ir stebėti.
3. Tikrinkite įvesties duomenis
Visada tikrinkite iš kliento gaunamus įvesties duomenis, kad išvengtumėte saugumo pažeidžiamumų ir užtikrintumėte duomenų vientisumą. Naudokite tikrinimo bibliotekas, tokias kaip Joi ar Yup, kad apibrėžtumėte tikrinimo schemas ir įgyvendintumėte duomenų apribojimus.
4. Apsaugokite jautrius duomenis
Saugokite jautrius duomenis, tokius kaip API raktai ir duomenų bazės prisijungimo duomenys, aplinkos kintamuosiuose. Niekada neįtraukite jautrių duomenų į savo kodo saugyklą.
5. Įgyvendinkite užklausų ribojimą
Apsaugokite savo API maršrutus nuo piktnaudžiavimo įgyvendindami užklausų ribojimą (rate limiting). Tai apriboja užklausų, kurias klientas gali atlikti per tam tikrą laikotarpį, skaičių. Naudokite užklausų ribojimo bibliotekas, tokias kaip express-rate-limit
ar limiter
.
6. Saugokite API raktus
Neatskleiskite API raktų tiesiogiai kliento pusės kode. Visada nukreipkite užklausas per savo API maršrutus, kad apsaugotumėte savo API raktus nuo neteisėtos prieigos. Saugokite API raktus saugiai aplinkos kintamuosiuose savo serveryje.
7. Naudokite aplinkos kintamuosius
Venkite kietai koduoti konfigūracijos vertes savo kode. Vietoj to, naudokite aplinkos kintamuosius konfigūracijos nustatymams saugoti. Tai palengvina jūsų programos valdymą skirtingose aplinkose (kūrimo, testavimo, produkcijos).
8. Registravimas ir stebėjimas
Įgyvendinkite registravimą (logging) ir stebėjimą (monitoring), kad sektumėte savo API maršrutų našumą. Registruokite svarbius įvykius, tokius kaip klaidos, įspėjimai ir sėkmingos užklausos. Naudokite stebėjimo įrankius metrikoms, tokioms kaip užklausos vėlavimas, klaidų dažnis ir resursų naudojimas, sekti. Paslaugos kaip Sentry, Datadog ar New Relic gali būti naudingos.
Diegimo aspektai
Next.js API maršrutai yra sukurti diegti be serverio platformose. Populiarios diegimo parinktys apima:
- Vercel: Vercel yra rekomenduojama platforma Next.js programoms diegti. Ji užtikrina sklandžią integraciją su Next.js ir automatiškai optimizuoja jūsų programos našumą.
- Netlify: Netlify yra kita populiari be serverio platforma, palaikanti Next.js diegimus. Ji siūlo panašias funkcijas kaip Vercel, tokias kaip automatiniai diegimai ir CDN integracija.
- AWS Lambda: AWS Lambda yra be serverio skaičiavimo paslauga, leidžianti paleisti kodą nepateikiant ir nevaldant serverių. Galite įdiegti savo Next.js API maršrutus kaip Lambda funkcijas, naudodami įrankius, tokius kaip Serverless Framework ar AWS SAM.
- Google Cloud Functions: Google Cloud Functions yra be serverio vykdymo aplinka, leidžianti kurti ir jungti debesijos paslaugas. Galite įdiegti savo Next.js API maršrutus kaip Cloud Functions, naudodami įrankius, tokius kaip Firebase CLI ar Google Cloud SDK.
- Azure Functions: Azure Functions yra be serverio skaičiavimo paslauga, leidžianti paleisti kodą pagal poreikį nevaldant infrastruktūros. Galite įdiegti savo Next.js API maršrutus kaip Azure Functions, naudodami įrankius, tokius kaip Azure Functions Core Tools ar Azure CLI.
Diegdami savo Next.js programą su API maršrutais, įsitikinkite, kad jūsų aplinkos kintamieji yra tinkamai sukonfigūruoti diegimo platformoje. Taip pat atsižvelkite į be serverio funkcijų „šaltojo starto“ (cold start) laiką, kuris gali paveikti pradinį jūsų API maršrutų atsako laiką. Kodo optimizavimas ir technikų, tokių kaip „provisioned concurrency“, naudojimas gali padėti sušvelninti „šaltojo starto“ problemas.
Išvada
Next.js API maršrutai suteikia galingą ir patogų būdą kurti „full-stack“ programas su React. Išnaudodami be serverio funkcijas, galite supaprastinti kūrimą, sumažinti operacines išlaidas ir pagerinti programos našumą. Laikydamiesi šiame straipsnyje aprašytų geriausių praktikų, galite sukurti tvirtus ir palaikomus API maršrutus, kurie maitins jūsų Next.js programas.
Nesvarbu, ar kuriate paprastą kontaktų formą, ar sudėtingą e. prekybos platformą, Next.js API maršrutai gali padėti supaprastinti jūsų kūrimo procesą ir suteikti išskirtinę vartotojo patirtį.