Ελληνικά

Μάθετε πώς να δημιουργείτε ισχυρά API endpoints χρησιμοποιώντας τα Next.js Route Handlers. Αυτός ο οδηγός καλύπτει τα πάντα, από τη βασική ρύθμιση έως τις προηγμένες τεχνικές, με πρακτικά παραδείγματα και βέλτιστες πρακτικές.

Next.js Route Handlers: Ένας Ολοκληρωμένος Οδηγός για τη Δημιουργία API Endpoints

Το Next.js έχει φέρει επανάσταση στον τρόπο που δημιουργούμε εφαρμογές web με τα ισχυρά χαρακτηριστικά του, όπως το server-side rendering, το static site generation και τώρα, τα Route Handlers. Τα Route Handlers παρέχουν έναν ευέλικτο και αποτελεσματικό τρόπο για τη δημιουργία API endpoints απευθείας μέσα στην εφαρμογή σας Next.js. Αυτός ο οδηγός εξερευνά την έννοια των Route Handlers, τα οφέλη τους και πώς να τα χρησιμοποιήσετε αποτελεσματικά για τη δημιουργία ισχυρών APIs.

Τι είναι τα Next.js Route Handlers;

Τα Route Handlers είναι συναρτήσεις που ορίζονται μέσα στον κατάλογο app ενός project Next.js και διαχειρίζονται τα εισερχόμενα αιτήματα HTTP. Σε αντίθεση με την παλαιότερη προσέγγιση pages/api (που χρησιμοποιεί API Routes), τα Route Handlers προσφέρουν έναν πιο απλοποιημένο και ευέλικτο τρόπο για τον ορισμό API endpoints δίπλα στα React components σας. Είναι ουσιαστικά serverless συναρτήσεις που εκτελούνται στο edge ή στο επιλεγμένο σας περιβάλλον server.

Σκεφτείτε τα Route Handlers ως τη λογική του backend της εφαρμογής σας Next.js, υπεύθυνα για την επεξεργασία αιτημάτων, την αλληλεπίδραση με βάσεις δεδομένων και την επιστροφή απαντήσεων.

Οφέλη από τη Χρήση των Route Handlers

Ρύθμιση του Project σας Next.js

Πριν ασχοληθείτε με τα Route Handlers, βεβαιωθείτε ότι έχετε ένα project Next.js ρυθμισμένο με τον κατάλογο app. Εάν ξεκινάτε ένα νέο project, χρησιμοποιήστε την ακόλουθη εντολή:

npx create-next-app@latest my-nextjs-app

Επιλέξτε τον κατάλογο app κατά τη διαδικασία ρύθμισης για να ενεργοποιήσετε το νέο σύστημα δρομολόγησης.

Δημιουργία του Πρώτου σας Route Handler

Ας δημιουργήσουμε ένα απλό API endpoint που επιστρέφει μια απάντηση JSON. Δημιουργήστε έναν νέο κατάλογο μέσα στον κατάλογο app, για παράδειγμα, /app/api/hello. Μέσα σε αυτόν τον κατάλογο, δημιουργήστε ένα αρχείο με το όνομα route.tsroute.js αν δεν χρησιμοποιείτε TypeScript).

Αυτός είναι ο κώδικας για το πρώτο σας Route Handler:

// app/api/hello/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from Next.js Route Handlers!' });
}

Εξήγηση:

Τώρα, μπορείτε να έχετε πρόσβαση σε αυτό το endpoint πλοηγούμενοι στο /api/hello στον browser σας ή χρησιμοποιώντας ένα εργαλείο όπως το curl ή το Postman.

Διαχείριση Διαφορετικών Μεθόδων HTTP

Τα Route Handlers υποστηρίζουν διάφορες μεθόδους HTTP όπως GET, POST, PUT, DELETE, PATCH, και OPTIONS. Μπορείτε να ορίσετε ξεχωριστές συναρτήσεις για κάθε μέθοδο μέσα στο ίδιο αρχείο route.ts.

// app/api/users/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Λογική για την ανάκτηση όλων των χρηστών από τη βάση δεδομένων
 const users = [{ id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }]; // Παράδειγμα δεδομένων
 return NextResponse.json(users);
}

export async function POST(request: Request) {
 const data = await request.json(); // Ανάλυση του σώματος του αιτήματος ως JSON
 // Λογική για τη δημιουργία ενός νέου χρήστη στη βάση δεδομένων χρησιμοποιώντας τα 'data'
 const newUser = { id: 3, name: data.name, email: data.email }; // Παράδειγμα
 return NextResponse.json(newUser, { status: 201 }); // Επιστροφή του νέου χρήστη με κωδικό κατάστασης 201 Created
}

