REST API چیست و چه زمانی باید از آن استفاده کنیم؟
REST سبک معماری است نه محصول: قیدهای Fielding، منبع و فعل HTTP، بیحالتی، و مقایسهٔ عملی با RPC و GraphQL — بدون شعار «همیشه REST».
SE
13 min readSoheil Ebrahimpour
Founder & product engineer

بیشتر وقتها وقتی کسی میگوید «REST API داریم»، منظورش این است: چند URL، چند فعل HTTP، و بدنهٔ JSON. این توصیف یک پیادهسازی رایج است، نه تعریف REST. روی تیلور فیلدینگ (Roy Fielding) در رسالهٔ دکتری سال ۲۰۰۰ انتقال حالت بازنمودی (Representational State Transfer یا REST) را یک سبک معماری برای سامانههای ابررسانهای توزیعشده نامید، نه یک محصول و نه یک پروتکل.
سبک معماری یعنی مجموعهای از قیدها. اگر قید را بردارید، ممکن است هنوز یک HTTP API مفید داشته باشید؛ فقط دیگر دقیق نیست آن را RESTful بنامید. این دقت pedantic نیست: روی تصمیم اثر میگذارد. بیحالتی مقیاس را عوض میکند. رابط یکنواخت کش و واسطه را ممکن میکند. منبعمحوری شکل URL را عوض میکند. اگر اینها را نخواهید، اصرار به برچسب REST هزینه میتراشد.
مقالهٔ ۰۳۶ API را بهعنوان قرارداد تعریف کرد. اینجا همان قرارداد را وقتی منبعمحور و روی HTTP است باز میکنیم، و میپرسیم چه زمانی این سبک مینشیند و چه زمانی RPC یا GraphQL صادقانهتر است. IBM صریح نوشته هیچکدام ذاتاً برتر نیستند.
اگر دنبال دستور «همیشه REST بسازید» هستید، این متن آن را نمیدهد. اگر دنبال معیار تصمیم هستید، ادامه مفید است.

