وقتی پای نوشتن API برای یک سرویس تحت وب به میان میآید، بدون شک نیاز خواهیم داشت تا بسته به شرایط مختلف از یک HTTP Status Code استفاده نماییم تا دیگر دولوپرهایی که از API ما استفاده میکنند تا حد ممکن کمتر سردرگم شوند. در همین راستا، یکسری Best Practice وجود دارد که با پیروی از آنها میتوانیم اطمینان حاصل کنیم که کدهای وضعیتمان کاملاً قابلفهم خواهند بود.
به طور کلی، کدهای وضعیت در پروتکل HTTP به پنج گروه زیر تقسیمبندی میشوند اما هر کدام از این سری کدها خود حاوی زیرشاخههای بسیاری هستند و در همین راستا اطمینان حاصل کردن از اینکه دیگر دولوپرهایی که به تعامل با ایپیآی ما میپردازند به خوبی قادر به درک معنا و مفهوم کدهای وضعیت هستند، امری ضروری است:
- 1xx
- 2xx
- 3xx
- 4xx
- 5xx
به طور کلی، اهمیت کدهای وضعیت در این است که به منزلهٔ اولین نقطهٔ اتکایی هستند که اگر ریکوئست ارسال شده به سرور دچار مشکل شد، کلاینت را از این موضوع مطلع میسازد (برای مشاهدهٔ لیستی از کدهای وضعیت، میتوانید به لینک HTTP Status Codes مراجعه نمایید.)
کدهای وضعیت گروه 1xx
کدهای وضعیت HTTP که با عدد یک شروع میشوند حاوی دو کاربرد کلی هستند. اولین کاربرد به دیتای مرتبط با وضعیت کانکشن اشاره داشته و همچنین کدهای وضعیت گروه 1xx نشانگر رکوئست اولیه از طرف کلاینت هستند به طوری که مثلاً کد وضعیت 100 (Continue) حاکی از آن است که سرور اطلاعات Request Headers را از کلاینت دریافت کرده و منتظر Request Body است.
کدهای وضعیت گروه 2xx
کدهای وضعیت HTTP که با عدد دو شروع میشوند نشان از موفقیتآمیز بودن ریکوئست ارسالی به سمت سرور دارند. به طور مثال، کد وضعیت 200 (OK) حاکی از آن است که ریکوئست با موفقیت انجام شده و کد وضعیت 201 (Created) هم نشان میدهد که درخواست با موفقیت انجام شده و یک ریسورس جدید ایجاد شده است.
کدهای وضعیت گروه 3xx
کدهای وضعیت HTTP که با عدد سه شروع میشوند نشانگر این مسأله هستند که به منظور تکمیل موفقیتآمیز ریکوئست مد نظر کاربر، وی میبایست اقدام دیگری نیز انجام دهد. به عنوان مثال، کد وضعیت 301 (Moved Permanently) کلاینت را به URI متفاوتی برای عملی شدن درخواستش ارجاع میدهد.
کدهای وضعیت گروه 4xx
کدهای وضعیت HTTP که با عدد چهار شروع میشوند به نوعی برای کاربران غیرفنی نیز ملموس هستند چرا که معروفترین کد وضعیت متعلق به این خانواده، 404 (Not Found)، برای بسیاری کاربران نامآشنا است! علاوه بر این، کدهای کاربردی دیگری نیز در این گروه قرار دارند که در طراحی API میتوان از آنها استفاده کرد که از آن جمله میتوان به کد وضعیت 429 (Too Many Requests) اشاره کرد که در مواقعی میتوان آن را مورد استفاده قرار داد که تعداد ریکوئستهای دریافتی از طرف کلاینت خاصی بیش از حد مجاز باشد که در نهایت منجر به رد درخواست توسط سرور میشود.
کدهای وضعیت گروه 5xx
کدهای وضعیت HTTP که با عدد پنج شروع میشوند در یک کلام همگی مرتبط با مشکلات سمت سرور بوده و اصلاً ربطی به کلاینت ندارند و برخلاف کدهای خانوادهٔ 4xx، این دست کدها زمانی مورد استفاده قرار میگیرند که در سمت سروری که API روی آن پیادهسازی شده است مشکلی به وجود آمده و سرور از انجام درخواست کلاینت ناتوان است که یکی از معروفترین آنها کد وضعیت ۵۰۳ (Service Unavailable) است که زمانیهایی مورد استفاده قرار میگیرد که سرویس در دسترس نباشد.
فیچرهای یک Status Code خوب چیست؟
یک کد وضعیت خوب نه تنها کلاینت را در جریان روند انجام کار قرار میدهد، بلکه به کلاینت دلیل یا دلایل رخداد یک رویداد خاص را نیز نشان میدهد. به طور کلی، زمانی میتوانیم بگوییم یک کد وضعیت خوب در اختیار کلاینت قرار دادهایم که از سه ویژگی زیر برخوردار باشد:
- حاوی کد وضعیت (مثلاً 200) و همچنین توضیحات خلاصه (مثلاً OK) باشد.
- حاوی توضیحات تکمیلی و جزئیات بیشتری در مورد فرایند باشد.
- حاوی متنی قابلفهم برای کاربران باشد که خلاصهای از کد، وضعیت، جزئیات، دلایل مرتبط و راهکار پیشنهادی برای حل مشکل باشد.
برای درک بهتر نحوهٔ نوشتن یک کد وضعیت خوب، در ادامه به توضیح در مورد ویژگیهای فوقالذکر خواهیم پرداخت:
- کدهای وضعیت استاندارد: استفاده از کدهای وضعیت استاندارد که در بالا آنها را در قالب پنج گروه مختلف بررسی کردیم، میتواند نقطهٔ شروع خوبی برای نوشتن کدهای وضعیت حرفهای باشد. در واقع، وقتی شما از خانوادهٔ کدهای وضعیت 4xx یا 5xx استفاده میکنید، کاربر خیلی سریع متوجه خواهد شد که مشکلی، خواه از سمت کلاینت یا خواه از سمت سرور، وجود دارد.
- ارائهٔ جزئیات: اگر کد وضعیتی همچون 400 (Bad Request) را در اختیار کلاینت قرار دهیم، گرچه چنین کدی حاکی از وجود مشکلی از سمت کاربر است، اما به هیج وجه اطلاعات کافی و کاربردی در اختیار کاربر قرار نمیدهد تا وی بتوانند اقدامی مقتضی را در نظر گیرد. در همین راستا، میبایست جزئیات بیشتری را در اختیار کاربر قرار دهیم چرا که عبارت Bad Request (درخواست بد) مفهومی کلی دارد و کلمهٔ بد کاملاً نسبی است و ضروری است که آن را از حالت نسبی بودن خارج ساخته و مفهومش را کاملاً گویا و قابلدرک نماییم.
- قابلفهم برای کاربران: گرچه کدهای وضعیت عددی برای سیستم به خوبی قابلدرک هستند (مثلاًً میتوانیم با استفاده از دستورات شرطی چک کنیم که اگر به طور مثال کد وضعیت برابر با 400 بود، فلان کار انجام شود)، اما ارائهٔ جزئیات قابلفهم برای انسانها هم کمک به هرچه حرفهایتر شدن کدهای وضعیت میکند.
حال اگر بخواهیم آنچه در بالا بدانها اشاره شد را به صورت عملی مورد بررسی قرار دهیم، با کد وضعیتی همچون آنچه در ادامه خواهید دید مواجه خواهیم شد:
{
"code": 429,
"codeMessage": "Too Many Requests",
"errorDetails": "There have been more HTTP requests that you`re allowed to send; To solve this problem, you have to upgrade you plan to Unlimited API Usage."
}
در واقع، کد وضعیت بالا حاوی کلیدهایی تحت عناوین codeMessage ،code و errorDetails میباشد که شامل اطلاعات مفیدی برای دولوپری است که از API استفاده میکند که در کنار یکدیگر تشکیلدهندهٔ سه ویژگی یک یک وضعیت اصولی هستند. در تفسیر کد وضعیت فوق، بایستی بگوییم که کد 429 و پیام استاندارد Too Many Requests حاکی از آنند که تعداد درخواستهای ارسالی به سمت سرور بیش از حد مجاز بودهاند اما آنچه بیش از هر چیزی برای دولوپری که این پیام خطا را دریافت کرده کاربردی است، پیام مرتبط با کلید errorDetails است که به این نکته اشاره دارد که «تعداد درخواستهای ارسالی بیش از حد مجاز است و برای رفع این مشکل میبایست پلن خود را به Unlimited (بدون محدودیت) ارتقاء دهید.» که به سادگی راهکار مورد نیاز را هم برای رفع مشکل به دولوپر ارائه میدهد.
نتیجه
به طور کلی، کدهای وضعیت که در پروژههای مختلفی مورد استفاده قرار میدهیم کاملاً پروژهمحور بوده و تحت هیچ عنوان نمیتوان از ساختاری که برای یک API جوابگو بوده، دقیقاً به همان شکل در سایر پروژهها نیز استفاده نمود. در یک کلام، هدف از ارائهٔ کدهای وضعیت در طراحی API این است که نه تنها اطلاعاتی در مورد نوع مشکل به وجود آمده ارائه دهیم، بلکه میبایست راهکاری نیز برای رفع مشکل در اختیار دولوپرها قرار داده تا از کار با API ما تجربهٔ کاربری خوبی به دست آورند.