فارسی

یاد بگیرید چگونه از مسیرهای API در Next.js برای ساخت بک‌اندهای بدون سرور (serverless) مستقیماً در اپلیکیشن Next.js خود استفاده کنید. این راهنما همه چیز را، از راه‌اندازی اولیه تا تکنیک‌های پیشرفته برای مدیریت احراز هویت، پایداری داده‌ها و موارد دیگر، پوشش می‌دهد.

مسیرهای API در Next.js: ساخت آسان بک‌اند شما

Next.js با ویژگی‌های قدرتمند و ساختار شهودی خود، توسعه فرانت‌اند را متحول کرده است. اما آیا می‌دانستید که می‌تواند توسعه بک‌اند را نیز به طور قابل توجهی ساده کند؟ مسیرهای API در Next.js به شما این امکان را می‌دهند که اندپوینت‌های API بدون سرور را مستقیماً در اپلیکیشن Next.js خود ایجاد کنید و در بسیاری از موارد نیاز به یک سرور بک‌اند مجزا را از بین ببرید. این راهنمای جامع شما را در فرآیند ساخت یک بک‌اند قوی و مقیاس‌پذیر با استفاده از مسیرهای API در Next.js راهنمایی می‌کند.

مسیرهای API در Next.js چه هستند؟

مسیرهای API توابع بدون سروری هستند که شما در دایرکتوری /pages/api در پروژه Next.js خود ایجاد می‌کنید. این توابع درخواست‌های HTTP ورودی را مدیریت کرده و پاسخ‌ها را برمی‌گردانند، دقیقاً مانند یک API بک‌اند سنتی. تفاوت اصلی این است که آنها به عنوان توابع بدون سرور (serverless functions) مستقر می‌شوند، به این معنی که نیازی به مدیریت سرورها یا زیرساخت ندارید.

آنها را به عنوان توابع بک‌اند سبک و بر حسب تقاضا در نظر بگیرید که به طور یکپارچه با فرانت‌اند Next.js شما ادغام شده‌اند.

مزایای استفاده از مسیرهای API در Next.js

شروع کار با مسیرهای API در Next.js

بیایید یک مسیر API ساده ایجاد کنیم که یک پاسخ JSON برمی‌گرداند. ابتدا، مطمئن شوید که یک پروژه Next.js راه‌اندازی کرده‌اید. اگر نه، یکی با استفاده از دستور زیر ایجاد کنید:

npx create-next-app my-app
cd my-app

اکنون، فایلی به نام hello.js در داخل دایرکتوری /pages/api ایجاد کنید:

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}

این کد یک مسیر API ساده را تعریف می‌کند که با یک شیء JSON حاوی نام "John Doe" پاسخ می‌دهد. برای دسترسی به این مسیر API، سرور توسعه Next.js خود را شروع کنید:

npm run dev

سپس، مرورگر خود را باز کرده و به آدرس http://localhost:3000/api/hello بروید. شما باید پاسخ JSON زیر را ببینید:

{"name": "John Doe"}

درک کنترل‌کننده (Handler) مسیر API

تابع handler در مسیر API شما دو آرگومان دریافت می‌کند:

شما می‌توانید از این اشیاء برای مدیریت انواع مختلف درخواست‌ها، خواندن داده‌ها از بدنه درخواست، تنظیم هدرهای پاسخ و ارسال انواع مختلف پاسخ‌ها استفاده کنید.

مدیریت متدهای مختلف HTTP

شما می‌توانید از ویژگی req.method برای تعیین متد HTTP درخواست ورودی استفاده کنید و متدهای مختلف را بر این اساس مدیریت کنید. برای مثال:

// pages/api/method.js
export default function handler(req, res) {
  if (req.method === 'GET') {
    // رسیدگی به درخواست GET
    res.status(200).json({ message: 'این یک درخواست GET است' })
  } else if (req.method === 'POST') {
    // رسیدگی به درخواست POST
    res.status(200).json({ message: 'این یک درخواست POST است' })
  } else {
    // رسیدگی به متدهای دیگر
    res.status(405).json({ message: 'متد مجاز نیست' })
  }
}

در این مثال، مسیر API هم درخواست‌های GET و هم POST را مدیریت می‌کند. اگر متد درخواست GET باشد، با یک شیء JSON حاوی پیام "این یک درخواست GET است" پاسخ می‌دهد. اگر متد درخواست POST باشد، با یک شیء JSON حاوی پیام "این یک درخواست POST است" پاسخ می‌دهد. اگر متد درخواست هر چیز دیگری باشد، با خطای 405 Method Not Allowed پاسخ می‌دهد.

خواندن داده‌ها از بدنه درخواست

برای درخواست‌های POST، PUT و PATCH، شما اغلب نیاز به خواندن داده‌ها از بدنه درخواست دارید. Next.js پشتیبانی داخلی برای تجزیه بدنه‌های درخواست JSON و URL-encoded فراهم می‌کند. برای تجزیه بدنه درخواست JSON، می‌توانید از ویژگی req.body استفاده کنید. برای مثال:

