آموزش کامل REST FULL

Image تحقیقات

آموزش کامل REST FULL

با سلام خدمت شما دوستان عزیز

مطلب امروز درباره مفهوم REST و REST FUL می باشد و سعی کردم تا جای ممکن شما را با این دو مفهوم آشنا کنم .

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

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

طبقREST این URIها به انتخاب سرور هستند و میتوانند تغییر کنند (کلاینت باید این URI را از خود سرور دریافت کند) و مورد ثابتی در این زمینه وجود ندارد.

از XML برای ارائه منابع استفاده می شود.
از HTTP و متدهای GET, HEAD, POST, PUT, DELETE برای اجرای عملیات استفاده میشود.
از URL به طور معمول برای شناسه یک وبسرویس استفاده میشود و پاسخ داده شده با فرمت XML است.
برای مثال صفحه اصلی یک سایت طبق این معماری یک منبع با شناسه http://www.example.com است.اجزا در این معماری روی منابع عمل میکنند، این معماری شبیه معماری وب میباشد و به خاطر آشنایی توسعه دهندگان با این سبک معماری,بسیار محبوب شد.

در مفهوم REST متدهای HTTP را به عملیات مورد نظر نگاشت میکنند، یعنی وقتی میخواهند یک منبع را حذف کنند (خود منبع که باURIمشخص میشود) درخواست را با HTTP DELETE ارسال میکنند.وقتی میخواهند به آن چیزی اضافه کنند از متد POST استفاده میکنند و برای بازیابی,درخواست را با متد GET ارسال میکنند، و برای بازنویسی منبعی از PUT استفاده میکنند،اما این روش اجباری نیست ولی ترجیح اکید این است که از متدهای پروتکل انتقال برای رساندن این مفاهیم استفاده شود. از متد POST برای ایجاد ،GET برای خواندن ، PUT برای به روز رسانی ،DELETE برای حذف استفاده میشود.با متد POST میتوان هر نوع دیتایی رو با هر فرمتی منتقل کرد و طبیعتا در سمت دیگر با فرمت اصلی بازیابی و خوانده می شود.

طبقREST این URIها به انتخاب سرور هستند و میتوانند تغییر کنند (کلاینت باید این URI را از خود سرور دریافت کند) و مورد ثابتی در این زمینه وجود ندارد.

 

از XML برای ارائه منابع استفاده می شود.
از HTTP و متدهای GET, HEAD, POST, PUT, DELETE برای اجرای عملیات استفاده میشود.
از URL به طور معمول برای شناسه یک وبسرویس استفاده میشود و پاسخ داده شده با فرمت XML است.
برای مثال صفحه اصلی یک سایت طبق این معماری یک منبع با شناسه http://www.example.com است.اجزا در این معماری روی منابع عمل میکنند، این معماری شبیه معماری وب میباشد و به خاطر آشنایی توسعه دهندگان با این سبک معماری,بسیار محبوب شد.

 

در مفهوم REST متدهای HTTP را به عملیات مورد نظر نگاشت میکنند، یعنی وقتی میخواهند یک منبع را حذف کنند (خود منبع که باURIمشخص میشود) درخواست را با HTTP DELETE ارسال میکنند.وقتی میخواهند به آن چیزی اضافه کنند از متد POST استفاده میکنند و برای بازیابی,درخواست را با متد GET ارسال میکنند، و برای بازنویسی منبعی از PUT استفاده میکنند،اما این روش اجباری نیست ولی ترجیح اکید این است که از متدهای پروتکل انتقال برای رساندن این مفاهیم استفاده شود. از متد POST برای ایجاد ،GET برای خواندن ، PUT برای به روز رسانی ،DELETE برای حذف استفاده میشود.با متد POST میتوان هر نوع دیتایی رو با هر فرمتی منتقل کرد و طبیعتا در سمت دیگر با فرمت اصلی بازیابی و خوانده میشود.

آموزش کامل rest full

آموزش کامل rest full

طبق این معماری میتوان سیستمهای مختلفی از جمله وب سرویس را طراحی کرد که به آن RESTful گفته میشود.

 

اصول طراحی وب سرویس های RESTful

