چگونه یک REST API بسازیم: طراحی، امنیت و انتشار
برای ساخت یک REST API، ابتدا منابع اپلیکیشن خود را فهرست کنید (کاربران، سفارشها، رزروها)، به هرکدام یک آدرس مثل /orders و /orders/{id} بدهید و برای عملیات از متدهای HTTP استفاده کنید: GET برای خواندن، POST برای ساختن، PATCH برای بهروزرسانی و DELETE برای حذف. پاسخ را به صورت JSON با کدهای وضعیت معنادار برگردانید، تمام ورودیها را اعتبارسنجی کنید، احراز هویت و بررسی دسترسی برای هر رکورد را روی سرور الزامی کنید و لیستها را صفحهبندی کنید. سپس endpointها را مستند کنید و API را پشت HTTPS منتشر کنید.
این راهنما تصمیمهای طراحی، مجموعهای از مسیرهای نمونه، پرامپتهایی برای یک AI app builder و اشتباهاتی را پوشش میدهد که منجر به حفرههای امنیتی میشوند. اگر API برای شما تازگی دارد، از API چیست شروع کنید.
چه زمانی به REST API نیاز دارید
- فرانتاند وب شما باید دادهها را از سرور ذخیره و بارگذاری کند
- یک اپ موبایل، شریک تجاری یا ابزار اتوماسیون به دادههای شما دسترسی لازم دارد
- سرویسهای دیگر رویدادها را برای شما ارسال میکنند (وبهوک)
- کار را بین تیم فرانتاند و بکاند تقسیم میکنید
REST رایجترین سبک است، اما تنها سبک نیست. REST در برابر GraphQL توضیح میدهد چه زمانی یک endpoint واحد با کوئری انعطافپذیر مناسبتر است.
ابتدا طراحی کنید: منابع و مسیرها
اسمهای اپلیکیشن خود و کارهایی را که کاربران با آنها انجام میدهند یادداشت کنید. برای یک اپ رزرواسیون ساده:
| متد | مسیر | کارکرد | کد موفقیت |
|---|---|---|---|
GET | /api/bookings | فهرست رزروهای درخواستدهنده (صفحهبندیشده) | 200 |
POST | /api/bookings | ساخت یک رزرو | 201 |
GET | /api/bookings/{id} | دریافت یک رزرو | 200 |
PATCH | /api/bookings/{id} | تغییر برخی فیلدها | 200 |
DELETE | /api/bookings/{id} | لغو یک رزرو | 204 |
GET | /api/health | بررسی سلامت برای مانیتورینگ | 200 |
اینها به ساختن، خواندن، بهروزرسانی و حذف (CRUD) نگاشت میشوند؛ CRUD چیست را ببینید. قواعدی که ارزش رعایت دارند:
- اسمهای جمع و بدون فعل در آدرسها:
/bookings، نه/getBookings. - فقط یک سطح تودرتو وقتی مالکیت را روشنتر میکند:
/bookings/{id}/notes. - عملیات غیر CRUD میتوانند زیرمنبع باشند:
POST /bookings/{id}/cancelواضحتر از یک PATCH جادویی است. - نامگذاری یکسان فیلدها، مثل
created_atدر همه جا.
کدهای وضعیت و خطاها
کدهای استاندارد HTTP را به کار ببرید تا کلاینتها بدون تجزیه متن بفهمند چه اتفاقی افتاده است:
| کد | معنی | زمان استفاده |
|---|---|---|
| 200 | OK | خواندن یا بهروزرسانی موفق |
| 201 | Created | یک POST چیزی ساخته است |
| 204 | No Content | موفقیت بدون داده برای بازگشت |
| 400 | Bad Request | ورودی اعتبارسنجی را رد نکرد |
| 401 | Unauthorized | واردنشده یا توکن نامعتبر |
| 403 | Forbidden | واردشده اما اجازه ندارد |
| 404 | Not Found | وجود ندارد، یا نباید بداند که وجود دارد |
| 409 | Conflict | تکراری است، یا بازه از قبل رزرو شده |
| 429 | Too Many Requests | محدودیت نرخ پر شده |
| 500 | Server Error | خطایی در سمت شما رخ داده |
خطاها را در یک ساختار JSON یکسان برگردانید، مثلاً {"error": {"code": "slot_taken", "message": "این زمان دیگر در دسترس نیست."}}، و هرگز stack trace یا خطاهای پایگاه داده را در پاسخ قرار ندهید.
گزینهها و مبادلات
| تصمیم | انتخاب ساده | جایگزین |
|---|---|---|
| محل قرارگیری API | مسیرهای API داخل فریمورک وب شما | یک سرویس API جداگانه، مفید برای چند کلاینت یا زبان متفاوت |
| احراز هویت | کوکی نشست برای اپ وب خودتان | توکن (bearer token یا API key) برای اپهای موبایل و اشخاص ثالث |
| صفحهبندی | ?page=2&limit=20 | مبتنی بر cursor (?after=...)، پایدارتر برای لیستهای بزرگ و در حال تغییر |
| نسخهبندی | ندارد تا وقتی کاربران بیرونی داشته باشید | /v1/ در مسیر، وقتی دیگران به آن وابسته شدند |
| مستندات | یک README با فهرست مسیرها | یک مشخصه OpenAPI که ابزارها میتوانند آن را به مستندات تعاملی و کد کلاینت تبدیل کنند |
گامبهگام
- منابع و مسیرها را فهرست کنید طبق بالا، همراه با اینکه چه کسی مجاز به فراخوانی هر کدام است.
- دادهها را مدلسازی کنید در پایگاه داده، با فیلدها و روابطی که لازم دارید.
- ابتدا مسیرهای خواندن را بسازید، سپس ساختن، بهروزرسانی و حذف.
- هر ورودی نوشتنی را با یک کتابخانه schema اعتبارسنجی کنید: فیلدهای الزامی، نوعها، طولها، مقادیر مجاز. فیلدهای ناشناخته را رد کنید.
- احراز هویت و سپس مجوزدهی برای هر رکورد را اضافه کنید: بارگذاری
/bookings/42باید بررسی کند که رزرو 42 متعلق به درخواستدهنده است، نه فقط اینکه کسی وارد شده است. - هر لیست را صفحهبندی کنید و اندازه صفحه را محدود کنید.
- برای ورود و مسیرهای سنگین، محدودیت نرخ بگذارید. به محدودیت نرخ مراجعه کنید.
- CORS را فقط در صورت نیاز پیکربندی کنید، یعنی وقتی مرورگرهای روی دامنههای دیگر باید API را صدا بزنند، و آن مبداها را صریح فهرست کنید. رفع خطاهای CORS خطاهایی را که خواهید دید توضیح میدهد.
- مستندات و تست برای هر مسیر بنویسید، شامل حالتهای خطا.
- انتشار با متغیرهای محیطی برای رمزها، HTTPS، لاگ و بررسی سلامت.
پرامپتهایی برای AI builder شما
اسکلت اولیه:
یک REST API برای رزرو بسازید با این مسیرها: GET /api/health، GET /api/bookings (صفحهبندیشده، حداکثر 50 در هر صفحه)، POST /api/bookings، GET /api/bookings/:id، PATCH /api/bookings/:id، DELETE /api/bookings/:id. دادهها را در پایگاه داده ما ذخیره کنید. بدنه درخواستها را با یک کتابخانه schema اعتبارسنجی کنید و فیلدهای ناشناخته را رد کنید. خطاهای JSON را به شکل {"error": {"code", "message"}} و با کدهای درست (400، 401، 403، 404، 409) برگردانید. رمزها را در متغیرهای محیطی نگه دارید.
امنیت:
برای همه مسیرهای رزرو ورود را الزامی کنید. در هر خواندن، بهروزرسانی و حذف، روی سرور بررسی کنید که رزرو متعلق به کاربر فعلی است؛ اگر نبود 404 برگردانید. هرگز شناسه کاربر یا نقش را از بدنه درخواست نپذیرید. برای POST /api/bookings محدودیت نرخ 20 در دقیقه برای هر کاربر بگذارید. خطاها را روی سرور لاگ کنید بدون اینکه stack trace به کاربر برگردد.
مستندات:
یک توصیف OpenAPI از این مسیرها بنویسید و یک README کوتاه با نمونه درخواست و پاسخ برای هر مسیر.
تست API خود
از بیرون فرانتاند تست کنید، چون مهاجمان همین کار را میکنند:
- هر مسیر با ورودی معتبر کار میکند و شکل و کد مستندشده را برمیگرداند
- فیلدهای ناقص یا نامعتبر با پیام واضح، 400 برمیگردانند
- بدون توکن، هر مسیر محافظتشده 401 برمیگرداند
- کاربر A با درخواست رکورد کاربر B از طریق شناسه، 404 یا 403 میگیرد
- لیستها صفحهبندیاند و مقدار بزرگ
limitمحدود میشود - ساختن تکراری یا متعارض، 409 برمیگرداند نه 500
- محدودیتهای نرخ، 429 برمیگردانند
- پاسخهای خطا شامل stack trace، SQL یا رمز نیستند
- CORS فقط به مبداهای مورد نظر اجازه میدهد
اشتباهات رایج
- بررسی ورود، بدون بررسی مالکیت. رایجترین حفره API: هر کاربر واردشده با تغییر شناسه میتواند هر رکوردی را بخواند.
- اعتماد به کلاینت. قیمتها، نقشها و شناسههای کاربر از بدنه درخواست قابل ویرایشاند.
- برگرداندن کل سطرهای پایگاه داده. هش رمز و فیلدهای داخلی نشت میکنند. تعیین کنید هر پاسخ چه چیزی را شامل شود.
- لیستهای بیکران. یک درخواست برای همه رکوردها میتواند کل اپ را کند کند.
200 OKهمراه با پیام خطا در متن. کلاینتها و مانیتورینگ نمیفهمند که شکست خورده است.- CORS با اجازه همهچیز روی API که از کوکی استفاده میکند.
- نبود بررسی سلامت یا لاگ، پس از قطعیها کاربران به شما خبر میدهند.
برای بازبینی گستردهتر قبل از انتشار، چکلیست امنیتی برای اپهای ساختهشده با AI را ببینید.
ساخت REST API در Mythex
میتوانید از Mythex یک API را به عنوان بخشی از اپ یا به صورت سرویس مستقل بخواهید. دستور آماده REST API backend در مستندات، یک پرامپت شروع دارد: نام فریمورک و مسیرها را مشخص کنید، خطاهای JSON واضح بخواهید، رمزها را در متغیرهای محیطی نگه دارید و یک Dockerfile اضافه کنید. بکاندهای کانتینری با Node، Python، C#، Java و دیگران از طریق Dockerfile منتشر میشوند و Mythex انتشار را از بخش Publish مدیریت میکند (بکاندهای API). یک پروژه میتواند وبسایت و سرور API را کنار هم اجرا کند و میتوانید در پیشنمایش بین آنها جابهجا شوید. کلیدها را به عنوان secret پروژه نگه دارید و اگر API به پایگاه داده نیاز دارد، آن را در چت درخواست کنید. برای کارهای زمانبندیشده در کنار API، چگونه کارهای پسزمینه را اجرا کنیم را ببینید.
پرسشها
REST API چیست؟
REST API راهی است که برنامهها از طریق HTTP با دادههای اپلیکیشن شما کار میکنند. هر نوع داده یک منبع (resource) با آدرس اختصاصی خودش است، مانند /orders، و متدهای استاندارد روی آن عمل میکنند: GET برای خواندن، POST برای ساختن، PATCH یا PUT برای بهروزرسانی و DELETE برای حذف. داده معمولاً به صورت JSON ارسال میشود.
REST API را با کدام زبان بسازم؟
از زبانی استفاده کنید که خودتان یا تیمتان بتوانید نگهداریاش کنید. Node.js با Express یا Fastify، Python با FastAPI و فریمورکهای C# یا Java همه خوب کار میکنند. قواعد طراحی مسیرها، کدهای وضعیت، اعتبارسنجی و احراز هویت از زبان مهمترند.
چطور از REST API محافظت کنم؟
برای هر مسیری که عمومی نیست احراز هویت الزامی کنید، روی سرور بررسی کنید که درخواستدهنده به هر رکورد مشخص دسترسی دارد، تمام ورودیها را اعتبارسنجی کنید، از HTTPS استفاده کنید، تعداد درخواستها را محدود کنید و رمزها و کلیدها را در متغیرهای محیطی نگه دارید. هرگز به شناسهها یا نقشهایی که کلاینت میفرستد اعتماد نکنید.
آیا برای REST API به بکاند جداگانه نیاز دارم؟
همیشه نه. فریمورکهایی مانند Next.js میتوانند مسیرهای API را کنار صفحات سرو کنند. یک سرویس API جداگانه وقتی منطقی است که چند کلاینت (وب، موبایل، شرکای تجاری) از آن استفاده کنند، یا وقتی به زبان و مقیاسپذیری مستقل نیاز داشته باشد.