URL ها و action ها در REST

shape
shape
shape
shape
shape
shape
shape
shape

URL ها و action ها در REST

شاید به توان گفت یکی از کلیدی ترین اصول طراحی سرویس های مبتنی بر REST جداسازی و طراحی API در قالب منابع منطقی متفاوت است. در واقع تمام هدف RESTTاین است که این منابع را بگونه ای در اختیار کلاینت ها قرار دهد تا از آنها استفاده کنند، تغییراتی در آنها دهند و یا آنها را حذف کنند. یکی از نکات مثبت سرویس های RESTاین است که دسترسی کلاینت ها به این منابع از طریق درخواست های HTTP انجام می گیرد. این درخواست ها با متد های مختلفی می توانند ارسال شوند که هر یک معنا و مفهومی خاص را دارد. این متد ها عبارتند از GET، POST ، PUT، DELETE و … که کاربرد هریک با دیگری متفاوت است.

گفتیم که اصل در سرویس های REST فراهم کردن منابع برای کلاینت هاست. کلاینت ها نیز از طریق درخواست های HTTP باید به آنها دسترسی داشته باشند.بنابر این در سرویس های URL,REST ها نقش مهمی را بازی می کنند. آنها هستند که مشخص کننده یک منبع می باشند. بنابراین انتخاب نام مناسب برای آنها از اهمیت بسیاری برخوردار است. پیشنهاد می شود برای نام گذاری منابع از اسامی استفاده کنید. استفاده از اسامی به دلیل ماهیت و نحوه استفاده از وب سرویس RESTful خوانایی URL را برای استفاده کنندگان از وب سرویس بیشتر می کند.

خیلی از برنامه نویس ها در هنگام طراحی منابع وب سرویس خود به دنبال نگاشت یک به یک بین مدل های برنامه خود و منابع وب سرویس خود هستند. مثلا اگر مدلی بنام User دارند سعی دارند که برای دستیابی به مدل User منبعی به همین نام (user) را فراهم کنند. این مسئله بسیار خوب و مطلوب است. اگر بتوان چنین نگاشتی را فراهم کرد خیلی خوب است اما توجه داشته باشید که برقراری این نگاشت یک به یک ضروری نیست و مهمتر از آن خوانایی و با معنا بودن نام منابع شماست.

