پیش از این توضیح دادیم که هر ریسورس میتواند بسته به نیازی که در سمت کلایند داریم از یکسری Representation مختلف برخوردار باشد تا با نیازهای ما همسو گردد؛ اینکه فرمت ریسورس به چه شکل باشد اصطلاحاً Content Negotiation گفته میشود. به عبارت دیگر، پروسهٔ انتخاب فرمت ریسورس برای یک ریکوئست خاص در زمانهایی که چندین فرمت در اختیار داریم Content Negotiation نامیده میشود.
آشنایی با تفاوتهای Server-driven و Agent-driven در Content Negotiation
چنانچه انتخاب فرمت مناسب برای ریسورس درخواستی از طرف کلاینت بر اساس الگوریتم خاصی در سمتِ سرور صورت پذیرد، این کار اصطلاحاً Server-driven نامیده میشود و در صورتی که انتخاب فرمت توسط کلاینت صورت گیرد، میگوییم که Content Negotiation به صورت Agent-driven صورت گرفته است.
با توجه به اینکه در مدل Server-driven ما از یکسو نیاز به پیشفرضهای بسیاری داریم تا در نهایت بتوانیم دست به انتخاب صحیح فرمت بزنیم و از سوی دیگر این کار منجر به پیچیده شده سورسکد در سمت سرور میشود، این مدل کمتر مورد استفاده قرار میگیرد و در عوض معماری RESTful API بیشتر مبتنی بر Agent-driven است که این کار هم از طریق هِدِرهای پروتکل اچتیتیپی صورت میگیرد. به طور مثال، در سمت سرور هِدِر Content-Type
مشخص میکند که فرمت چه چیزی باشد به طوری که برای مثال داریم:
Content-Type: application/json
از جمله فرمتهای رایج میتوان به text/html
و application/json
اشاره کرد اما این در حالی است که بسته به نیازهای وب سرویس خود، میتوان از فرمتهای دیگری من جمله text/plain
و image/jpeg
و یا application/xml
استفاده کرد. همچنین اگر بخواهیم مشخص کنیم که در سمت کلاینت چه فرمتی مد نظرمان است، میباید از هِدِری تحت عنوان Accept
استفاده نماییم:
Accept: application/json
در واقع، هِدِر فوق به سرور دستور میدهد که فرمت بازگشتی از سمت سرور میباید application/json
باشد و اگر Accept
در ریکوئست موجود نباشد هم سرور فرمت پیشفرض خود را در نظر میگیرد. لازم به یادآوری است که در آنِ واحد میتوان بیش از یک مقدار برای هِدِر Accept
در نظر گرفت به طوری که داریم:
Accept: application/json, application/xml
همانطور که میبینیم، اولویت با فرمت جیسون است اما اگر چنین چیزی امکانپذیر نبود، از سرور خواسته میشود تا فرمت اکسامال را بازگرداند.
در این ارتباط، میتوان از پارامتری تحت عنوان q
به منظور اولویتبندی فرمتها استفاده کرد. مقدار این پارامتر میتواند چیزی مابین ۰ تا ۱ باشد به طوری که ۰ کمترین اولویت و ۱ بیشترین اولویت را دارا است:
Accept: application/json, application/xml;q=0.9, */*;q=0.8
در مثال فوق، کلاینت از سرور میخواهد که ابتدا تلاش کند پاسخ را در قالب فرمت application/json
ارسال کند و اگر ارسال چنین فرمتی امکانپذیر نبود، برود به سراغ فرمت application/xml
و در صورتی که هیچکدام از فرمتهای مذکور امکانپذیر نبودند، بر مبنای دستور */*
هر فرمتی که ساپورت میکرد را در پاسخ به درخواست ارسالی در اختیار کلاینت قرار دهد.