امروزه برنامه های سنتی وب در حال حرکت به سمت سرویسی شدن هستند، بدین صورت که کلاینت ها تنها از طریق وب سرویسها با سرور در تماس هستند.به بیانی دیگر ارتباط کلاینت ها با لایه Data Model از طریق وب سرویس ها صورت می پذیرد.در چنین برنامه هایی منطق برنامه کاملا در سمت کلاینت پیاده سازی می شود و سرور دیگر هیچ نقشی جز فراهم کردن داده برای کلاینت هایش را برعهده ندارد.نمونه رایجی از این گونه نگرش برنامه نویسی,برنامه های SPA که مخفف Single Page Application است,می باشد.در اینگونه برنامه ها تمامی منطق برنامه در سمت کلاینت و پیاده سازی می شود و تنها نیازی که برنامه به سرور دارد، فراهم ساختن داده ها می باشد. این نگرش این امکان را می دهد که شما به راحتی و بدون هزینه بالا یک برنامه SPA را به یک برنامه دیگر، مثلا یک برنامه موبایل تبدیل کنید. تنها کاری که انجام می شود این است که باید یک کلاینت برای تلفن همراه بنویسید که از طریق همان API ها با سرور ارتباط برقرار کند.

در نگاه اول پیاده سازی و استفاده از وب سرویس های RESTful بسیار مطلوب و خوش آیند به نظر می رسند. اما باید دقت داشته باشید که اگر در طراحی و پیاده سازی آنها دقت لازم را نکنید، هزینه های جانبی زیادی را در آینده ممکن است به برنامه شما وارد کند که اکثر آنها نیز مربوط به هزینه اعمال تغییرات می باشند.به همین دلیل در این مطلب سعی شده مطالبی گفته شود که به طراحی هرچه بهتر وب سرویس های RESTful کمک کند.

 

اولین و مهمترین نکته ای که باید پیش از شروع به طراحی یک وب سرویس RESTful باید به آن توجه داشته باشید این است که طراحی یک سرویس خوب تنها یک فن نیست، بلکه یک هنر است و نیاز به خلاقیت دارد. در زیر به اصولی کلیدی در طراحی وب سرویس های RESTful اشاره شده است:

وب سرویس شما باید به صورت درست و به جا از استاندارد های وب استفاده کند. مثلا انواع مختلفی از کد های پاسخ HTTPوجود دارند که همه بصورت کلی معنی موفقیت آمیز بودن عملیات را دارند اما هر کدام جایگاه خاصی دارد که در حین استفاده باید به آن دقت نمود.
دقت داشته باشید همانطور که یک برنامه نویس برنامه اش را برای کاربر نهایی می نویسد، شما نیز وب سرویس تان را بعنوان یک برنامه برای برنامه نویس ها می نویسید. بنابراین در اینجا نیز اصل user friendly بودن مصداق دارد و باید به آن توجه نمود.وب سرویس باید طوری نوشته شود که یک برنامه نویس بتواند براحتی با آن کار کند.
اگر وب سرویسی طراحی میکنید خیلی مهم است که توسط مرورگر ها و از طریق نوار آدرس آنها قابل پیمایش باشد.
وب سرویس شما باید تا حد ممکن ساده و به راحتی قابل درک باشد. طوری آن را طراحی کنید که اعمال تغییرات بر اساس نیاز کاربر در آینده قابل انجام باشد.
در طراحی وب سرویس به کارایی و انعطاف پذیر بودن آن توجه کنید.
همانطور که UX برای برنامه های کاربردی مطرح می شود، در مورد وب سرویس ها نیز طوری باید آنها را طراحی کنید که برنامه نویسی که با آنها کار می کند تجربه خوبی داشته باشد.
این ها اصول و مواردی هستند که در تمامی مراحل طراحی وب سرویس ها باید همواره مد نظر قرار گرفته شوند.

 

URL ها و action ها در REST:

شاید به توان گفت یکی از کلیدی ترین اصول طراحی سرویس های مبتنی بر REST جداسازی و طراحی API در قالب منابع منطقی متفاوت است. در واقع تمام هدف RESTاین است که این منابع را بگونه ای در اختیار کلاینت ها قرار دهد تا از آنها استفاده کنند، تغییراتی در آنها دهند و یا آنها را حذف کنند. یکی از نکات مثبت سرویس های 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 زمانی استفاده می شود که بخواهیم منبع جدیدی را ایجاد کنیم.

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

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

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

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

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

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

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

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

