علاقهمند نرم افزار
اصول طراحی RESTful API / بهترین راهکار ها
فیسبوک، گوگل، گیتهاب، نتفلیکس و چندین غول دیگر تکنولوژی ، شانس استفاده از اطلاعاتشان را از طریق API ها به دولوپرها و برنامه های شخص ثالث داده اند.
حتی اگر شما برای بقیه دولوپر ها و نرم افزار ها API ارائه نمیدهید، برای برنامه شما خیلی مفیدتر است که API تمیز و زیبایی طراحی کنید.
نحوه درست طراحی یک API یک جر و بحث قدیمی در فضای وب است، و یکی از بزرگترین آنهاست، چون هیچ دستورالعمل رسمی ای برای آن وجود ندارد.
ـ API رابطی است که دولوپر های زیادی از طریق آن به تبادل داده ها میپردازند. یک API خوب همیشه کاربری ساده ای دارد و زندگی دولوپر ها را راحتتر میکند. API یک محیط گرافیکی (GUI) برای دولوپر هاست، اگر گیج کننده باشد آنها دنبال یک جایگزین برای آن خواهند گشت و دیگر از آن استفاده نمیکند. تجربه دولوپری (Developers’ experience) یکی از مهمترین معیار ها برای اندازه گیری کیفیت طراحی API شماست.
۱. ترمینولوژی
اینها از مهمترین اصطلاح (term) های حوزه REST API هستند:
- ـ Resource یک شی یا نمایش از چیزیست (مدل) که به دیتاهای دیگر مرتبط است و شامل متد هایی است که روی آن کار هایی انجام میدهند. مثلا حیوانات، مدارس و کارمندان resource هستند و حذف، افزودن و ویرایش کردن افعالی که میتواند روی آنها انجام شود.
- ـ Collection ها مجموعه ای از resource ها هستند: کمپانی مجموعی از منابع کمپانی است (مثل کارمندان، مشاوران و ... )
- ـ URL یا Uniform Resource Locator مسیری هستند که میتوانند مکان Resource ها را تعیین کنند و بعضی افعال را روی آنها پیاده کنند.
۲. ـ API endpoint
بگذارید برای درک بهتر موضوع چند API برای یک کمپانی با کارمندانش بنویسیم:
برای دریافت لیست همه کارمندان getAllEmployee/
و برای بعضی از کار های معمول دیگر هم لیست زیر را پیاده سازی کردهایم:
-
/addNewEmployee
/updateEmployee
/deleteEmployee
/deleteAllEmployees
/promoteEmployee
/promoteAllEmployees
و تعداد زیادی endpoint دیگر برای انجام کار های مختلف باید پیاده کنیم، که همه آنها شامل ویژگی های منحصر بفرد زیادی هستند. از این رو نگهداری و تعمیر وقتی تعداد پایانه ها (endpoint) افزایش پیدا میکند بسیار سخت خواهد بود.
مشکل کجاست؟
url طبق تعریف (Uniform Resource Locator / مشخص کننده مکان منبع) باید فقط مشخص کننده مکان یک Resource باشد نه انجام فعلی روی آن. پس وجود و getAll
. . . در URL اشتباه است.
پس روش درست چیست؟
آدرس companies/ مثال مناسبی از روش صحیح است که هیچ فعلی را مستقیم ذکر نکرده است.اما چگونه باید افعال را به سرور بفهمانیم؟ مثلا اینکه میخواهیم لیست کارمندان را دریافت کنیم؟ این کار به عهده HTTP متد هاست (GET, POST, DELETE, PUT) که به آنها verb هم میگوییم.
اسم Resource ها همواره باید بصورت جمع بکار برده شوند؛ و اگر خواستیم به یکی از آنها دسترسی داشته باشیم میتوانیم id مورد نظرمان را در URL ارسال کنیم.
- متد GET برای آدرس companies/ باید لیست همه کمپانی ها را بگیرد.
- متد GET برای آدرس 34/companies/ باید اطلاعات کمپانی با آی دی ۳۴ را بگیرد.
- متد DELETE برای آدرس 34/companies/ باید کمپانی با آی دی ۳۴ را حذف کند.
مثال های زیر با فرض این که کارمندان زیر مجموعه ای از کمپانی ها هستند:
- ـ
GET /companies/3/employees
برای دریافت لیست همه کارکنان کمپانی ۳ - ـ
GET /companies/3/employees/45
برای دریافت اطلاعات کارمند ۴۵ متعلق به شرکت ۳ - ـ
DELETE /companies/3/employees/45
برای حذف کارمند ۴۵ متعلق به شرکت ۳ - ـ
POST /companies
برای ساخت یک کمپانی جدید و دریافت اطلاعات کمپانی ساخته شده
حالا API ما تمیز و درست حسابی شد!?
نتیجه این که: آدرس ها باید شامل اسم های جمع Resource ها باشند، و HTTP متد ها فعل انجام شده روی Resource را مشخص کنند.
۳. متد های HTTP
ـ HTTP تعدادی متد تعریف شده دارد که مشخص میکنند چه فعلی روی Resource مورد نظر اعمال میشود.
ـ URL یک جمله است؛ Resource ها اسم های آن و HTTP متد ها فعل های آن هستند.
متد های پر استفاده تر HTTP به قرار زیر اند:
- متد GET اطلاعات را از Resource مورد نظر دریافت میکند. مثلا
companies/3/employees/
اطلاعات مربوط به کارمندان کمپانی ۳ را برمیگرداند. ( این عمل نباید هیچ تاثیر جانبی دیگری بر سیستم داشته باشد.) - متد POST برای ساخت یک Resource در دیتابیس بکار میرود.(معمولا وقتی یک فرم ارسال میشود.)
برای مثالcompanies/3/employees/
یک کارمند جدید از کمپانی ۳ ایجاد میکند.
نکته : این متد non-idempotent است یعنی با تکرار درخواست یک Resource جدید ایجاد میکند. - متد PUT درخواستی است که Resource را ویرایش میکند و در صورت عدم وجود آنرا میسازد. برای مثال
companies/3/employees/john/
ـ john را در زیر مجموعه کارکنان کمپانی ۳ ویرایش میکند و در صورت عدم وجود آنرا میسازد.
نکته: این متد idempotent است یعنی با تکرار درخواست همان Resource قبلی ویرایش میشود. - متد DELETE برای حذف Resource ای که باید از دیتابیس حذف شود بکار میرود. برای مثال
/companies/3/employees/john/
باعث حذف john از لیست کارمندان کمپانی ۳ میشود.
برای اطلاع از متد های دیگر HTTP از ویکی پدیا استفاده کنید.
۴. کد های وضعیت HTTP Response
وقتی که کلاینت درخواستی از سرور میکند باید بتواند به راحتی از وضعیت درخواستش مطلع شود، که درخواستش موفق ،ناموفق و یا غلط بوده است. کد های وضعیت HTTP سریال هایی برای سناریو های مختلفی است که ممکن است روی دهد. سرور همیشه باید کد وضعیت درست را به کلاینت برگرداند.
در ادامه به معرفی دسته های مختلف کد های وضعیت HTTP میپردازیم:
حالت موفق - 2XX
این دسته کد های وضعیت به معنای دریافت درخواست توسط سرور و موفقیت پردازش مورد نظر است:
- ـ 200 OK: کد استاندارد HTTP برای نمایش موفقیت عملیات های GET,POST ,PUT
- ـ 201 Created: این کد وضعیت باید بعد از ایجاد شدن یک Resource بازگردانده شود. برای مثال هنگام ساخت با POST
- ـ 204 No Content: درخواست موفق بوده است ولی هیچ محتوایی برای پاسخ وجود نداشته است. معمولا درخواست DELETE با این کد برمیگردد. وقتی درخواست DELETE ارسال میشود ما به صراحت به سرور گفته ایم که یک نمونه را حذف کن و نیازی به بازگشت اطلاعات خاصی نداریم. اگر نمونه مورد نظر وجود نداشته باشد ارور کلاینت رخ داده که در حوزه 4XX قرار میگیرد.
حالت ریدایرکت - 3XX
- ـ 304 Not Modified: نشان میدهد که کلاینت پاسخ را در کش خود دارد و نیازی به ارسال مجدد داده ها به کلاینت نیست.
حالت کلاینت ارور - 4XX
این حالت هنگامی رخ میدهد که درخواستی معیوب از سمت کاربر ارسال شود:
- ـ 400 Bad Request: درخواست توسط سرور انجام نشده است. سرور معنای درخواست کلاینت را متوجه نمیشود.
- ـ 401 Unauthorized: کلاینت اجازه دسترسی به این Resource را ندارد و برای دسترسی باید با اعتبار مشخصی اقدام کند.
- ـ 403 Forbidden: درخواست درست ارسال شده و کلاینت تایید اعتبار شده است اما به دلیلی به او اجازه دسترسی به Resource داده نمیشود. برای مثال کاربران عضو یک وبسایت به فایل های دایرکتوری دسترسی ندارند.
- ـ 404 Not Found: نشان میدهد در حال حاضر منبعی برای این درخواست موجود نیست.
- ـ 410 Gone: نشان میدهد مکان Resource مورد نظر جا به جا شده است.
حالت سرور ارور - 5XX
- ـ 500 Internal Server Error: درخواست درست است ولی سرور در ارائه خواسته کلاینت مشکل دارد. یعنی اروری در حین آماده سازی پاسخ در سرور ایجاد شده است.
- ـ 503 Service Unavailable: سرور غیر فعال است یا نمیتواند درخواست ها را دریافت و پردازش کند. عموما به معنای این است که سرور در حال تعمیر است.
۵. قوانین نام گذاری
شما میتوانید از هر قاعده نام گذاری (naming convention) ای که میخواهید پیروی کنید.اما حتما این قاعده را در تمام سطح API رعایت کنید. اگر از JSON برای بدنه درخواست یا پاسخ استفاده میکنید سعی کنید که از Camel Case استفاده کنید.
۶. جستجو، مرتب سازی، فیلتر کردن و صفحه بندی
همه این کار ها با کوئری زدن روی دیتاست ها انجام پذیر اند؛ و نیازی به طراحی API مجزا ندارند. کافیست پارامتر هایی به URL خود اضافه کنیم و توسط همان متد GET آنرا درخواست دهیم. بگذارید با چند مثال قضیه را روشن تر کنیم:
- مرتب سازی: کلاینت میخواهد درخواستی برای دریافت لیست مرتب کمپانی ها ارسال کند. پایانه
GET /companies
باید بتواند پارامتر های مختلفی را قبول کند مثل :GET /companies?sort=rank_asc
که لیست کمپانی ها را بر اساس رنکینگ بصورت صعودی برمیگرداند. - فیلتر کردن: برای فیلتر کردن دیتاست ها میتوانیم مانند مرتب سازس عمل کنیم مثلا:
GET /companies?category=banking&location=india
بانک هایی که در هند مستقر هستند را برمیگرداند. - جستجو: مثلا برای جستجو بر اساس نام یک کمپانی :
GET /companies?search=Digital Mckinsey
که اطلاعات کمپانی دیجیتال مکنزی را برمیگرداند. - صفحهبندی: وقتی دیتاست خیلی بزرگ است، آنرا به بخش های کوچک تر تبدیل میکنیم تا بازده سیستم بالاتر رود و پاسخ سریعتر ارسال شود . برای مثال:
GET /companies?page=23
کمپانی های بخش ۲۳ را برمیگرداند.
نکته: وقتی تعداد پارامتر های ارسالی بالارود و طول URL بیش از حد شود، ممکن است سرور کد 414 URI Too Long بدهد. در این موارد میتوانید دیتای مورد نظر را در بدنه درخواست POST قرار دهید.
۷. نسخه بندی (versioning)
وقتی API شما در حال استفاده است، بهبود دادن آن و تغییر ساختار آن ممکن است در عملکرد نرم افزار هایی که از API شما استفاده میکنند مشکل ایجاد کند. این URL یک نمونه مناسب از API است: http://api.yourservice.com/v1/companies/34/employees
که عدد ورژن به صراحت در URL ذکر شده است. اگر تغییر اساسی در API شما انجام شد باید ورژن جدیدی از API منتشر کنید. برای مثال از v2 یا v1.x.x استفاده کنید.
پایان
این یادداشت ترجمه آزادی بود از:
در صورتی که آن را دوست داشتید از لایک و اشتراک گذاری دریغ نکنید.
مطلبی دیگر از این انتشارات
چطور در دیزاین بد نباشیم، یک راهنمای ۵ دقیقه ای برای غیرطراحان
مطلبی دیگر در همین موضوع
معرفی مطالب جالب برنامه نویسی -۳
بر اساس علایق شما
پارتی 300 تایی شدن ..