Εξήγηση:

Πρόσβαση σε Δεδομένα Αιτήματος

Το αντικείμενο request παρέχει πρόσβαση σε διάφορες πληροφορίες σχετικά με το εισερχόμενο αίτημα, συμπεριλαμβανομένων των headers, των query parameters και του σώματος του αιτήματος.

Headers

Μπορείτε να έχετε πρόσβαση στα headers του αιτήματος χρησιμοποιώντας την ιδιότητα request.headers:

export async function GET(request: Request) {
 const userAgent = request.headers.get('user-agent');
 console.log('User Agent:', userAgent);
 return NextResponse.json({ userAgent });
}

Query Parameters

Για να έχετε πρόσβαση στα query parameters, μπορείτε να χρησιμοποιήσετε τον constructor URL:

export async function GET(request: Request) {
 const url = new URL(request.url);
 const searchParams = new URLSearchParams(url.search);
 const id = searchParams.get('id');
 console.log('ID:', id);
 return NextResponse.json({ id });
}

Σώμα Αιτήματος (Request Body)

Για αιτήματα POST, PUT και PATCH, μπορείτε να έχετε πρόσβαση στο σώμα του αιτήματος χρησιμοποιώντας τις μεθόδους request.json() ή request.text(), ανάλογα με τον τύπο περιεχομένου.

export async function POST(request: Request) {
 const data = await request.json();
 console.log('Data:', data);
 return NextResponse.json({ receivedData: data });
}

Επιστροφή Απαντήσεων

Το αντικείμενο NextResponse χρησιμοποιείται για την κατασκευή απαντήσεων API. Παρέχει διάφορες μεθόδους για τον ορισμό headers, κωδικών κατάστασης και του σώματος της απάντησης.

Απαντήσεις JSON

Χρησιμοποιήστε τη μέθοδο NextResponse.json() για να επιστρέψετε απαντήσεις JSON:

return NextResponse.json({ message: 'Success!', data: { name: 'John Doe' } }, { status: 200 });

Απαντήσεις Κειμένου (Text Responses)

Χρησιμοποιήστε τον constructor new Response() για να επιστρέψετε απαντήσεις απλού κειμένου:

return new Response('Hello, world!', { status: 200, headers: { 'Content-Type': 'text/plain' } });

Ανακατευθύνσεις (Redirects)

Χρησιμοποιήστε το NextResponse.redirect() για να ανακατευθύνετε τους χρήστες σε ένα διαφορετικό URL:

import { redirect } from 'next/navigation';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.redirect(new URL('/new-location', request.url));
}

Ορισμός Headers

Μπορείτε να ορίσετε προσαρμοσμένα headers χρησιμοποιώντας την επιλογή headers στο NextResponse.json() ή στο new Response():

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'no-cache' } });

Ενσωμάτωση Middleware

Το Middleware σας επιτρέπει να εκτελέσετε κώδικα πριν ένα αίτημα διαχειριστεί από το Route Handler σας. Αυτό είναι χρήσιμο για τον έλεγχο ταυτότητας, την εξουσιοδότηση, την καταγραφή (logging) και άλλες διαλειτουργικές ανησυχίες (cross-cutting concerns).

Για να δημιουργήσετε middleware, δημιουργήστε ένα αρχείο με το όνομα middleware.tsmiddleware.js) στον κατάλογο app ή σε οποιονδήποτε υποκατάλογο. Το middleware θα εφαρμοστεί σε όλες τις διαδρομές εντός αυτού του καταλόγου και των υποκαταλόγων του.

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/protected/:path*'], // Εφαρμογή αυτού του middleware σε διαδρομές που ξεκινούν με /protected/
};

Εξήγηση:

Διαχείριση Σφαλμάτων (Error Handling)

Η σωστή διαχείριση σφαλμάτων είναι κρίσιμη για τη δημιουργία ισχυρών APIs. Μπορείτε να χρησιμοποιήσετε μπλοκ try...catch για να διαχειριστείτε εξαιρέσεις και να επιστρέψετε κατάλληλες απαντήσεις σφάλματος.

export async function GET(request: Request) {
 try {
 // Προσομοίωση ενός σφάλματος
 throw new Error('Something went wrong!');
 } catch (error: any) {
 console.error('Error:', error);
 return NextResponse.json({ error: error.message }, { status: 500 });
 }
}

Εξήγηση:

Ροή Απαντήσεων (Streaming Responses)

Τα Route Handlers υποστηρίζουν απαντήσεις ροής (streaming), οι οποίες σας επιτρέπουν να στέλνετε δεδομένα σταδιακά στον client. Αυτό είναι ιδιαίτερα χρήσιμο για μεγάλα σύνολα δεδομένων ή διεργασίες που διαρκούν πολύ.