توجه داشته باشید چنانچه منبع مرتبط با منبع اصلی بطور متداول در برنامه شما مورد استفاده قرار می گیرد,برای جلوگیری از ارسال دو در خواست پشت سر هم به سرور (مانند آنچه در روش بالا آن مواجه خواهیم شد) بهتر است منبع وابسته در داخل رشته پاسخ به کلاینت افزوده شود. در این صورت هنگامی که لیست 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 در اینجا این کمک را می کند که بدون نیاز به مستندات زیادی به برنامه نویس سمت کلاینت بدون آنکه دچار سردرگمی شود اطلاع دهیم که کار این منبع جستجو است.

 

استفاده از SSL

همیشه و بدون هیچ استثنائی از SSL استفاده کنید. توجه داشته باشید که API شما از هر نقطه ای که دسترسی به اینترنت داشته باشند قابل دسترسی است. بنابراین اگر داده های ارسالی و دریافتی شما رمزگذاری نشوند به راحتی قابل شنود هستند و یک تهدید امنیتی برای سیستم شما به شمار می روند.یکی دیگر از مزایای استفاده از SSL این است که احراز هویت کلاینت ها تضمین می شود و دیگر نیاز به sign کردن API ها نیست. نکته مهم دیگر که باید مد نظر قرار دهید این است که اگر کلاینتی خواست بدونSSL به URL های API شما دسترسی پیدا کند آن را به هیچ وجه به URL های SSL خود هدایت (redirect) نکنید. بجای این کار خطایی به او باز گردانید. بنابراین دسترسی را به URL های SSL محدود کنید.

 

مستند سازی

یک API خوب باید مستندات خوبی نیز داشته باشد. این مستندات باید به راحتی و برای همه برنامه نویسانی که قصد دارند از APIشما استفاده کنند قابل دستیابی باشند. دقت داشته باشید که بیشتر برنامه نویسان پیش از آنکه از API شما استفاده کنند مستندات شما را مطالعه می کنند. بنابر این اگر مستندات شما در قالب فایل های PDF باشند و یا اینکه برای دسترسی نیاز به لاگین داشته باشند هم دسترسی به آنها دشوار می شود و هم آنکه نمی توان با جستجو انها را به راحتی یافت. بنابراین پیشنهاد می شود آنها را در قالب هایی مانند HTML منتشر نمایید.

دقت داشته باشید که مستندات شما علاوه بر توضیحات,بهتر است مثال های کاملی از نحوه ارسال درخواست و دریافت پاسخ داشته باشد. ترجیحا طوری این مثال ها را بنویسید که بتوان آن را براحتی copy/paste کرد. اگر لینک درخواست ها نیز قابل کپی شدن باشند به برنامه نویسانی که قصد استفاده از API شما را دارند بسیار کمک خواهد کرد.

نکته مهم دیگری که باید توجه کنید این است که هر گونه بروز رسانی در API خود را باید در مستندات بیاورید. بعنوان مثال درخواست هایی که دیگر نباید استفاده شوند یا deprecate شده اند و آخرین تغییرات در نحوه دستیابی به API باید به برنامه نویسان اطلاع داده شود. بهتر است این کار را بصورت change log و یا mailing list انجام دهید.

 

Versioning

همیشه و همیشه API خود را نسخه بندی کنید. این مسئله باعث می شود که تکامل API شما راحت تر صورت پذیرد و از به مشکل خوردن کلاینت ها در هنگام تغییرات جلوگیری نماید. شما می توانید تغییرات را براحتی در ورژن جدید اعمال کنید و اجازه دهید کلاینت های قدیمی تر با ورژن قدیمی بدون هیچ مشکلی به کار خود ادامه دهند.

اما سوال اینجاست که ورژن بهتر است در URL مشخص گردد و یا در header درخواست. نظرات مختلفی در این باره وجود دارد. اگر بخواهیم به طور آکادمیک بگوییم بهتر است ورژن در header مشخص شود. اما پیشنهاد می شود که ورژن در URL مشخص شود تا بتوان از پشتیبانی مرورگر نیز بهره مند شد. اگر بیاد داشته باشید در ابتدای این بحث گفتیم که یکی از ویژگی های API خوب این است که بتوان از طریق نوار آدرس آن را پیمایش کرد.