// pages/api/post.js
export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { name, email } = req.body

    // پردازش داده‌ها
    console.log('Name:', name)
    console.log('Email:', email)

    res.status(200).json({ message: 'داده‌ها با موفقیت دریافت شدند' })
  } else {
    res.status(405).json({ message: 'متد مجاز نیست' })
  }
}

برای آزمایش این مسیر API، می‌توانید از ابزاری مانند Postman یا curl برای ارسال یک درخواست POST با بدنه JSON استفاده کنید:

curl -X POST -H "Content-Type: application/json" -d '{"name": "Jane Doe", "email": "jane.doe@example.com"}' http://localhost:3000/api/post

تنظیم هدرهای پاسخ

شما می‌توانید از متد res.setHeader() برای تنظیم هدرهای پاسخ استفاده کنید. این برای تنظیم نوع محتوا، کنترل کش و سایر اطلاعات مهم مفید است. برای مثال:

// pages/api/headers.js
export default function handler(req, res) {
  res.setHeader('Content-Type', 'application/json')
  res.setHeader('Cache-Control', 's-maxage=3600')
  res.status(200).json({ message: 'Hello, world!' })
}

در این مثال، مسیر API هدر Content-Type را به application/json تنظیم می‌کند، که نشان می‌دهد پاسخ یک شیء JSON است. همچنین هدر Cache-Control را به s-maxage=3600 تنظیم می‌کند، که به مرورگر و CDN می‌گوید پاسخ را تا 1 ساعت کش کند.

مدیریت خطا

مدیریت صحیح خطاها در مسیرهای API شما مهم است. می‌توانید از بلوک‌های try-catch برای گرفتن استثناها و ارسال پاسخ‌های خطای مناسب به کلاینت استفاده کنید. برای مثال:

// pages/api/error.js
export default async function handler(req, res) {
  try {
    // شبیه‌سازی یک خطا
    throw new Error('مشکلی پیش آمد')
  } catch (error) {
    console.error(error)
    res.status(500).json({ message: 'خطای داخلی سرور' })
  }
}

در این مثال، مسیر API با پرتاب یک شیء Error جدید، یک خطا را شبیه‌سازی می‌کند. بلوک catch خطا را گرفته، آن را در کنسول ثبت می‌کند و یک پاسخ 500 Internal Server Error به کلاینت ارسال می‌کند. برای محیط‌های تولیدی، استفاده از یک سیستم لاگ‌گیری قوی مانند Sentry یا Datadog را در نظر بگیرید.

اتصال به پایگاه داده

یکی از رایج‌ترین موارد استفاده برای مسیرهای API، اتصال به پایگاه داده است. مسیرهای API در Next.js به طور یکپارچه با پایگاه‌های داده مختلف، از جمله موارد زیر، ادغام می‌شوند:

در اینجا مثالی از نحوه اتصال به پایگاه داده MongoDB در یک مسیر API در Next.js آورده شده است:

// pages/api/mongodb.js
import { MongoClient } from 'mongodb'

const uri = process.env.MONGODB_URI
const options = {}

let client
let clientPromise

if (!process.env.MONGODB_URI) {
  throw new Error('لطفاً Mongo URI خود را به .env.local اضافه کنید')
}

if (process.env.NODE_ENV === 'development') {
  // در حالت توسعه، از یک متغیر سراسری استفاده کنید تا مقدار
  // در بارگذاری‌های مجدد ماژول ناشی از HMR (Hot Module Replacement) حفظ شود.
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options)
    global._mongoClientPromise = client.connect()
  }
  clientPromise = global._mongoClientPromise
} else {
  // در حالت تولید، بهتر است از یک متغیر سراسری استفاده نشود.
  client = new MongoClient(uri, options)
  clientPromise = client.connect()
}

// یک promise از MongoClient با حوزه ماژول صادر کنید. با انجام این کار در یک
// ماژول جداگانه، کلاینت می‌تواند به طور ایمن در چندین
// تابع استفاده مجدد شود. ببینید: https://github.com/vercel/next.js/blob/canary/examples/with-mongodb/lib/mongodb.js
export default async function handler(req, res) {
  try {
    const client = await clientPromise
    const db = client.db(process.env.MONGODB_DB)
    const collection = db.collection('users')

    const users = await collection.find({}).toArray()

    res.status(200).json({ users })
  } catch (e) {
    console.error(e)
    res.status(500).json({ message: 'واکشی کاربران ناموفق بود' })
  }
}

قبل از اجرای این کد، مطمئن شوید که بسته mongodb را نصب کرده‌اید:

npm install mongodb

شما همچنین باید متغیرهای محیطی MONGODB_URI و MONGODB_DB را تنظیم کنید. این متغیرها باید در فایل .env.local شما (یا در تنظیمات متغیر محیطی ارائه‌دهنده میزبانی شما برای تولید) تعریف شوند. MONGODB_URI شامل رشته اتصال به پایگاه داده MongoDB شما است و MONGODB_DB نام پایگاه داده را مشخص می‌کند.

