قواعد اصلی و کلی برای پیاده سازی اصولی یک API بصورت زیر است. هر کدام از این قواعد دارای جزییات و مفاهیم زیادی میباشد. در این قسمت صرفا اشارهای به آنها کردم. برای ریز شدن در جزییات هرکدام باید جداگانه در موردشان بخوانید.
اشتباه نکنید، این قواعد ربطی به محدودیت های REST ندارد، صرفا قواعدی هستند که برای درست و کامل پیاده سازی کردن API لازم است.
فرض کنید میخواهید api برای گرفتن اطلاعات یک کاربر بخصوص طراحی کنید، نباید نام api غیرشفاف باشد. " GetUsers " یک نامگذاری اشتباه برای این api خواهد بود. چون تصور میشه api با این نام اطلاعات تمام کاربران را به ما میدهد.
همچنین نباید از فعل استفاده کنیم. باید از اسمی استفاده کنیم که نماینده موجودیتی است که End point ما قصد انجام کوئری روی آن را دارد. دلیل این است که متد درخواست HTTP ما خود یک فعل دارد.
یک endpoint جایی است که API درخواستها را دریافت می کند. در واقع توابع یا resourceهایی هستند که از طریق API میتوان به آنها دسترسی داشت.مانند حذف یک پست یا اطلاعات کتابخانه و یا یک کتاب خاص. endpoint عملکرد خاصی را انجام می دهند و تعدادی پارامتر را میگیرد و دادهها را باز می گرداند. برای اکثر سرویسها، endpoint یک URL است.
یک route نامی است که برای دسترسی به endpoint استفاده میشه. یک route میتونه چند endpoint مرتبط داشته باشه و اینکه از کدوم آنها استفاده بشه به HTTP Verb بستگی داره.
برای مثال http://localhost:8000/users
رو در نظر بگیرید.
در این مثال http://localhost:8000/users و http://localhost:8000/users/{userId}
دو endpoint هستند و اینها route های زیر را دارند:
GET /users
GET /users/userId
PUT /users/userId
.......
پارامترهای پرس و جو رایج ترین نوع پارامترها هستند. آنها در انتهای URL درخواست پس از علامت سوال (؟)، با جفت های مختلف name=value که با علامت (&) از هم جدا شده اند ظاهر می شوند. پارامترهای پرس و جو می توانند مورد نیاز و اختیاری باشند. از این پارامتر بیشتر برای فیلترکردن دیتا و یا صفحه بندی استفاده می شود.
GET /users/findByStatus?status=available
GET /books?offset=100&limit=50
هدرهای API بخشی از request/response هستند که برای انتقال meta data در مورد request و response مورد نظر استفاده میشوند. به عبارت ساده تر، اینجا جایی است که می توانید اطلاعات اضافی در مورد request/response ارائه دهید. به عنوان مثال، مشخص میکنن که دادههای ارسال شده در قالب JSON هستند، کدام نسخه از API را فراخوانی کند و .....
هدرها عموما بصورت جفت key:value هستند.
نرم افزار و نسخه client را شناسایی می کند.
فرمت ترجیحی response را مشخص می کند و اطمینان می دهد که سرور response را در قالبی ارائه می دهد که کلاینت بتواند پردازش و درک کند. برای مثال "application/json" به سرور نشان می دهد که کلاینت response را در قالب JSON میپذیرد. چند نمونه از فرمت های قابل قبول:
Application/JSON - Application/XML - Text/HTML - Text/plain
برای نشان دادن نوع دیتایی که درrequest body وجود دارد. برای مثال "application/json" نشان می دهد که request body در قالب JSON است. چند نمونه از فرمت های قابل قبول:
Application/JSON - Application/XML - Text/HTML - Text/plain
برای ارائه اطلاعات احراز هویت به سرور استفاده می شود. این به client اجازه میدهد تا credential یا token را که هویت و مجوزهای آن را تأیید می کند، وارد کند و دسترسی به resourceها را تضمین کند. Authorization نقش مهمی در اجرای مکانیسمهای کنترل دسترسی ایفا میکند و تضمین میکند که فقط clientهای مجاز میتوانند اقدامات خاصی را انجام دهند یا دادههای خاصی را از API فرخوانی کنند. چند مثال معمول از این هدر:
دستورالعملهایی را به clinetها و واسطهها (مانند حافظههای پنهان) در مورد مدیریت ذخیرهسازی response ارائه میکنند. آنها با کاهش انتقال دیتاهای غیر ضروری و بهبود زمان response، به بهینه سازی عملکرد کمک می کنند.
هنگامی که یک response در حافظه پنهان ذخیره می شود (cached)، body ذخیره شده به requestها بازگردانده می شود، نه اینکه اطلاعات هر بار بازیابی شود. چند مثال از این هدر:
مشخص می کند که response را می توان ذخیره کرد
مشخص می کند که response را می توان ذخیره کرد اما برای یک کاربر خاص در نظر گرفته شده است.
حداکثر زمان (بر حسب ثانیه) را مشخص میکند که response ذخیره شده در cache قابل قبول است.
توسط کلاینت ها برای تعیین اینکه یک response ذخیره شده نباید استفاده شود، یا توسط سرور نباید از response برای requestsهای بعدی بدون اعتبارسنجی در سرور مبدا استفاده کند.
هدرهای response بخشی جدایی ناپذیر از پروتکل HTTP هستند و توسط سرورها برای ارائه اطلاعات اضافی در مورد response ارسال شده به کلاینت استفاده می شوند. response headerها نقش مهمی در انتقال جزئیات مهم در مورد response سرور دارند. میتوانند شامل اطلاعات مختلفی مانند نوع محتوای response، دستورالعملهای حافظه پنهان، اطلاعات سرور و غیره باشند. اینها با request headerها مرتبط هستند زیرا جزئیات مهمی را ارائه می دهند که به کلاینت کمک می کند تا response دریافتی را درک کند و پردازش کند. به عنوان مثال، هدر "Content-Type" کلاینت را در مورد قالب داده های بازگردانده شده (به عنوان مثال، JSON، XML) مطلع می کند و به کلاینت اجازه می دهد تا پاسخ را به طور مناسب تجزیه و مدیریت کند.
برای نشان دادن نوع دیتایی که درresponse body وجود دارد. برای مثال "application/json" نشان می دهد که response body در قالب JSON است. چند نمونه از فرمت های قابل قبول:
Application/JSON - Application/XML - Text/HTML - Text/plain
این هدر برای هدایت کلاینت به یک URL دیگر استفاده می شود. کلاینت باید به طور خودکار URL را در Location header دنبال کند. معمولاً برای تغییر مسیرهای HTTP استفاده می شود، مانند زمانی که کاربر فرمی را ارسال می کند و به صفحه تأیید هدایت می شود.
POST /api/orders HTTP/1.1
Host: api.amaxon.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Accept: application/json
User-Agent: AmaxonApp/1.01
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 96
هنگامی که شما نیاز به ارسال داده از کلاینت به API دارید، آن را به عنوان Request Body ارسال میکنید. این جایی است که ما دیتا و ویژگیهایی که میخواهیم در request خود ارسال کنیم، مشخص میکنیم. بجز متد GET بقیه متدها همیشه request body دارند.
اینکه چه دیتاهایی در request body قرار دهید بستگی به تعریف آبجکتها در API و دیتابیس شما دارد. در API Documentation باید ۳ مورد مشخص شود:
۱. کدام فیلدها اجباری و کدام اختیاری است ۲. شرح هر فیلد ۳. نمونه ای از دیتای ارسالی
از نظر فنی می تواند هر نوع رشته ای را در خود جای دهد، اما به طور کلی شامل XML یا JSON می شود، به عنوان مثال. {"firstName":"Pied", "lastName":"Piper"}
برای ارسال مقادیر متنی ساده در یک رشته پرس و جو استفاده میشود. مثال key1=value1&key2=value2. در ایت روش همه کارکترها کدگذاری میشوند. مثلا فاصله(space) با %20 جایگزین میشه.
برای پیوست کردن تصاویر، فیلم ها، صداها و سایر فایل های غیر متنی استفاده میشود.
انواع دیگر عبارتند از GraphQL و فرم های چند بخشی. فرمت صحیح بستگی به سرور دارد و داکیومنت API همیشه باید به شما بگوید که دقیقاً چگونه دیتا را ارسال کنید که به درستی پردازش شوند.
اگر قصد داشته باشیم با متد PUT اطلاعات کاربری را آپدیت کنیم، request body و route آن میتواند بصورت زیر باشد:
GET /users/findByName?name=saeed
{
"Name": "Majid",
"Number": 57,
"Team": "Arsenal"
}
در این مثال اطلاعات هر ۳ فیلدی که در request body مشخض شده است برای کاربری با نام saeed آپدیت می شود. نکته مهم در تعریف request body این است که فقط دیتاهایی را مشخص کنیم که به آنها نیاز است.
درست مانند request body، برای نگهداری و ارسال دیتاهایی که میخواهیم به کلاینت ارسال کنیم، استفاده میشود. البته در پاسخ به بعضی از requestها به response body نیاز نیست و تنها با ارسال یک status code مشخص میکنیم که درخواست کلاینت انجام شد یا نشد. برای مثال هنگام لاگین به یک سایت تنها نیاز است status code ارسال کنیم و مشخص کنیم که لاگین موفق بود و یا به چه علت لاگین انجام نشد.
متدهای GET همیشه نیاز به یک Response body دارند.
ساختار response body همانند request body است و فقط دیتاهایی که در اینها مشخص میکنیم تفاوت دارد. و نکته اصلی این است که از ارسال دیتاهای غیرضروری از طریق response body خودداری کنید.
نشان می دهد آیا سرور با موفقیت درخواست را انجام داده است یا خیر - و اگر نه، چرا. اولین بخشی از Response که خطا را مشخص میکند و همچنین دولوپرها برای دیباگ کردن به آن توجه میکنند status code ها هستند، در نتیجه انتخاب درست status code ها اهمیت زیادی دارند. حتما صفحه ویکی پدیا را مطالعه کنید.
همانطور که قبلا گفتم هنگام لاگین به یک سایت تنها نیاز است که status code را مشخص کنیم که در اینجا می تواند موارد زیر باشد:
برای مثال اگر یک کاربر فقط نام یک کاربر را درخواست میکند، نام کامل و ID را هم به کاربر ارسال نکنید. فقط همان چیزی که نیاز است. ارسال response body کوچک اهمیت بالایی دارد.
هنگام ایجاد یک API، سعی کنید تا حد امکان همه چیز را در یک تابع تعریف نکنید. اگر وظایف زیادی را به طور همزمان انجام دهد، باید به چند API تقسیم شود.
هنگامی که یک میکروسرویس بزرگ ایجاد میکنید و Response body یا Response Object بیش از حد بزرگ میشود، صفحهبندی باعث میشود API بتواند مقدار کمی از اطلاعات را برگرداند. صفحه بندی روشی برای جداسازی محتوای دیجیتال به صفحات مختلف در یک وب سایت یا یک Response Object است.
یک پایگاه داده با هفتاد کاربر را تصور کنید. API به جای ارسال پاسخ همه کاربران به یکباره و کند کردن آن، getUsers را فراخوانی می کند.میتوانید پاسخ را تجزیه کنید، مانند بازگرداندن سی کاربر اول، سی کاربر بعدی و ده کاربر بعدی.
هنگامی که یک API به صورت داخلی ارتباط برقرار می کند، response معمولا کوتاه است. اما وقتی response بزرگ باشد، استثناست و وقتی استثنا باشد، یعنی یک مشکلی وجود دارد. این زمانی اتفاق میافتد که response از اندازه نرمال خود بیشتر شود (10 کیلوبایت یا 15 کیلوبایت). راه حل در اینجا این است که response را تجزیه کنید و آن را ذره ذره به سرویس دیگری بدهید.