روشی که در اینجا می خواهیم پیشنهاد کنیم آن است که ورژن های اصلی API را در URL مشخص کنید. اما تغییرات جزئی را بدون تغییر ورژن اصلی و با ایجاد زیر ورژن هایی در header در خواست تعیین کنید. بعنوان مثال در URL شما ورژن v1 را مشخص می کنید در header نیز می توانید زیر ورژن های آن را مانند ۱٫۰٫۱ را تعیین نمایید که نشان دهنده تغییرات جزئی تر هستند.

هیچ API ای وجود ندارد که کاملا stable و بدون تغییر باقی بماند. بنابراین ورژن دهی به API یکی از مهمترین کارهایی است که همواره باید آن را مد نظر قرار دهید تا بتوانید مدیریت بهتری بر روی تغییرات خود داشته باشید. همواره مستندات خود را بروز نگه دارید و تغییرات API خود را به اطلاع برنامه نویسان کلاینت ها برسانید.

 

فیلتر کردن

هنگامی که می خواهید نتایج را فیلتر کنید به ازای هر فیلدی که می خواهید فیلتر کنید یک پارامتر در نظر بگیرید و آن را در URL قرار دهید. به عنوان مثال فرض کنید می خواهیم لیستی از کاربران فعال را از سرور دریافت کنیم. در این صورت بهتر است URL شما بصورت users?state=active/ باشد. در این جا state پارامتری است که بر اساس آن می خواهیم نتایج را فیلتر کنیم.

 

مرتب سازی

همانند آنچه در مورد فیلترینگ داشتیم، برای مرتب سازی نیز پارامتری را به URL اضافه می کنیم. معمولا این پارامتر با نام sort اضافه می شود. به عنوان مثال اگر بخواهیم کاربران را بر اساس تاریخ تولدشان مرتب کنیم پیشنهاد می شود بصورت زیر این کار انجام شود :

users?sort=-birth_date/

در مثال بالا با –birth_date مشخص می کنیم که می خواهیم نتایج را به صورت نزولی مرتب  سازی کنیم. اگر بخواهیم مرتب سازی را بر اساس پارامتر های دیگر نیز انجام دهیم پیشنهاد می شود لیست پارا متر ها را با کاما از هم جدا کرده و همه را با هم در قالب پارامتر sort ارسال کنیم. بعنوان مثال اگر بخواهیم کاربران را بر اساس نام و نام خانوادگی مرتب کنیم می توان بصورت زیر عمل نمود :

GET /users?sort=first_name,laste_name

جستجو کردن

در هنگام جستجو کردن در صورتی که از جستجوی تمام متن استفاده می کنید پیشنهاد می شود پارامتری بنام q را برای مشخص کردن رشته مورد جستجو در URL اضافه نمایید.

می توان با ترکیب این سه مورد URL های پیچیده ای و در عین حال خوانایی را بصورت زیر ایجاد نمود :

GET /users?sort=-updated_at
 
GET /users?state=closed&sort=-updated_at
 
GET /users?q=return&state=open&sort=-priority,created_at

 

استفاده از نام های مستعار برای برخی از پرس و جو های رایج

برخی از پرس و جو ها ممکن است بسیار رایج و مورد استفاده باشند. بد نیست برای راحتی کار استفاده کنندگان API های خود این پرس و جو ها را در قالب URL های خاصی در اختیار آنها قرار دهید. به عنوان مثال گرفتن آخرین لیست آخرین محصولات را می توانید در قالب یک مسیر مجزا مثلا GET /products/recently_added در اختیار کاربران قرار دهید.

 

اعمال محدودیت (limit) بر روی فیلد های خروجی API

همان طور که گفته شد برای آن که کاربران بتوانند به یک یا چند منبع دسترسی پیدا نمایند باید در خواستی را با متد GET به سرویسشما ارسال نمایند. در پاسخ به درخواست آن ها دو رویکرد وجود دارد. یکی آن که همیشه کل فیلد های منبع یا منابع را باز گردانید و یا آنکه آنچه را که مورد نیاز کاربر است در اختیار وی قرار دهید. باید گفت کسانی که از API شما استفاده می کنند در بسیاری از مواقع فقط به بخشی از منبع نیاز دارند. بنابراین بهتر است راهکاری را در اختیار آنها قرار دهید تا بتوانند به API شما فیلد های مورد نیازشان را اعلام کنند. به این ترتیب هم API شما بهینه تر عمل می کند و هم آنکه اطلاعات اضافی و غیر ضروری در اختیار کاربران قرار نمی گیرد. علاوه بر این در پهنای باند شبکه صرفه جویی شده و پاسخ به کاربر با سرعت بیشتری می رسد.