import { Readable } from 'stream';
import { NextResponse } from 'next/server';

async function* generateData() {
 for (let i = 0; i < 10; i++) {
 await new Promise(resolve => setTimeout(resolve, 500)); // Προσομοίωση καθυστέρησης
 yield `Data chunk ${i}\n`;
 }
}

export async function GET(request: Request) {
 const readableStream = Readable.from(generateData());

 return new Response(readableStream, {
 headers: { 'Content-Type': 'text/plain; charset=utf-8' },
 });
}

Εξήγηση:

Έλεγχος Ταυτότητας και Εξουσιοδότηση

Η ασφάλεια των API endpoints σας είναι κρίσιμη. Μπορείτε να υλοποιήσετε έλεγχο ταυτότητας και εξουσιοδότηση χρησιμοποιώντας middleware ή απευθείας μέσα στα Route Handlers σας.

Έλεγχος Ταυτότητας (Authentication)

Ο έλεγχος ταυτότητας επαληθεύει την ταυτότητα του χρήστη που κάνει το αίτημα. Οι συνήθεις μέθοδοι ελέγχου ταυτότητας περιλαμβάνουν:

Ακολουθεί ένα παράδειγμα ελέγχου ταυτότητας JWT με χρήση middleware:

// app/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import jwt from 'jsonwebtoken';

const secret = process.env.JWT_SECRET || 'your-secret-key'; // Αντικαταστήστε με ένα ισχυρό, τυχαία παραγόμενο μυστικό

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth-token')?.value;

 if (!token) {
 return NextResponse.json({ message: 'Authentication required' }, { status: 401 });
 }

 try {
 jwt.verify(token, secret);
 return NextResponse.next();
 } catch (error) {
 return NextResponse.json({ message: 'Invalid token' }, { status: 401 });
 }
}

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

Εξουσιοδότηση (Authorization)

Η εξουσιοδότηση καθορίζει σε ποιους πόρους επιτρέπεται η πρόσβαση ενός χρήστη. Αυτό συνήθως βασίζεται σε ρόλους ή δικαιώματα.

Μπορείτε να υλοποιήσετε εξουσιοδότηση μέσα στα Route Handlers σας ελέγχοντας τους ρόλους ή τα δικαιώματα του χρήστη και επιστρέφοντας ένα σφάλμα εάν δεν έχουν πρόσβαση.

// app/api/admin/route.ts
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 // Υποθέστε ότι έχετε μια συνάρτηση για να πάρετε τον ρόλο του χρήστη από το token ή τη συνεδρία
 const userRole = await getUserRole(request);

 if (userRole !== 'admin') {
 return NextResponse.json({ message: 'Unauthorized' }, { status: 403 });
 }

 // Λογική για την ανάκτηση δεδομένων διαχειριστή
 const adminData = { message: 'Admin data' };
 return NextResponse.json(adminData);
}

async function getUserRole(request: Request): Promise {
 // Αντικαταστήστε με την πραγματική σας λογική για την εξαγωγή του ρόλου του χρήστη από το αίτημα
 // Αυτό θα μπορούσε να περιλαμβάνει την επαλήθευση ενός JWT token ή τον έλεγχο μιας συνεδρίας
 return 'admin'; // Παράδειγμα: σκληρά κωδικοποιημένος ρόλος για επίδειξη
}

Ανάπτυξη των Route Handlers

Τα Route Handlers αναπτύσσονται ως serverless συναρτήσεις στον επιλεγμένο σας πάροχο φιλοξενίας. Το Next.js υποστηρίζει διάφορες πλατφόρμες ανάπτυξης, όπως Vercel, Netlify, AWS και άλλες.

Για το Vercel, η ανάπτυξη είναι τόσο απλή όσο η σύνδεση του Git repository σας με το Vercel και το push του κώδικά σας. Το Vercel ανιχνεύει αυτόματα το project σας Next.js και αναπτύσσει τα Route Handlers σας ως serverless συναρτήσεις.

Προηγμένες Τεχνικές

Edge Functions

Τα Route Handlers μπορούν να αναπτυχθούν ως Edge Functions, οι οποίες εκτελούνται στο άκρο (edge) ενός CDN, πιο κοντά στους χρήστες σας. Αυτό μπορεί να μειώσει σημαντικά την καθυστέρηση και να βελτιώσει την απόδοση.

Για να αναπτύξετε ένα Route Handler ως Edge Function, προσθέστε το edge runtime στο αρχείο route.ts σας:

export const runtime = 'edge';

