API Routes في Next.js — دليل شامل 2026
دليل عملي مفصل لـ API Routes في Next.js — بناء APIs، Route Handlers، والتحقق من البيانات
في المقال السابق، تعلمت جلب البيانات. الآن سنتعلم API Routes — لبناء Backend كامل داخل Next.js.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم API Routes، مع تمارين وحلول.
ما هي API Routes؟
API Routes هي نقاط نهاية (Endpoints) تبنيها داخل Next.js، دون الحاجة لسيرفر منفصل.
الفائدة:
- ✅ نفس المشروع (Frontend + Backend).
- ✅ نشر واحد.
- ✅ TypeScript مشترك.
- ✅ لا CORS.
متى تستخدمها؟
- عندما تحتاج API لتطبيقك.
- عندما تريد دمج البيانات من مصادر متعددة.
- عندما تحتاج التحقق من البيانات قبل الإرسال.
- عندما تريد حماية API Keys.
Route Handlers
في App Router، تُسمى Route Handlers وتوضع في ملف route.ts.
| المسار | الملف | الرابط |
|---|---|---|
| API أساسي | app/api/route.ts | /api |
| API للمستخدمين | app/api/users/route.ts | /api/users |
| API للمستخدم الواحد | app/api/users/[id]/route.ts | /api/users/1 |
| API للمقالات | app/api/posts/route.ts | /api/posts |
أول API
app/api/hello/route.ts:
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({
message: "مرحباً من Next.js API!",
timestamp: new Date().toISOString(),
});
}
الاختبار:
GET http://localhost:3000/api/hello
النتيجة:
{
"message": "مرحباً من Next.js API!",
"timestamp": "2026-11-16T10:30:00.000Z"
}
🎉 مبروك! بنيت أول API!
طرق HTTP
app/api/users/route.ts:
import { NextResponse } from "next/server";
// GET /api/users
export async function GET() {
return NextResponse.json([
{ id: 1, name: "أحمد" },
{ id: 2, name: "محمد" },
]);
}
// POST /api/users
export async function POST(request: Request) {
const body = await request.json();
return NextResponse.json(
{ success: true, user: body },
{ status: 201 }
);
}
// PUT /api/users
export async function PUT(request: Request) {
const body = await request.json();
return NextResponse.json({ success: true, user: body });
}
// DELETE /api/users
export async function DELETE() {
return NextResponse.json({ success: true });
}
// PATCH /api/users
export async function PATCH(request: Request) {
const body = await request.json();
return NextResponse.json({ success: true, patch: body });
}
// HEAD / OPTIONS (تلقائي)
قراءة الطلبات
1. قراءة Body (JSON)
export async function POST(request: Request) {
const body = await request.json();
return NextResponse.json({ received: body });
}
2. قراءة Body (Form)
export async function POST(request: Request) {
const formData = await request.formData();
const name = formData.get("name") as string;
return NextResponse.json({ name });
}
3. قراءة Query Parameters
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const query = searchParams.get("q");
const limit = searchParams.get("limit");
return NextResponse.json({ query, limit });
}
الاختبار: /api/search?q=react&limit=5
4. قراءة Route Parameters
app/api/users/[id]/route.ts:
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
return NextResponse.json({ id, name: `المستخدم ${id}` });
}
⚠️ لاحظ: في Next.js 15، params هو Promise.
5. قراءة Headers
export async function GET(request: Request) {
const auth = request.headers.get("authorization");
return NextResponse.json({ auth });
}
إرسال الاستجابات
1. JSON
return NextResponse.json({ message: "مرحباً" });
2. مع Status Code
return NextResponse.json(
{ error: "غير موجود" },
{ status: 404 }
);
3. مع Headers
return NextResponse.json(
{ message: "مرحباً" },
{
headers: {
"Cache-Control": "no-store",
"X-Custom-Header": "value",
},
}
);
4. نصوص
return new Response("نص عادي", {
headers: { "Content-Type": "text/plain; charset=utf-8" },
});
5. إعادة توجيه
import { redirect } from "next/navigation";
export async function GET() {
redirect("/");
}
أكواد الحالة
| الكود | المعنى | الاستخدام |
|---|---|---|
| 200 | OK | نجاح |
| 201 | Created | إنشاء |
| 204 | No Content | حذف |
| 400 | Bad Request | طلب خاطئ |
| 401 | Unauthorized | غير مصرح |
| 403 | Forbidden | ممنوع |
| 404 | Not Found | غير موجود |
| 500 | Internal Server Error | خطأ في السيرفر |
مثال عملي: CRUD للمستخدمين
app/api/users/route.ts:
import { NextResponse } from "next/server";
let users = [
{ id: 1, name: "أحمد", email: "[email protected]" },
{ id: 2, name: "محمد", email: "[email protected]" },
];
// GET /api/users
export async function GET() {
return NextResponse.json(users);
}
// POST /api/users
export async function POST(request: Request) {
const body = await request.json();
if (!body.name || !body.email) {
return NextResponse.json(
{ error: "الاسم والبريد مطلوبان" },
{ status: 400 }
);
}
const newUser = {
id: Date.now(),
name: body.name,
email: body.email,
};
users.push(newUser);
return NextResponse.json(newUser, { status: 201 });
}
app/api/users/[id]/route.ts:
import { NextResponse } from "next/server";
let users = [
{ id: 1, name: "أحمد", email: "[email protected]" },
{ id: 2, name: "محمد", email: "[email protected]" },
];
// GET /api/users/:id
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const user = users.find((u) => u.id === parseInt(id));
if (!user) {
return NextResponse.json(
{ error: "المستخدم غير موجود" },
{ status: 404 }
);
}
return NextResponse.json(user);
}
// PUT /api/users/:id
export async function PUT(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const body = await request.json();
const index = users.findIndex((u) => u.id === parseInt(id));
if (index === -1) {
return NextResponse.json(
{ error: "المستخدم غير موجود" },
{ status: 404 }
);
}
users[index] = { ...users[index], ...body };
return NextResponse.json(users[index]);
}
// DELETE /api/users/:id
export async function DELETE(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
const index = users.findIndex((u) => u.id === parseInt(id));
if (index === -1) {
return NextResponse.json(
{ error: "المستخدم غير موجود" },
{ status: 404 }
);
}
users.splice(index, 1);
return new NextResponse(null, { status: 204 });
}
التحقق من البيانات
export async function POST(request: Request) {
const body = await request.json();
const errors = [];
if (!body.name || body.name.length < 2) {
errors.push("الاسم يجب أن يكون حرفين على الأقل");
}
if (!body.email || !body.email.includes("@")) {
errors.push("البريد غير صحيح");
}
if (body.age && (body.age < 18 || body.age > 100)) {
errors.push("العمر يجب أن يكون بين 18 و 100");
}
if (errors.length > 0) {
return NextResponse.json(
{ errors },
{ status: 400 }
);
}
// ... إنشاء المستخدم
}
استخدام API من Client
1. استخدام fetch
"use client";
import { useState, useEffect } from "react";
export default function UsersList() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("/api/users")
.then((res) => res.json())
.then(setUsers);
}, []);
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
}
2. إرسال POST
"use client";
async function createUser(name: string, email: string) {
const res = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, email }),
});
const data = await res.json();
return data;
}
مثال: API للبحث
app/api/search/route.ts:
import { NextResponse } from "next/server";
const articles = [
{ id: 1, title: "تعلم Next.js", category: "برمجة" },
{ id: 2, title: "تعلم React", category: "برمجة" },
{ id: 3, title: "تعلم TypeScript", category: "برمجة" },
];
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const q = searchParams.get("q") || "";
const results = articles.filter((article) =>
article.title.toLowerCase().includes(q.toLowerCase())
);
return NextResponse.json({
query: q,
count: results.length,
results,
});
}
الاختبار: /api/search?q=react
تمارين عملية
تمرين 1: API بسيط
أنشئ /api/hello يعيد ترحيباً.
الحل:
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({ message: "مرحباً" });
}
تمرين 2: GET مع Query
أنشئ API يقرأ ?name=.
الحل:
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const name = searchParams.get("name") || "زائر";
return NextResponse.json({ message: `مرحباً ${name}` });
}
تمرين 3: POST
أنشئ API يستقبل JSON.
الحل:
export async function POST(request: Request) {
const body = await request.json();
return NextResponse.json({ received: body }, { status: 201 });
}
تمرين 4: CRUD كامل
أنشئ CRUD للمقالات.
الحل:
// app/api/posts/route.ts
let posts = [];
export async function GET() {
return NextResponse.json(posts);
}
export async function POST(request: Request) {
const body = await request.json();
const post = { id: Date.now(), ...body };
posts.push(post);
return NextResponse.json(post, { status: 201 });
}
تمرين 5: مسار ديناميكي
أنشئ /api/users/[id].
الحل:
export async function GET(
request: Request,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
return NextResponse.json({ id });
}
تمرين 6: التحقق
أضف تحققاً للبيانات.
الحل:
if (!body.email?.includes("@")) {
return NextResponse.json(
{ error: "بريد غير صحيح" },
{ status: 400 }
);
}
تمرين 7: حماية API
أضف تحقق من Authorization.
الحل:
export async function POST(request: Request) {
const auth = request.headers.get("authorization");
if (auth !== "Bearer secret-token") {
return NextResponse.json(
{ error: "غير مصرح" },
{ status: 401 }
);
}
// ...
}
تمرين 8: API متكامل
ابنِ API كامل مع CRUD + تحقق + حماية.
الحل: (راجع المثال الكامل أعلاه)
حل المشاكل الشائعة
🔴 المشكلة 1: API لا يعمل في Client
السبب: استخدام URL غير كامل.
الحل: استخدم URL نسبي:
fetch("/api/users"); // ✅
🔴 المشكلة 2: request.json() يفشل
السبب: Body فارغ أو غير JSON.
الحل:
try {
const body = await request.json();
} catch {
return NextResponse.json({ error: "JSON غير صحيح" }, { status: 400 });
}
🔴 المشكلة 3: CORS
السبب: الطلب من نطاق مختلف.
الحل: أضف headers:
return NextResponse.json(data, {
headers: {
"Access-Control-Allow-Origin": "*",
},
});
🔴 المشكلة 4: API Routes لا تعمل مع output: 'export'
السبب: التصدير الثابت لا يدعم API Routes.
الحل: استخدم Vercel أو Firebase Functions.
🔴 المشكلة 5: params غير متاح
السبب: في Next.js 15، params هو Promise.
الحل:
{ params }: { params: Promise<{ id: string }> }
// ...
const { id } = await params;
جدول دوال API
| الدالة | الوظيفة |
|---|---|
NextResponse.json() | إرسال JSON |
request.json() | قراءة JSON |
request.formData() | قراءة Form |
request.headers.get() | قراءة Header |
new URL(request.url) | قراءة Query |
new Response() | استجابة مخصصة |
redirect() | إعادة توجيه |
قائمة تحقق نهائية
| المهمة | الحالة |
|---|---|
| فهم Route Handlers | ⬜ |
| GET و POST | ⬜ |
| قراءة Body و Query | ⬜ |
| المسارات الديناميكية | ⬜ |
| التحقق من البيانات | ⬜ |
| حماية API | ⬜ |
| حل التمارين الثمانية | ⬜ |
ماذا بعد هذا المقال؟
الآن بعد أن أتقنت API Routes، أنت جاهز للمقال التالي:
- Styling — Tailwind و CSS.
- Authentication — المصادقة.
- Deployment — النشر.
الخلاصة
في هذا المقال، تعلمت:
- ✅ ما هي API Routes.
- ✅ Route Handlers.
- ✅ طرق HTTP.
- ✅ قراءة الطلبات.
- ✅ إرسال الاستجابات.
- ✅ CRUD كامل.
- ✅ التحقق من البيانات.
- ✅ حل 8 تمارين عملية.
تذكر: API Routes تجعل Next.js إطاراً كاملاً — Frontend و Backend.
جلب البيانات في Next.js — دليل شامل 2026
Styling في Next.js — دليل شامل 2026
📚 مقالات ذات صلة
مشروع Next.js متكامل — مدونة احترافية 2026
مشروع عملي شامل لبناء مدونة كاملة بـ Next.js — مع Markdown، SEO، نشر تلقائي، وتصميم احترافي
نشر تطبيق Next.js — دليل شامل 2026
دليل عملي مفصل لنشر تطبيق Next.js — Vercel، Firebase، Netlify، والتصدير الثابت
المصادقة في Next.js — دليل شامل 2026
دليل عملي مفصل للمصادقة في Next.js — NextAuth.js، JWT، Middleware، وحماية المسارات