برای این منظور پیشنهاد می شود همانند آنچه در مورد search گفتیم عمل شود. مثلا پارامتری با نام fields در URL در نظر بگیرید و به کاربر این امکان را دهید تا فیلد های مورد نیازش را بصورت comma separated به API اعلام نماید. در زیر نمونه ای از این نحوه کار آورده شده است :

GET /users?fields=id,subject,customer_name,updated_at&state=open&sort=-updated_at

استفاده از نام های مستعار برای برخی از پرس و جو های رایج
برخی از پرس و جو ها ممکن است بسیار رایج و مورد استفاده باشند. بد نیست برای راحتی کار استفاده کنندگان API های خود این پرس و جو ها را در قالب URL های خاصی در اختیار آنها قرار دهید. به عنوان مثال گرفتن آخرین لیست آخرین محصولات را می توانید در قالب یک مسیر مجزا مثلا GET /products/recently_added در اختیار کاربران قرار دهید.

اعمال محدودیت (limit) بر روی فیلد های خروجی API
همان طور که گفته شد برای آن که کاربران بتوانند به یک یا چند منبع دسترسی پیدا نمایند باید در خواستی را با متد GET به سرویسشما ارسال نمایند. در پاسخ به درخواست آن ها دو رویکرد وجود دارد. یکی آن که همیشه کل فیلد های منبع یا منابع را باز گردانید و یا آنکه آنچه را که مورد نیاز کاربر است در اختیار وی قرار دهید. باید گفت کسانی که از API شما استفاده می کنند در بسیاری از مواقع فقط به بخشی از منبع نیاز دارند. بنابراین بهتر است راهکاری را در اختیار آنها قرار دهید تا بتوانند به API شما فیلد های مورد نیازشان را اعلام کنند. به این ترتیب هم API شما بهینه تر عمل می کند و هم آنکه اطلاعات اضافی و غیر ضروری در اختیار کاربران قرار نمی گیرد. علاوه بر این در پهنای باند شبکه صرفه جویی شده و پاسخ به کاربر با سرعت بیشتری می رسد.

برای این منظور پیشنهاد می شود همانند آنچه در مورد search گفتیم عمل شود. مثلا پارامتری با نام fields در URL در نظر بگیرید و به کاربر این امکان را دهید تا فیلد های مورد نیازش را بصورت comma separated به API اعلام نماید. در زیر نمونه ای از این نحوه کار آورده شده است :پس از انجام عملیات درج و بروزرسانی منبع را نیز بازگردانید
همانطور که گفتیم فراخوانی های PUT، POST و PATCH برای اعمال تغییرات بر روی منابع استفاده میشوند. از آنجایی که در بسیاری از مواقع برنامه نویسان پس از اعمال اینگونه تغییرات، می خواهند منبع تغییر یافته یا ایجاد شده را نمایش دهند و یا از آن استفاده نمایند، پیشنهاد می شود برای جلوگیری از فراخوانی مجدد جهت دریافت منبع ، منبع تغییر یافته در پاسخ بازگردانده شود تا برای استفاده های آتی در اختیار برنامه نویسان قرار گیرد.

در مورد POST دقت کنید که بهتر است در پاسخ علاوه بر خود منبع، کد HTTP 201 (کد HTTP 201 به معنی دریافت موفقیت آمیز درخواست و ساخته شدن یک منبع جدید در سرور است (به فرض ایجاد یک فایل یا صفحه جدید)، ارسال کد ۲۰۱ تنها در صورتی صحیح است که سرور منبع جدید را ساخته باشد، در غیر اینصورت (اگر منبع هنوز ساخته نشده باشد) باید کد ۲۰۲ را ارسال کند.) را بازگردانید. علاوه بر آن هدر مربوط به Location را نیز با آدرس مربوط به منبع جدید مقدار دهی نمایید.

 

استفاده از HATEOAS

استفاده از HATEOAS یکی از موارد بحث بر انگیز در هنگام طراحی API های REST است. برخی از طراحان معتقند که لینک های مربوط به برنامه کلاینت باید توسط خود کلاینت (یا بهتر بگوییم برنامه نویس کلاینت) ایجاد گردد و سرویس تنها نقش پاسخ دهی به درخواست ها را بر عهده دارد. اما برخی دیگر معتقدند که در سرویس های REST طراحی باید بر مبنای HATEOAS صورت پذیرد. بدین معنی که API وظیفه دارد نحوه تعامل کلاینت با سرویس را از طریق فراهم کردن لینک هایی در پاسخ تعیین نماید. به بیانی دیگرسرویس علاوه بر داده وظیفه دارد فرا داده هایی (metadata) را در اختیار کلاینت قرار دهد و از طریق آن لینک هایی که در آینده مورد استفاده کلاینت است را برای کلاینت فراهم کند. بعنوان مثال در هنگام گرفتن لیستی از کاربران از سرویس در صورتی که صفحه بندی (pagination) برای نمایش کاربران داشته باشیم، علاوه بر لیست کاربران در فراداده لینک های صفحه بعدی و صفحه قبلی را در اختیار کلاینت قرار می دهیم.

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

 

استفاده از JSON در پاسخ ها

در بسیاری از مطالب آموزشی در مورد طراحی API ها گفته می شود که پاسخ ها را در دو فرمت JSON و XML برای کلاینت ها محیا کنید تا کلاینت از هرکدام که خواست استفاده نماید. اما در اینجا می گوییم شاید وقت آن باشد که دیگر فرمت XML را بعنوان پاسخ رها کنیم و تنها از JSON استفاده کنیم. اگرچه فرمت XML کاربرد های بسیاری دارد و مزایای زیادی هم در بسیاری از برنامه ها دارد اما در اینجا باید گفت این فرمت برای پاسخ یک API بسیار طولانی است، پارس کردن ان نیز دشوار است، به آسانی نمی توان آن را خواند و علاوه بر اینها با مدل های داده ای مرسوم در زبان های برنامه نویسی نیز سازگاری زیادی ندارد. بنابه این دلایل و بسیاری از دلایل دیگر، برنامه های متعدد از جمله YouTube، Twitter و … در حال کنار گذاشتن XML هستند. یکی از دلیل این ادعا هم میتواند اختلاف گرایش به سمت این دو در Google Trend باشد.

آموزش کامل restfull

آموزش کامل restfull

 

نامگذاری پارامتر ها بر اساس snake_case و یا camelCase

اگر شما از JSON برای پاسخ استفاده می کنید، بدلیل آنکه قاعده نامگذاری در JavaScript بر اساس camelCase است، درست آن است شما نیز برای نامگذاری پارامتر ها از camelCase استفاده نمایید. اما وقتی قرار است در سمت کلاینت کتابخانه هایی با زبان های مختلف داشته باشید بهتر است مبنای کار شما قواعد نامگذاری در آن زبان ها باشد. بعنوان مثال اگر از جاوا استفاده می کنید بهتر از نام های شما camelCase و در صورتی که از زبان هایی مانند python و یا ruby بهره می گیرد پیشنهاد می شود ازsnake_case استفاده نمایید.

 

فراهم نمودن خروجی زیبا و پشتیبانی از فشرده سازی gzip

همانطور که در بخش های مختلف بیان کردیم API شما باید از طریق مرورگر قابل دسترس باشد. این بدین معناست که خروجی APIدر مرورگر قابل مشاهده خواهد بود. بنابراین بهتر است خروجی چاپ شده در مرورگر به راحتی قابل خواندن باشد. گاهی اوقات به منظور صرفه جویی در پهنای باند و ترافیک شبکه از فشرده سازی white-space compression استفاده می شود که این مسئله باعث می شود خروجی API در مرورگر چندان زیبا و خوانا نباشد. البته برخی ها با استفاده از پارامتر هایی مانند ?prety=true این امکان را برای کاربران فراهم می آورند تا امکان مشاهده خروجی زیبا (pretty print) را داشته باشند اما پیشنهاد می شود بطور پیشفرض این قابلیت را در API های خود فعال نمایید چراکه می توانید اختلاف هزینه انتقال داده را با پشتیبانی از فشرده سازی gzipجبران نمایید و در عین حال API شما از نظر در دسترس بودن و خوانا بودن وضعیت بهتری را خواهد داشت.