احراز هویت و مجوزدهی

محافظت از مسیرهای API شما برای امنیت بسیار مهم است. مسیرهای API در Next.js را می‌توان با استفاده از تکنیک‌های مختلف احراز هویت و مجوزدهی، از جمله موارد زیر، امن کرد:

در اینجا مثالی از نحوه محافظت از یک مسیر API با استفاده از احراز هویت JWT آورده شده است:

// pages/api/protected.js
import jwt from 'jsonwebtoken'

const secret = process.env.JWT_SECRET

export default function handler(req, res) {
  const token = req.headers.authorization?.split(' ')[1]

  if (!token) {
    return res.status(401).json({ message: 'غیرمجاز' })
  }

  try {
    const decoded = jwt.verify(token, secret)
    // شیء "decoded" حاوی اطلاعات کاربری است که در توکن گنجانده شده است
    // برای مثال: const userId = decoded.userId;

    // ادامه پردازش درخواست
    res.status(200).json({ message: 'دسترسی به منبع محافظت‌شده موفقیت‌آمیز بود' })
  } catch (error) {
    return res.status(401).json({ message: 'توکن نامعتبر است' })
  }
}

قبل از اجرای این کد، مطمئن شوید که بسته jsonwebtoken را نصب کرده‌اید:

npm install jsonwebtoken

شما همچنین باید متغیر محیطی JWT_SECRET را تنظیم کنید. این باید یک کلید مخفی قوی و تولید شده به صورت تصادفی باشد که برای امضا و تأیید JWT‌ها استفاده می‌شود. این کلید را به صورت امن ذخیره کنید و هرگز آن را در کد سمت کلاینت خود فاش نکنید.

میان‌افزار (Middleware)

در حالی که Next.js میان‌افزار سنتی برای مسیرهای API را به همان روش Express.js ارائه نمی‌دهد، می‌توانید با بسته‌بندی کنترل‌کننده‌های مسیر API خود با توابع قابل استفاده مجدد، به عملکرد مشابهی دست پیدا کنید. این به شما امکان می‌دهد کارهایی مانند موارد زیر را انجام دهید:

در اینجا مثالی از نحوه ایجاد یک میان‌افزار لاگ‌گیری ساده آورده شده است:

// utils/middleware.js
export function withLogging(handler) {
  return async function(req, res) {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`)
    return handler(req, res)
  }
}

برای استفاده از این میان‌افزار، به سادگی کنترل‌کننده مسیر API خود را با تابع withLogging بسته‌بندی کنید:

// pages/api/logged.js
import { withLogging } from '../../utils/middleware'

async function handler(req, res) {
  res.status(200).json({ message: 'این درخواست لاگ شد' })
}

export default withLogging(handler)

بهترین شیوه‌ها برای ساخت مسیرهای API در Next.js

تکنیک‌های پیشرفته

کارهای پس‌زمینه (Background Jobs)

برای کارهای طولانی‌مدت که نباید پاسخ API را مسدود کنند، استفاده از کارهای پس‌زمینه را در نظر بگیرید. می‌توانید از کتابخانه‌هایی مانند BullMQ یا Bree برای مدیریت کارهای پس‌زمینه و پردازش آنها به صورت ناهمزمان استفاده کنید.

وب‌سوکت‌ها (WebSockets)

برای برنامه‌های بی‌درنگ، می‌توانید از وب‌سوکت‌ها در مسیرهای API Next.js خود استفاده کنید. کتابخانه‌هایی مانند Socket.IO و ws ایجاد اتصالات پایدار بین کلاینت و سرور را آسان می‌کنند.

GraphQL

اگر به روشی انعطاف‌پذیرتر و کارآمدتر برای واکشی داده‌ها نیاز دارید، استفاده از GraphQL را در نظر بگیرید. می‌توانید از کتابخانه‌هایی مانند Apollo Server یا Yoga برای ایجاد یک اندپوینت API GraphQL در برنامه Next.js خود استفاده کنید.

نتیجه‌گیری

مسیرهای API در Next.js روشی قدرتمند و راحت برای ساخت بک‌اندهای بدون سرور مستقیماً در برنامه Next.js شما فراهم می‌کنند. با بهره‌گیری از مزایای معماری بدون سرور، می‌توانید توسعه را ساده کرده، عملکرد را بهبود بخشید و هزینه‌ها را کاهش دهید. چه در حال ساخت یک فرم تماس ساده باشید و چه یک پلتفرم تجارت الکترونیک پیچیده، مسیرهای API در Next.js می‌توانند به شما در ایجاد یک بک‌اند قوی و مقیاس‌پذیر با سهولت کمک کنند. با درک قوی از اصول اولیه و به کارگیری بهترین شیوه‌ها، می‌توانید از این ابزار قدرتمند برای ایجاد برنامه‌های کارآمد، امن و قابل دسترس در سطح جهانی استفاده کنید.