پس از تعیین نام برای منابع و تعریف آنها شما نیاز به تعریف عملیات مختلف بر روی منابع را دارید. شما باید مشخص کنید بر روی یک منبع (مثلا user) چه عملیاتی قابل انجام است و این عملیات چگونه باید توسط کاربر درخواست شده و توسط سیستم به actionهای شما نگاشت داده شوند. توجه داشته باشید که بر اساس اصول REST شما تنها مجاز به پیاده سازی عملیات محدودی بر روی هر منبع خود هستید. این تعداد را تعداد متد های HTTP مشخص میکند(POST، GET، PUT، DELETE، PATCH و …(. بر اساس این متد ها شما قادر به پیاده سازی عملیات CRUD برای منابع خود هستید.

اما چگونه سیستم,عمل نگاشت بین درخواست HTTP و عملیات CRUD را انجام می دهد؟ در جواب باید گفت این کار بر اساس متد های درخواست صورت می گیرد.

در زیر نحوه استفاده از متد ها و معنای هرکدام آورده شده است:

متد GET به منظور بازیابی و خواندن منبع استفاده می شود.

GET /users – Retrieves a list of users

GET /users/21 – Retrieves a specific user

متد POST زمانی استفاده می شود که بخواهیم منبع جدیدی را ایجاد کنیم.

POST /users – Creates a new user

متدهای PUT و PATCH برای دستکاری در یک منبع مورد استفاده قرار می گیرند.

PUT /users/21 – Updates user #21

PATCH /users/21 – Partially updates user #21

متد DELETE نیز به منظور حذف یک منبع مورد استفاده قرار می گیرد.

DELETE /users/21 – Deletes user #21

توجه داشته باشید که ما با استفاده از متد های HTTP توانستیم عملیات مختلفی را بر روی یک آدرس ( users/ ) پیاده سازی کنیم. هیج نیازی به آوردن نام عملیات یا متد مورد نظر در آدرس URL نیست که این مسئله باعث تمیز ماندن و خواناتر شدن آدرس های منابع در سرویس های REST می گردد و این مسئله جزو نقاط قوت سرویس های REST نسبت به سایر سرویس ها می باشد.
حال این سوال را باید پاسخ دهیم که نام منابع بهتر است مفرد بیاید یا جمع؟ جواب این است که اگرچه در قواعد گرامری استفاده از اسم جمع برای یک منبع واحد صحیح نیست، اما در این جا باید گفت که به منظور بالا بردن خوانایی و با معنا تر شدن نام های منابع توصیه می شود که از نام های جمع استفاده کنید. بنابراین بجای استفاده از /user از /users استفاده کنید.

در یک برنامه کاربردی در بسیاری از مواقع ممکن است در کنار یک منبع بخواهیم به منابع مرتبط با آن نیز دستیابیم. بنابراین این سوال مطرح می شود که برای دستیابی به چنین ارتباطاتی آدرس های URL باید به چه صورتی طراحی شوند. البته در اینجا بایدی وجود ندارد اما پیشنهاد می شود برای دستیابی به منابع مرتبط با یک منبع مانند مثال های زیر عمل کنید. در این مثال ها قصد داریم در کنار دستیابی به منبع user پیام های مرتبط به آن را نیز بازیابی یا دستکاری نماییم :

اگر بخواهیم تمامی پیام های مرتبط با user شماره ۲۱ را بازیابی کنیم بهتر است URL بصورت زیر طراحی شود :

GET /users/21/messages – Retrieves list of messages for user #21

اگر بخواهیم یک پیام خاص از یک user خاص را بازیابی کنیم پیشنهاد می شود بصورت زیر عمل شود:

GET /users/21/messages/7 – Retrieves message #7 for user #21

برای ایجاد، ویرایش و حذف یک پیام در رابطه با یک user خاص فراخوانی سرویس بصورت زیر می باشد :

POST /users/21/messages – Creates a new message in user #21

PUT /users/21/messages/7 – Updates message #7 for user #21

PATCH /users/21/messages/7 – Partially updates message #7 for user #21

DELETE /users/21/messages/7 – Deletes message #7 for user #21

توجه داشته باشید چنانچه منبع مرتبط با منبع اصلی بطور متداول در برنامه شما مورد استفاده قرار می گیرد,برای جلوگیری از ارسال دو در خواست پشت سر هم به سرور (مانند آنچه در روش بالا آن مواجه خواهیم شد) بهتر است منبع وابسته در داخل رشته پاسخ به کلاینت افزوده شود. در این صورت هنگامی که لیست user ها را دریافت می کنیم در کنار هر user پیام های آنها نیز دریافت می شوند. و دیگر کلاینت نیاز به ارسال در خواست دوم برای گرفتن پیام ها نمیباشد.
در طراحی سرویس های REST توسعه دهنده در برخی مواقع نیاز به استفاده از خلاقیت دارد تا بتواند به بهترین شکل ممکن URLمربوط به منابع خود را تعریف کند. فرض کنید action ای در برنامه دارید که در قالب عملیات CRUD نمی توان آن را گنجاند. مثلا فرض کنید می خواهید امکانی را به کلاینت بدهید تا یک کاربر را فعال یا غیر فعال کند. البته این کار را می توان با همان متد UPDATE برای کاربران انجام داد. اما فرض کنید شما می خواهید متدی مخصوص این کار را برای کلاینت فراهم کنید. در چنین مواقعی کار کمی خلاقیتی می شود و راهکار جامعی برای آن وجود ندارد.

یک روش این است که شما action را طوری تغییر دهید که همانند یک فیلد از منبع بنظر برسد. مثلا اگر می خواهید منبع را فعال کنید، action فعال سازی می تواند بصورت یک فیلد فعالسازی مثلا activated از نوع Boolean طراحی شود که با متد PATCHفراخوانی می شود. البته این روش وقتی خوب عمل می کند که action پارامتر نگیرد.

روش دیگر این است که Action بصورت یک sub-resource از منبع طراحی شود. برای مثال در GitHub برای ستاره دار کردن یک gist از فراخوانی PUT /gists/:id/star استفاده می شود. همانطور که می بینید action مربوط به ستاره دار کردن (star) بصورت زیر منبعی ازgists استفاده شده است. برای حذف ستاره نیز از DELETE /gists/:id/start استفاده می شود.

حال شرایطی را در نظر بگیرید که می خواهید چندین منبع را جستجو کنید. در چنین حالتی هیچ راه منطقی برای نگاشت action به یک ساختار منطبق با REST وجود ندارد. در چنین حالتی می توانید یک منبع خاص مثلا /search را در اختیار کاربر قرار دهید. دقت کنید که لغت Search در اینجا نام نیست. بلکه یک فعل است. اما بدلیل آنکه برای این منبع خاص بسیار منطقی و قابل فهم می باشد ما در اینجا بجای استفاده از اسامی جمع، از یک فعل استفاده کردیم. بنابراین می بینید که در مواقع مختلف نیاز است بسته به شرایط تصمیمات خاص گرفته شود. استفاده از Search در اینجا این کمک را می کند که بدون نیاز به مستندات زیادی به برنامه نویس سمت کلاینت بدون آنکه دچار سردرگمی شود اطلاع دهیم که کار این منبع جستجو است.

منبع

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *