ملاحظات مهمی که تو طراحی RESTful API باید در نظر بگیریم

این مقاله اولین نوشته‌ی ترجمه‌ی شده‌ایه که تو این وبلاگ منتشر میکنم. میتونید اصل مقاله رو اینجا ببینید.

وقتی داریم یک RESTful API مینویسیم بهتره که URL ها چجوری باشه؟ در URL از اسمهای جمع استفاده کنیم یا مفرد؟ برای یک ریسورس چند تا URL نیاز داریم؟ برای هر URL بهتره که از کدوم متد HTTP برای ساخت ریسورس جدید استفاده کنیم؟ URLهای عملیاتهایی که به هیج ریسورسی نیاز ندارند چطور؟ چگونه باشند؟ بهترین روش برای ورژن بندی کردن API چیه؟ اینها سوالاتی هستند که تلاش میکنیم تو این مقاله بهشون پاسخ بدیم.

برای هر نوع داده‌ای دو URL داشته باشید:

یکی برای نمایش تمام داده ها یکی برای نمایش یک داده مشخص:

 

/employees         #collection URL
/employees/56      #element URL

 

به جای فعل از اسم استفاده کنید:

اینکار باعث میشود که API شما سادگی‌اش را حفظ کند و تعداد URLها کاهش بابد. برای مثال اینکار رو نکنید:

/getAllEmployees
/getAllExternalEmployees
/createEmployee
/updateEmployee

به جای اینکار از متدهای HTTP برای انجام اعمال مختلف روی داده‌هایتان استفاده کنید:

GET /employees
GET /employees?state=external
POST /employees
PUT /employees/56

از URLهای برای این استفاده کنید که مشخص کنید روی کدام داده میخواهید کار کنید و از متدهای HTTP برای مشخص کردن کاری که میخواهید بکنید استفاده کنید. با چهار متد GET, POST, PUT, DELETE میتوانید چهار عمل CRUD را انجام دهید (Create , Read, Update, Delete) :

  • خواندن (Read) : برای خواندن داده‌ها از GET  استفاده کنید.
  • ساختن (Create) : برای ساختن داده جدید از متد POST استفاده کنید.
  • به روز رسانی (Update) : برای به روز رسانی داده از متد PUT استفاده کنید.
  • پاک کردن (Delete) : برای پاک کردن دادهها از متد Delete استفاده کنید.

دو URL به همراه چهار متد HTTP یک سری قابلیت کامل به ما میدهند. به جدول زیر نگاه کنید:

post231_table1

از اسمهای جمع استفاده کنید:

برای مثال این را:

/employees
/employees/21

به این ترجیح بدید:

/employee
/employee/21

حقیقتا این یک مقدار سلیقه‌ایه ولی خب اسامی جمع معمولترند. استفاده از اسامی جمع هوشمندانه‌‌تر هم هست. برای مثال وقتی دارید از متد GET برای گرفتن مجموعه‌ای از یک داده استفاده میکنید،‌دارید مجموعی از داده‌ها را میگیرید و اسم جمع منطقی‌تره. اما مهمتر از همه،‌ از ترکیب اسامی جمع و مفرد خودداری کنید. چون باعث گیجی میشند.

برای پارامتر‌های پیچیده تر از متغیرها استفاده کنید:

برای مثال اینکار را نکنید:

GET /employees
GET /externalEmployees
GET /internalEmployees
GET /internalAndSeniorEmployees

بهتره که URL رو ساده نگه دارید و پارامترهای پیچیده تر رو در قالب متغیر به آن اضافه کنید:

GET /employees?state=internal&maturity=senior
پیغام ارور مفید و مناسب ارسال کنید:

در هنگام بروز خطا، بهتره که در پاسخ یک پیغام خطای خوب و مناسب ارسال کنید. برای مثال:

درخواست:

GET /employees?state=super

پاسخ:

۴۰۰ Bad Request
{
"message": "You submitted an invalid state. Valid state values are 'internal' or 'external'",
"errorCode": 352,
"additionalInformation" : "http://www.domain.com/rest/errorcode/352"
}
برای نامگذاری Attributeها، از روش CamelCase استفاد کنید:

برای مثال:

	
{ "yearOfBirth": 1982 }

از underscore ((“year_of_birth” یا حروف تمام بزرگ(“YearOfBirth”) استفاده نکنید. معمولا RESTful API شما توسط کلاینتی استفاده میشه که به جاوااسکریپت نوشته شده. و به طور معمول کلاینت شی JSON را به یک شی جاوااسکریپت تبدیل میکنه. با صدا زدن خط  (var person = JSON.parse(response . بنابراین، بهتره که شما هم به قراردادهای جاوااسکریپت متعهد باشید و کار برنامه‌نویس کلاینت رو راحت‌تر کنید.

همیشه شماره ورژن رو داخل URL قرار بدید:

همیشه API رو با یک شماره ورژن منتشر کنید و سعی کنید این شماره ورژن رو داخل URL  قرار دهید. این باعث میشه که  اگه در آینده خواستید API رو طوری تغییر بدید که با نسخه‌های قبلی سازگار نباشه، به مشکل برنخورید. و این باعث میشه که مشتری‌ها هر وقت که دوست داشتند به نسخه جدید رو بیارن. نه اینکه موقع استفاده از API به خاطر اینه نسخه جدید رفتار متفاوتی بروز میده به مشکل بخورند. برای مثال میتونید به این شیوه API رو ورژن گذاری کنید:

/v1/employees
اطلاعات رو صفحه بندی کنید:

میشه با قاطعیت گفت که هیچوقت نباید تمام داده‌ها رو یکجا و با یک درخواست به کلاینت ارسال کرد. به جای آن باید اطلاعات رو صفحه بندی کنید. استفاده از offset و limit در این شرایط روش ایده‌آلیه که برای دیتابیسها هم کاملا شناخته شده‌ست. برای مثال :

/employees?offset=30&limit=15       #returns the employees 30 to 45

اگر کلاینت پارامترها رو ارسال نکرد،‌برای آنها مقدار دیفالت در نظر بگیرید. یک مقدار پیشفرض خوب میتونه limit=10 و offset=0 باشه.

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

درخواست:

GET /employees

پاسخ:

{
  "offset": 0,
  "limit": 10,
  "total": 3465,
  "employees": [
    ...
  ]
}
برای درخواستهایی که برای دریافت داده‌ها نیستند از فعل استفاده کنید:

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

GET /translate?from=de_DE&to=en_US&text=Hallo
GET /calculate?para2=23&para2=432

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

امکان سرچ فراهم کنید:

فراهم کردن امکان سرچ برای نوع خاصی از داده‌هها کار آسونیه. فقط کافیه URL اون نوع خاص داده رو با یک پارامتر سرچ در نظر بگیرید:

GET /employees?query=Paul

اگر میخواید که سرچ کلی بین تمام داده‌ها موجود فراهم کنید باید روش متفاوتی رو پیش بگیرید. درس گذشته در مورد URLهای عملیاتی رو به خاطر بیارید: از فعل به جای اسم استفاده کن. بنابراین URL سرچ شما میتونه به شیوه زیر باشه:

GET /search?query=Paul   //returns employees, customers, suppliers etc.
 برای گشت و گذار در میان API خود لینک فراهم کنید:

در حالت ایده‌آل، بهتره که اجازه ندید کاربر مجبور بشه که برای استفاده از REST API شما لینکها رو خودش بسازه. مثال زیر رو در نظر بگیرید:

یک کاربر میخواد که ببینه مبلغ حقوق یک کارمند چقدره. برای اینکار اون باید یک درخواست به آدرسی مثل این ارسال کنه:   /employees/21/salaryStatements . احتمال اینکه کاربر یک اشتباه تایپی داشته باشه و این درخواست با خطا روبه‌رو شه بسیار زیاده. برای همین بهتره که شما در پاسخ‌هایی که به کاربران ارسال میکنید لینکهایی رو برای دسترسی به سایر اطلاعات قرار بدید. برای مثال:

درخواست:

GET /employees/

پاسخ:

...
   {
      "id":1,
      "name":"Paul"
      "links": [
         {
            "rel": "salary",
            "href": "/employees/1/salaryStatements"
         }
      ]
   },
...

در این حالت حتی میتوانید بدون اینکه کاربر با مشکلی رو به رو شود URL دسترسی به اطلاعات رو تغییر بدید. برای مثال salaryStatements رو به stalary_statements تبدیل کنید.

همینطور در مواقعی که اطلاعات رو به شکل صفحه بندی ارسال میکنید میتونید لینک صفحه بعد یا قبل اطلاعات رو به کاربر نشون بدید. برای مثال:

درخواست:

GET /employees?offset=20&limit=10

پاسخ:

{
  "offset": 20,
  "limit": 10,
  "total": 3465,
  "employees": [
    ...
  ],
  "links": [
     {
        "rel": "nextPage"
        "href": "/employees?offset=30&limit=10"
     },
     {
        "rel": "previousPage"
        "href": "/employees?offset=10&limit=10"
     }
  ]
}

4 پاسخ به “ملاحظات مهمی که تو طراحی RESTful API باید در نظر بگیریم”

  1. سجاد گفت:

    سلام
    بسیار عالی بود ، ممنون

  2. میلاد گفت:

    خیلی خوب بود

  3. محمدرضا گفت:

    بسیار عالی بود آرش .
    اگه وقت آزاد داشتی یه مثال خوب با همین استاندارد های پیاه کن.
    مرسی

پاسخ دهید

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

android application Google I/O HomeBrew ImageMagick Material Design mobile PogressBar RecyclerView splash TEDxKish ux آموزش اندروید الوین تافلر اندروید اپلیکیشن برنامه نویسی برنامه نویسی اندروید برنامه‌نویسی برنامه‌نویسی اندروید تداکس کیش تعمیر تغییر سایز عکس با ترمینال خلاصه کتاب دانش داده دانشگاه دانشگاه ایده‌آل دزد دیتا ساینس رشته مهندسی کامپیوتر ریکامندرسیستم سیستم‌های توصیه‌گر فری‌لنس لپتاپ متریال دیزاین معرفی کتاب موج سوم نوار پیشرفت همایش هوش مصنوعی ُجزیره کیش کار کسب و کار یادگیری عمیق یادگیری ماشین