REST یکی از تاثیرگذارترین ایده ها در معماری توزیع شده است. در اینجا دلیل اهمیت و نحوه درک خدمات RESTful در تئوری و عمل آمده است.
REST یا Representational State Transfer، سبک معماری فراگیر است که به این سوال اساسی پاسخ می دهد: وب سرورها و مشتریان چگونه با هم ارتباط برقرار می کنند؟ از میان تمام کلمات اختصاری موجود در سراسر جهان مهندسی نرم افزار، REST یکی از رایج ترین آنها است. همچنین یکی از رایج ترین مواردی است که سوء تفاهم می شود. این مقاله یک راهنمای سریع برای REST هم در تئوری و هم در عمل ارائه می دهد. به عبارت دیگر، هم به نظریه REST و هم به نحوه پیادهسازی آن که بیشتر به شکل RESTful API است نگاه میکنیم.
REST در تئوری
ساختن نرم افزار برای توزیع در اینترنت مستلزم درجه ای از پیچیدگی است. پشته TCP/IP و HTTP یک مکانیسم اساسی برای تبادل داده ها از طریق سیم به ما می دهد، اما پروتکل ها به همین جا ختم می شوند. توسعه دهندگان نرم افزار مجبور شده اند رویکردهای سطح بالاتر خود را برای سازماندهی نحوه بسته بندی و توزیع منابع از طریق برنامه های کاربردی وب طراحی کنند.
در این مقدمه بر REST، روی فیلدینگ با توضیحات جامع شروع کرد از نقاط قوت و ضعف معماری های مختلف وب در آغاز قرن. او نتیجه گرفت که مدیریت پیچیدگی سیستم های شبکه ای سخت است و توسعه دهندگان به راهی برای حفظ ویژگی های مفید مانند مقیاس پذیری، قابلیت اطمینان و عملکرد بدون به خطر انداختن سادگی نیاز دارند.
Fielding سپس REST را به عنوان راه حل معماری پیشنهاد کرد. پیچیدگی توزیع نرم افزار از طریق اینترنت یک خلاصه سطح بالا از پیشنهاد او ممکن است این باشد: مولفهها باید وضعیت داخلی خود را در قالبی استاندارد و اجرایی-آگنوستیک منتقل کنند. به عبارت دیگر، یک معماری وب باید از اجزای جدا شده تشکیل شده باشد که توسط یک پروتکل استاندارد ارتباط برقرار می کنند. این به سادگی طراحی خوبی بود، اگرچه برای یک فضای مشکل بزرگ اعمال می شد. اما فیلدینگ چیز خاص تری در ذهن داشت:
نام “انتقال وضعیت نمایندگی” برای برانگیختن تصویری از نحوه رفتار یک برنامه وب با طراحی خوب در نظر گرفته شده است: شبکه ای از صفحات وب (یک ماشین دولتی مجازی)، که در آن کاربر با انتخاب پیوندها از طریق برنامه پیشرفت می کند ( انتقال وضعیت)، در نتیجه صفحه بعدی (نماینده وضعیت بعدی برنامه) به کاربر منتقل می شود و برای استفاده او ارائه می شود.
برجستگی صفحات وب و پیوندها را در آن توضیحات مشاهده خواهید کرد. REST در اصل به هایپر مدیا (به ویژه HTML) و هایپرلینک ها اشاره داشت. اساساً، یک وب سرویس منابع را در URL ها و URI های مختلف میزبانی می کند. هنگامی که یک کاربر با یک منبع تماس می گیرد، سرویس با یک صفحه HTML پاسخ می دهد. صفحه حاوی پیوندهایی است که می توان از آنها برای پیمایش به منابع دیگر استفاده کرد و بنابراین این روند ادامه می یابد. این چشم انداز از بسیاری از اهداف طراحی نرم افزار خوب پشتیبانی می کند: رابط های یکنواخت، اجزای بدون حالت، منابع قابل ذخیره سازی، و خدماتی که می توانند ترکیب یا لایه بندی شوند.
REST در عمل: RESTful APIs
این روزها، رایجترین رویکرد REST به شکلی که در ابتدا تصور میشد کار نمیکند. در عوض، توسعهدهندگان معمولاً از HTTP API و JSON برای ارائه دادهها برای برنامهها در وب استفاده میکنند. به همین دلیل است که شما اغلب معماری به اصطلاح REST را می شنوید که به عنوان RESTful توصیف می شود – مانند چیزی شبیه به REST. (شاید REST-ish دقیق تر باشد.)
در سبک RESTful، یک کلاینت با استفاده از یک URL با فرمت معمولی (یک API RESTful) منبعی را درخواست میکند و یک پاسخ JSON با قالببندی معمولی را دریافت میکند که منبع را با استفاده از جفتهای کلید/مقدار توصیف میکند.
URL معمولی و پاسخهای JSON ویژگیهای متمایز برنامههای وب مدرن RESTful هستند. در این سبک، مسیر URL محل وجود یک دارایی و فعل HTTP نحوه دستکاری آن را توضیح می دهد. برای مثال، اگر یک API دارید که حاوی دادههایی درباره موسیقی است، ممکن است یک URL نقطه پایانی مانند musicservice/albums/1234
داشته باشید، که در آن ۱۲۳۴ شناسه یک دارایی معین است. اگر درخواست GET
را در آن نقطه پایانی صادر کنید، یک سند JSON برای آن دارایی پس خواهید گرفت، چیزی شبیه به این:
Response:
{
id: 1234,
name: “Abbey Road”,
band: “The Beatles”,
year: 1969,
best_song: “Come Together”
}
در فهرست ۱، می بینید که نقطه پایانی با داده هایی پاسخ می دهد که دارایی را توصیف می کند. این به این الزام احترام می گذارد که سرویس چیزی در مورد پیاده سازی فاش نکند. افعال دیگر به شما امکان می دهند منبع را حذف کنید (HTTP DELETE
)، آن را تغییر دهید (HTTP PUT
)، یا یک منبع جدید ایجاد کنید (HTTP POST
).
ساختار API سفت و سخت نیست. قانون اصلی این است که درخواستهای GET
نباید چیزی را تغییر دهند (به عبارت دیگر، GET
idempotent است). اغلب، درخواست GET
به نقطه پایانی musicservice/albums
فهرستی از آلبوم ها را برمی گرداند. نقطه پایانی همچنین از پارامترهای فیلتر و/یا پرس و جو به عنوان بخشی از URL پشتیبانی می کند، مانند این:
musicservice/albums?band_name=”pink_floyd”&years=”۱۹۷۳-۱۹۸۰”&sort=alpha
با پیچیدهتر شدن API، نمایش منابع کمتر سازگار میشود. فرض کنید MusicService API ما از برچسبگذاری آلبومها بر اساس سبک یا سبک پشتیبانی میکند. می توانید یک برچسب را به یک آلبوم یا یک آلبوم را به یک برچسب مرتبط کنید. در بسیاری از موارد، رویکرد در یک API RESTful به سبک و اولویت خلاصه می شود. قاعده ای که بیش از همه مهم است این است: تا حد امکان سازگار باشید. شما میخواهید که نحو URL سازگار باشد تا برای کسی که کد را در API مینویسد، انجام وظیفهاش آسان باشد.
قراردادهای دیگر شامل استفاده از فعل POST HTTP برای افزودن یک منبع جدید است. در این حالت، URL معمولاً یک شی JSON را با ویژگی های شی جدید می پذیرد. برای به روز رسانی معمولا از PUT استفاده می شود. در اینجا URL معمولاً شناسه (/musicservice/albums/1234) و آپلود JSON را با دادههای جدید نگه میدارد.
وقتی این روزها بحثی درباره REST می بینید، معمولاً به معنای این نوع طراحی RESTful است. کلاینت ها در جاوا اسکریپت با استفاده از یکی از بسیاری از چارچوب های موجود نوشته می شوند. درخواستهای سبک Ajax اغلب برای ایجاد تعاملات دقیق در برنامههای تک صفحهای استفاده میشوند. سرویسها (تا و از جمله سرویسهای میکرو) از RESTful API استفاده میکنند زیرا آنها استفاده از انواع پشتههای فناوری را امکانپذیر میکنند، که قراردادهای REST را برای پنهان کردن پیادهسازیهای اساسی خود پذیرفتهاند. سرویسهایی که به این سبک نوشته شدهاند میتوانند با یکدیگر تعامل داشته باشند تا درخواستها را به روشی سازگار و قابل تعامل انجام دهند.
REST در مقابل SOAP
REST در تئوری نوعی معماری خدمات خود توصیفی است که در آن مشتریان میدانند استانداردها چیست و سرویس دادههایی را منتشر میکند که با آن استانداردها مطابقت دارد. مشتری کم و بیش می تواند بدون دانستن چیزی در مورد ساختار خدمات ادامه دهد. در طرف دیگر این طیف، سبکی از رابطه سرویس مشتری به نام تماس رویه از راه دور یا RPC وجود دارد. در این مدل، مشتری و سرور از قبل یک قرارداد رسمی ایجاد می کنند که ماهیت دقیق تعاملات آنها را مشخص می کند. سپس در حالتی مشابه با فراخوانی رویه در کد محلی ارتباط برقرار می کنند. RPC فراخوانی تابع کد معمولی را روی تماس های شبکه نگاشت می کند.
RPC مزایایی دارد از این جهت که دقیقتر است و به برنامهریزی و خدمات و مشتریان کاملاً تعریفشده کمک میکند. نقطه ضعف RPC سختی آن است. هر زمان که یک سرویس گیرنده یا سرور تغییر کند، دیگری نیز باید تغییر کند، و همچنین مکانیسمی که قرارداد را تعریف می کند.
RPC و SOAP
مشهورترین نمونه RPC احتمالاً SOAP (پروتکل دسترسی به شیء ساده) است. در این سیستم، مشتریان و سرورها از تعاریف XML برای توصیف قراردادهای خود استفاده می کنند. SOAP بخش بزرگی از جنبش SOA (معماری خدمات گرا) در آغاز قرن بود. در این مدل، سرویسها تعاریف سرویس را نشان میدهند و مشتریان میتوانند آنها را برای کشف قابلیتها تجزیه کنند. این ایده واقعاً به نتیجه نرسید، اما عمدتاً به دلیل پیچیدگی بود. SOA و SOAP سربار زیادی را به کارهای پیچیده ای که توسعه دهندگان باید انجام می دادند اضافه کردند. (برای مروری بر رویکرد مدرن تر RPC به معرفی gRPC: جایگزین REST مراجعه کنید.)
REST در تئوری با اجازه دادن به سرویس دادهها در قالبی که خودش را توصیف میکند، از قراردادهای منحصربهفرد بین مشتریان و سرورها صرف نظر میکند. این باعث انعطاف بیشتر و حفظ قابلیت (نبوغ کاغذ فیلدینگ) می شود.
REST همانطور که تمرین می شود بیشتر یک نقطه میانی طبیعی است. در جایی که RPC و SOA از قراردادهای رسمی مشتری و سرور استفاده می کنند، REST و JSON مانند REST از این کار استفاده نمی کنند. در جایی که REST کلاینت ها و سرورها را جدا می کند (با دانش قبلی محدود از خدمات روی کلاینت)، کلاینت های REST مانند با سرور جفت می شوند (آنها از پیش آگاهی از سرویس دارند). شکل ۱ تفاوت بین این دو معماری را نشان می دهد.
شکل ۱. REST کلاینتها و سرورها را جدا میکند، اما کلاینتهای REST مانند با سرور جفت میشوند.
وقتی می گوییم مشتریان REST از قبل اطلاعی از سرویس ندارند، به این معنی است که آنها از جزئیات آن اطلاعی ندارند. آنها ممکن است و احتمالاً درباره ساختارها و مفروضات استاندارد در حال استفاده بیشتر بدانند. به عبارت دیگر، یک مشتری REST واقعی در مورد استانداردها پیچیده تر است، تا در مورد جزئیات کمتر پیچیده باشد.
خدمات REST مانند (یعنی سرویسهای JSON-URL) در واقع سرعت توسعه را به حداکثر میرسانند. به این ترتیب، جای تعجب نیست که این مدل بیشترین کشش را برای استفاده در دنیای واقعی پیدا کرده است.
در مورد HATEOAS چطور؟
عیب رویکرد REST مانند این است که به سمت پیچیدگی گرایش دارد. در این مورد، از دیدگاه روی فیلدینگ برای REST متفاوت است. پیچیدگی طراحی RESTful به وضوح در پیچیدگی کلاینت های وب مدرن دیده می شود، که باید بتوانند JSON را دریافت کنند و به صورت پویا آن را به رابط های کاربری تعاملی تبدیل کنند.
مسئله اینجاست که اکثر توسعه دهندگانی که REST را به عنوان یک سبک معماری اجرا می کنند، یکی از ستون های اصلی آن – اصل HATEOAS – را رها کرده اند. این مخفف عجیب غیرجذاب مخفف Hypermedia as the Engine of Application State است. اساساً به این معنی است که ما فقط باید هایپرمدیا را از سرویس ها صادر کنیم – ایده ای که مستقیماً با صدور JSON به عنوان ابزار توزیع مخالف است. فیلدینگ این اصل را محدودیت هایپررسانه می نامد و او در مورد اشاره به نقض گسترده آن:
یک API REST نباید نام منابع ثابت یا سلسله مراتب را تعریف کند (یک جفت آشکار مشتری و سرور). سرورها باید آزادی کنترل فضای نام خود را داشته باشند. در عوض، به سرورها اجازه دهید تا با تعریف این دستورالعمل ها در انواع رسانه ها و روابط پیوند، به مشتریان در مورد نحوه ساخت URI های مناسب، مانند آنچه در فرم های HTML و قالب های URI انجام می شود، آموزش دهند. [شکست در اینجا نشان میدهد که کلاینتها یک ساختار منبع را به دلیل اطلاعات خارج از باند، مانند یک استاندارد خاص دامنه، که معادل دادهگرایانه کوپلینگ عملکردی RPC است، فرض میکنند.]
واضح است که اکثر API های RESTful این جنبه اساسی سبک REST را نادیده می گیرند، جایی که مشتریان قرار است به سادگی خروجی سرویس ها را دنبال کنند – از جمله تمام داده های مورد نیاز برای تعامل با سرویس ها. ماهیت هایپر مدیا این است که هم دارایی ها و هم نحوه پیمایش آنها را توضیح می دهد. (کارسون گراس، خالق HTMX، اخیراً با پست وبلاگ خود به این موضوع پرداخته است، چگونه REST به معنای مخالف REST شد؟. ارزش خواندن را دارد.)
نتیجه گیری
انتقادات از سبک RESTful در مقابل طرح اصلی REST معتبر است. حفظ سرویسهای JSON/HTTP دشوار است و REST-as-inted ممکن است امیدی برای بهبود داشته باشد. در عین حال، استفاده در دنیای واقعی پاسخ های JSON بر اساس ساختارهای URL RPC مانند باقی می ماند. این سبک دارای مزیت استفاده متداول، اجرای گسترده و معناشناسی است که به راحتی قابل درک است.
امروزه هر توسعهدهنده وب در حال کار باید اصول اولیه REST (تئوری) و نحوه کاربرد گسترده آنها در برنامهها و رابطهای RESTful (عمل) را درک کند. هر دو ارزش در نظر گرفتن را دارند زیرا ما همچنان به ساخت این هواپیمای اینترنتی ادامه می دهیم.
پست های مرتبط
REST چیست؟ استاندارد معماری وب واقعی
REST چیست؟ استاندارد معماری وب واقعی
REST چیست؟ استاندارد معماری وب واقعی