پاسخ کوتاه
REST قیدهایی است که فیلدینگ برای وب مقیاساینترنتی جمع کرد: جدایی کلاینت/سرور، درخواست بیحالت، برچسب کشپذیری، رابط یکنواخت روی منبع، سامانهٔ لایهای، و اختیاری «کد هنگام تقاضا». APIای که این قیدها را جدی بگیرد REST API نام میگیرد. بیشتر APIهای تجاری تقریبی از سطح منبع + فعل HTTP هستند، نه پیادهسازی کامل hypermedia.
- منبع را نام بگذارید (کالا، سفارش، موجودی)، عمل را در فعل HTTP بگذارید، نه در /createOrder.
- هر درخواست باید بهتنهایی فهمیده شود؛ نشست مخفی روی سرور جای قرارداد نیست.
- REST را وقتی انتخاب کنید که کش، کلاینت متنوع، و تکامل مستقل مهماند.
- اگر عملها رویهاند نه منبع، یا کلاینت باید طرح را هر هفته ببرد، REST را صرفاً از روی مد انتخاب نکنید.
REST محصولی نیست که نصب شود؛ مجموعهای از قیدهاست که بعضی مسئلهها را ساده و بعضی را گران میکند.
REST سبک است، محصول نیست
فصل پنج رسالهٔ فیلدینگ REST را انتزاع عناصر معماری در سامانهٔ ابررسانهٔ توزیعشده میداند. جزئیات پیادهسازی و نحو پروتکل را کنار میگذارد تا روی نقش اجزا، قید تعامل، و تفسیر داده تمرکز کند. جمعبندی همان فصل میگوید این قیدها وقتی با هم اعمال شوند روی مقیاس تعامل، عمومیت رابط، استقرار مستقل اجزا، و وجود واسطه برای تأخیر و امنیت و کپسولهکردن سیستم کهنه تأکید میکنند.
دو نتیجهٔ عملی. اول: REST به HTTP گره خورده نیست، هرچند وب با HTTP آن را مشهور کرد. فیلدینگ میگوید REST ارتباط را به یک پروتکل محدود نمیکند؛ رابط بین اجزا را قید میگذارد. دوم: داشتن JSON روی HTTP بهخودیخود REST نیست. IBM هم REST را مجموعهٔ اصول معماری مینامد و API منطبق را RESTful.
Microsoft مدل بلوغ Richardson را بهعنوان طیف گزارش میکند: سطح صفر یک URI و همهٔ عملها POST؛ سطح یک URI جدا برای منابع؛ سطح دو فعل HTTP؛ سطح سه hypermedia. خیلی از APIهای منتشرشده حدود سطح دو هستند. این شکست اخلاقی نیست؛ فقط برچسب را صادق نگه دارید.
قیدها به زبان تصمیم
فیلدینگ REST را با افزودن تدریجی قید به سبک تهی میسازد. هر قید خاصیت میآورد و تاوان دارد. اگر تاوان را نخواهید بپردازید، قید را شعار نکنید.
کلاینت–سرور
جدا کردن دغدغهٔ رابط کاربری از ذخیرهٔ داده، حملپذیری UI و سادهشدن سرور را میخرد. مهمتر برای وب: اجزا مستقل تکامل مییابند. فرانت فروشگاه میتواند عوض شود بدون اینکه انبار همان روز مهاجرت کند — به شرط آنکه قرارداد منبع پایدار بماند.
بیحالت (Stateless)
هر درخواست کلاینت باید تمام اطلاعات فهمیدن خودش را داشته باشد و به بافت ذخیرهشده روی سرور تکیه نکند. حالت نشست روی کلاینت میماند. فیلدینگ سه خاصیت میشمارد: دیدپذیری (ناظر یک درخواست را کامل میفهمد)، قابلیت اطمینان (بازیابی از شکست جزئی آسانتر است)، مقیاس (سرور لازم نیست منبع را بین درخواستها نگه دارد). تاوان: دادهٔ تکراری در هر تماس، و کنترل کمتر سرور روی رفتار یکنواخت کلاینتها.
MDN همین را برای HTTP تکرار میکند: پروتکل بیحالت است؛ بین دو درخواست متوالی پیوندی در خودِ HTTP نیست. ولی HTTP بدون نشست نیست: کوکی اجازه میدهد نشست ساخته شود. این تمایز مهم است. REST میگوید سرور نباید برای فهم درخواست به «درخواست قبلی» محتاج باشد. اینکه بعداً با کوکی یا توکن هویت را همراه درخواست بفرستید، نقض بیحالتی نیست؛ مخفیکردن «الان در گام ۳ ویزارد هستی» روی سرور هست.
کش
پاسخ باید صریح یا ضمنی کشپذیر یا غیرکشپذیر برچسب بخورد. اگر کشپذیر باشد، کلاینت حق دارد برای درخواست معادل بعدی همان داده را دوباره به کار ببرد. فیلدینگ میگوید این میتواند بعضی تعاملها را حذف کند و کارایی و مقیاس و تأخیر درکشده را بهتر کند. تاوان: دادهٔ کهنه اگر با واقعیت سرور فاصلهٔ زیاد داشته باشد. موجودی فروشگاه را بدون سیاست تازگی کش نکنید.
رابط یکنواخت
فیلدینگ این را ویژگی مرکزی میداند که REST را از سبکهای شبکهای دیگر جدا میکند. عمومیت رابط، معماری را ساده و تعامل را دیدپذیر میکند و پیادهسازی را از خدمت جدا میکند. تاوان: کارایی؛ داده به شکل استاندارد منتقل میشود نه به شکل بهینهٔ یک کاربرد خاص. REST برای انتقال درشتدانهٔ ابررسانه طراحی شده، نه برای هر نوع تعامل.
چهار قید رابط: شناسایی منابع؛ دستکاری منابع از طریق بازنمایی؛ پیام خودتوضیح؛ ابررسانه بهعنوان موتور حالت کاربرد (HATEOAS). بیشتر تیمها دو مورد اول را جدی میگیرند و دو مورد بعد را تقریبی. اگر HATEOAS ندارید، دروغ نگویید که «کاملاً REST» هستید؛ بگویید HTTP API منبعمحور.
سامانهٔ لایهای
هر جزء فقط لایهٔ مجاور را میبیند. پیچیدگی کراندار میشود، سیستم کهنه کپسول میشود، و واسطه میتواند بار را پخش کند یا سیاست امنیتی مرز سازمان را اعمال کند. تاوان: سربار و تأخیر. فیلدینگ میگوید کش مشترک روی مرز سازمان میتواند این تاوان را جبران کند.
کد هنگام تقاضا (اختیاری)
کلاینت میتواند با دانلود کد گسترش یابد. قید اختیاری است و در API دادهٔ امروز کمتر محور تصمیم است.
منبع، شناسه، بازنمایی
کلید انتزاع در REST منبع است: هر چیز نامپذیر — سند، «هوای امروز»، مجموعه، حتی شخص. منبع نگاشت مفهومی است، نه موجودیت یک لحظه. «نسخهٔ مرجح» و «نسخهٔ چاپشده» دو منبعاند حتی اگر امروز یک فایل باشند. بازنمایی دنبالهٔ بایت بهعلاوهٔ فراداده است (HTML، JPEG، JSON)؛ نوع رسانه تفسیر را میگوید.
Microsoft: هر منبع URI یکتا دارد؛ کلاینت با همان URI بازنمایی میگیرد. اسم جمع برای مجموعه (/orders)، نه فعل (/create-order). فعل را HTTP میگوید. URI را آینهٔ جدول پایگاه نکنید؛ API انتزاع کسبوکار است.
افعال HTTP: معنا، ایمنی، تکرارپذیری
MDN روشهای درخواست HTTP را گاهی فعل مینامد. GET بازنمایی منبع را میخواهد و نباید برای تغییر استفاده شود. POST موجودیتی را میفرستد و اغلب وضعیت سرور را عوض میکند. PUT همهٔ بازنماییهای جاری را با محتوای درخواست جایگزین میکند. DELETE منبع را حذف میکند. PATCH اصلاح جزئی اعمال میکند.
سه ویژگی مشترک در جدول MDN مهماند. ایمن (Safe): اثر نباید از خواندن فراتر برود — GET ایمن است، POST نه. تکرارپذیر (Idempotent): تکرار همان درخواست نتیجهٔ یکسان میدهد — PUT و DELETE تکرارپذیرند، POST معمولاً نه. کشپذیر: GET معمولاً بله؛ POST و PATCH فقط با شرایط صریح. اگر «ثبت سفارش» را روی GET بگذارید، کش و پیشواکشی مرورگر میتواند سفارش تکراری بسازد. این باگ محصول است، نه بدشانسی.
Microsoft نگاشت قراردادی مجموعه/آیتم را اینطور جمع میکند: POST روی /customers مشتری جدید؛ GET همان مجموعه را میخواند؛ GET روی /customers/1 جزئیات یک مشتری؛ PUT همان را جایگزین میکند؛ DELETE حذف میکند. لازم نیست همهٔ فعلها را پیاده کنید. فعلی که معنا ندارد را با ۴۰۵ ببندید، نه با منطق پنهان.
| فعل | طبق MDN چه میکند | ایمن / تکرارپذیر | مثال فروشگاه |
|---|---|---|---|
| GET | بازنمایی منبع را میگیرد؛ فقط خواندن | بله / بله | خواندن موجودی کالای ۱۲۴ |
| POST | ارسال موجودیت؛ اثر جانبی روی سرور | خیر / خیر | ثبت سفارش جدید |
| PUT | جایگزینی کامل بازنمایی | خیر / بله | بازنویسی آدرس تحویل |
| PATCH | اصلاح جزئی | خیر / نه لزوماً | فقط تغییر وضعیت سفارش |
| DELETE | حذف منبع | خیر / بله | لغو پیشنویس سفارش |
REST در برابر RPC و GraphQL — بدون برندهٔ مطلق
AWS RPC را اینطور تعریف میکند: کلاینت یک تابع روی سرور کامل میکند و خروجی را میگیرد. IBM JSON-RPC را فراخوانی رویه با JSON میداند. منطق این سبک «فعل» است: /calculateTax یا /reserveStock. وقتی مسئله واقعاً رویه است — محاسبه، شروع گردش چندمرحلهای، فرمان بدون منبع پایدار — RPC یا دستکم URI تابعمانند صادقانهتر از این است که منبع جعلی بسازید.
GraphQL از نظر IBM زبان پرسوجو و زماناجرای سمت سرور است: کلاینت با چند خط همان دادهٔ لازم را میخواهد، نه چند endpoint پرپارامتر. محدودیت REST که IBM نام میبرد ساخت ثابت و برگرداندن کل شیء است؛ درخواست پیچیده چند منبع را چند تماس میکند و کمواکشی یا بیشواکشی پیش میآید. GraphQL این را بهتر هدف میگیرد. IBM همانجا میگوید REST پیادهسازی آسانتری دارد و وقتی پروتکل کشپذیر با کنترل دسترسی سخت میخواهید — مثل برخی فروشگاههای عمومی — rational است. GraphQL برای محیط پیچیده با نیاز فرانتِ سریعتغییر مناسبتر است.
gRPC در فهرست IBM چارچوب RPC با HTTP/2 و Protobuf است و در میکروسرویس داخلی رایج است. WebSocket کانال دوطرفه بعد از برقراری اتصال است؛ AWS آن را برای پیام لحظهای کاراتر از REST میداند چون سرور میتواند به کلاینت پوش بفرستد. هیچکدام «شکست REST» نیستند؛ مسئلهٔ متفاوتاند.
| اگر مسئله این است | سبک نزدیکتر | چرا | نشانهٔ اشتباه |
|---|---|---|---|
| منبع پایدار، کلاینت متنوع، کش و واسطه مهم | REST روی HTTP | رابط یکنواخت و پیام خودتوضیح به کش و تکامل مستقل کمک میکند | هر عمل را /doX با POST کردن |
| فرانت هر هفته فیلد عوض میکند و چند منبع میخواهد | GraphQL | یک درخواست، دقیقاً همان شکل لازم (طبق IBM) | یک endpoint REST غول که همه چیز را برمیگرداند |
| فرمان/محاسبه بدون منبع پایدار | RPC / gRPC | مدل ذهنی رویه است نه سند | منبع جعلی /taxCalculationResults |
| جریان لحظهای دوطرفه | WebSocket یا رویداد سمت سرور | REST درخواست/پاسخ درشتدانه است | polling هر ثانیه روی GET |
چه زمانی REST مناسب است
وقتی موجودیتهای کسبوکار نامپذیرند و عمر دارند: کالا، سبد، سفارش، مشتری. وقتی چند کلاینت (وب، اپ، شریک) باید همان قرارداد را بفهمند. وقتی میخواهید CDN یا کش معکوس پاسخ خواندنی را نگه دارد. وقتی استقلال سکو مهم است — Microsoft آن را اصل میداند: HTTP استاندارد، مستند روشن، قالب آشنا مثل JSON.
فروشگاه نمونه: خواندن کاتالوگ و موجودی با GET کشپذیر، ایجاد سفارش با POST، جایگزینی آدرس با PUT، لغو پیشنویس با DELETE. کلاینت وب و کلاینت انبار هر دو همان URI را میبینند. تغییر الگوریتم رزرو پشت منبع «موجودی» میماند.
AWS فایدهٔ REST را یکپارچگی سریع، نوآوری در سطح API بدون بازنویسی کل سیستم، گسترش روی سکوهای مختلف، و نگهداری بهخاطر درگاه بودن API میشمارد. اینها وقتی درستاند که قید بیحالتی و منبعمحوری واقعاً رعایت شوند، نه وقتی یک POST بزرگ همهٔ منطق را ببلعد.
چه زمانی REST را فشار ندهید
گزارش تجمیعی با فیلتر پیچیده و شکل متفاوت برای هر داشبورد ممکن است با یک منبع REST یا شلوغ شود یا کمواکشی بسازد؛ GraphQL یا endpoint گزارش جدا صادقتر است. فرمان «شروع تسویهٔ شبانه» منبع نیست. همگامسازی دوطرفهٔ حضور آنلاین با GET تکراری، کانال را اشتباه گرفته. تماس داخلی پرحجم سرویسبهسرویس با JSON متنی ممکن است هزینهٔ سریالایز بیدلیل بدهد؛ gRPC را دستکم ارزیابی کنید.
فیلدینگ خودش تاوان رابط یکنواخت را نوشته: برای تعاملهایی که به شکل اختصاصی نیاز دارند بهینه نیست. اگر تیم برای «REST بودن» منبع مصنوعی میسازد تا فعل را پنهان کند، هزینه را بدون فایده خریدهاید. Microsoft هم میگوید بعضی عملها به منبع مشخص نگاشت نمیشوند و میتوان آنها را با احتیاط بهصورت تابع در URI گذاشت؛ ولی باید کممصرف باشد.
محدودیت عملی دیگر: HATEOAS کامل ابزار و عادت کلاینت میخواهد که بسیاری از اپهای موبایل ندارند. اگر کلاینت URIها را سخت مینویسد، سطح سه را در اسلاید نگذارید. قرارداد نسخهبندیشدهٔ سطح دو، صادقتر از HATEOAS نمایشی است.
نسخه، خطا، و توصیف قرارداد
حتی API منبعمحور عوض میشود. برای REST عمومی، نسخه در URI یا نوع رسانه رایجتر است چون کش کلید را میفهمد؛ تاریخ بازنشستگی را بنویسید. کد وضعیت بخشی از رابط یکنواخت است — اگر همهچیز را با ۲۰۰ و ok:false برگردانید، واسطه را کور کردهاید. جزئیات تشخیص در ۰۲۲ است.
OpenAPI توصیف ماشینخوان قرارداد HTTP است (قبلاً Swagger)؛ مفید برای مستند و آزمون، ولی خودِ REST یا تعریف فیلدینگ نیست. JSON:API هم فقط یک قرارداد بازنمایی است. اگر استفاده میکنید، قرارداد-اول بنویسید؛ اگر نه، برای «کامل به نظر رسیدن» واردش نکنید.
چکلیست تصمیم قبل از برچسب REST
- موجودیتهای نامپذیر دارید یا فقط فرمان؟
- هر درخواست بدون حافظهٔ پنهان سرور فهمیده میشود؟
- GET اثر جانبی ندارد؟
- پاسخهای خواندنی برچسب کش دارند؟
- URI اسم است نه فعل؟
- کلاینتهای آینده باید مستقل از طرح پایگاه بمانند؟
- اگر جواب «نه» به بیش از دو مورد است، سبک را دوباره انتخاب کنید.
اگر چهار مورد اول «بله» است، REST روی HTTP معمولاً مسیر کماصطکاک تیم مختلط محصول و مهندسی است. اگر فقط «JSON میفرستیم» بله است، برچسب را عوض کنید تا انتظار HATEOAS و کش درست شکل نگیرد.
جمعبندی
REST سبک معماری فیلدینگ است: منبع، بازنمایی، رابط یکنواخت، بیحالتی، کش، لایه. HTTP افعال و کد وضعیت را برای پیادهسازی رایج فراهم میکند؛ MDN معنا و ایمنی و تکرارپذیری را جدول کرده است. REST همیشه بهترین نیست. در برابر رویه، پرسوجوی انعطافپذیر فرانت، و جریان لحظهای، RPC و GraphQL و WebSocket rationalاند — IBM و AWS همین تنوع را گزارش میکنند.
قدم بعدی: سه عمل محصول را روی کاغذ به منبع + فعل ترجمه کنید. اگر ترجمه مصنوعی شد، سبک را عوض کنید، نه اسم منبع را.
برای تعریف خودِ API به ۰۳۶ برگردید. برای قالب بدنه به ۰۳۸. برای همراه کردن هویت با درخواست بیحالت، ۰۴۵ را بخوانید.
منابع و مراجع
- Roy T. Fielding — Architectural Styles and the Design of Network-based Software Architectures، فصل ۵ Representational State Transfer: https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
- MDN Web Docs — Overview of HTTP: https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Overview
- MDN Web Docs — HTTP request methods: https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods
- IBM Think — What is an API (application programming interface)؟ (بخش REST و GraphQL): https://www.ibm.com/think/topics/api
- Amazon Web Services — What is an API؟ (بخش REST APIs): https://aws.amazon.com/what-is/api/
- Microsoft Learn / Azure Architecture Center — Web API design best practices: https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design
اگر بعد از این صفحه هنوز بین منبع و رویه مردد هستید، اول فهرست عملهای محصول را بنویسید؛ سبک را آخر انتخاب کنید.
Author
SE
Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.
Related notes
If you are unsure about architecture or the build path, we can talk about the project.
Describe the problem and the constraints. If there is a fit, we will schedule a conversation.