import { NextResponse } from 'next/server';

export async function GET(request: Request) {
 return NextResponse.json({ message: 'Hello from the Edge!' });
}

Server Actions

Τα Server Actions σας επιτρέπουν να εκτελείτε server-side κώδικα απευθείας από τα React components σας. Τα Route Handlers και τα Server Actions συνεργάζονται απρόσκοπτα, επιτρέποντάς σας να δημιουργείτε πολύπλοκες εφαρμογές με ευκολία.

Ακολουθεί ένα παράδειγμα χρήσης ενός Server Action για να καλέσετε ένα Route Handler:

// app/components/MyComponent.tsx
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';

async function handleSubmit(data: FormData) {
 'use server';

 const name = data.get('name');
 const email = data.get('email');

 const response = await fetch('/api/users', {
 method: 'POST',
 body: JSON.stringify({ name, email }),
 });

 if (response.ok) {
 router.refresh(); // Ανανέωση της σελίδας για να αντικατοπτριστούν οι αλλαγές
 }
}

export default function MyComponent() {
 const router = useRouter();

 return (
 




); }

Caching

Το caching μπορεί να βελτιώσει σημαντικά την απόδοση των API endpoints σας. Μπορείτε να χρησιμοποιήσετε το header Cache-Control για να ελέγξετε πώς οι απαντήσεις σας αποθηκεύονται προσωρινά από τους browsers και τα CDNs.

return NextResponse.json({ message: 'Success!' }, { status: 200, headers: { 'Cache-Control': 'public, max-age=3600' } });

Αυτό το παράδειγμα ορίζει το header Cache-Control σε public, max-age=3600, το οποίο λέει στους browsers και τα CDNs να αποθηκεύσουν προσωρινά την απάντηση για μία ώρα.

Βέλτιστες Πρακτικές

Παραδείγματα από τον Πραγματικό Κόσμο

Ακολουθούν μερικά παραδείγματα από τον πραγματικό κόσμο για το πώς μπορούν να χρησιμοποιηθούν τα Route Handlers:

Παράδειγμα διεθνούς E-commerce: Ένα Route Handler χρησιμοποιείται για την ανάκτηση της τιμολόγησης προϊόντων με βάση τη χώρα του χρήστη. Το endpoint θα μπορούσε να χρησιμοποιήσει τη γεωγραφική τοποθεσία του αιτήματος (που προκύπτει από τη διεύθυνση IP) για να καθορίσει την τοποθεσία του χρήστη και να επιστρέψει τιμές στο κατάλληλο νόμισμα. Αυτό συμβάλλει σε μια τοπικοποιημένη εμπειρία αγορών.

Παράδειγμα παγκόσμιου ελέγχου ταυτότητας: Ένα Route Handler που υλοποιεί έλεγχο ταυτότητας πολλαπλών παραγόντων (MFA) για χρήστες παγκοσμίως. Αυτό θα μπορούσε να περιλαμβάνει την αποστολή κωδικών SMS ή τη χρήση εφαρμογών authenticator, σεβόμενο ταυτόχρονα τους κανονισμούς απορρήτου και τις τηλεπικοινωνιακές υποδομές διαφορετικών περιοχών.

Παράδοση πολυγλωσσικού περιεχομένου: Ένα Route Handler που παραδίδει περιεχόμενο στην προτιμώμενη γλώσσα του χρήστη. Αυτό μπορεί να καθοριστεί από το header `Accept-Language` στο αίτημα. Αυτό το παράδειγμα αναδεικνύει την ανάγκη για σωστή κωδικοποίηση UTF-8 και υποστήριξη γλωσσών από δεξιά προς τα αριστερά όπου χρειάζεται.

Συμπέρασμα

Τα Next.js Route Handlers παρέχουν έναν ισχυρό και ευέλικτο τρόπο για τη δημιουργία API endpoints απευθείας μέσα στην εφαρμογή σας Next.js. Αξιοποιώντας τα Route Handlers, μπορείτε να δημιουργήσετε ισχυρά APIs με ευκολία, να συντοποθετήσετε τη λογική του backend σας με τα React components σας και να επωφεληθείτε από χαρακτηριστικά όπως το middleware, το streaming και οι Edge Functions.

Αυτός ο ολοκληρωμένος οδηγός κάλυψε τα πάντα, από τη βασική ρύθμιση έως τις προηγμένες τεχνικές. Ακολουθώντας τις βέλτιστες πρακτικές που περιγράφονται σε αυτόν τον οδηγό, μπορείτε να δημιουργήσετε APIs υψηλής ποιότητας που είναι ασφαλή, αποδοτικά και συντηρήσιμα.