aech
Link
click to show
click to show
متد جدید HTTP؛ آشنایی با QUERY
اگر تا حالا با REST یا HTTP کار کرده باشید، قطعا با متدهای GET، POST، PUT، PATCH و DELETE آشنایی دارید. اما بعد از حدود ۱۶ سال، یک متد جدید به پروتکل HTTP اضافه شده که اسمش QUERY هست.
بیاید با یه مثال ببینیم اصلاً چرا چنین متدی به وجود اومده.
فرض کنید یه endpoint به اسم orders داریم که از Pagination، Filter، Sort و موارد مشابه پشتیبانی میکنه. معمولاً برای دریافت اطلاعات از متد GET استفاده میکنیم و پارامترها رو هم به صورت Query String داخل URL میفرستیم.
GET /orders?status=paid&limit=20&offset=0
این روش سالهاست که استفاده میشه و تو اکثر مواقع هم کاملاً منطقیه، اما چند تا محدودیت داره:
• طول URL محدوده (معمولاً حدود ۸۰۰۰ کاراکتر یا حتی کمتر، بسته به سرور و مرورگر)
• پارامترها داخل URL قرار میگیرن و ممکنه توی لاگهای سرور ثبت بشن.
• ساختن کوئریهای پیچیده مثل فیلترهای پیشرفته، SQL، JSONPath و... سخت یا حتی غیرممکنه.
• انکودینگ کردن پارامترهای پیچیده هم دردسرهای خودش رو داره.
معمولاً وقتی به این محدودیتها میرسیم، خیلیها به جای GET از POST استفاده میکنن و پارامترها رو داخل Body درخواست میذارن.
POST /orders HTTP/1.1
Host: api.example.org
Content-Type: application/x-www-form-urlencoded
select=surname,givenname,email&limit=10&match="email=@example."
این روش مشکل محدودیت URL رو حل میکنه، اما خودش چند تا ایراد مهم داره:
• متد POST ذاتاً Idempotent نیست؛ یعنی اگر وسط ارسال درخواست ارتباط قطع بشه، نمیشه با خیال راحت همون درخواست رو دوباره ارسال کرد، چون ممکنه عملیات دوباره انجام بشه.
• پاسخهای POST به صورت پیشفرض از Cache استاندارد HTTP استفاده نمیکنن.
• پروکسی ها و CDNها نمیتونن تشخیص بدن که ارسال مجدد این درخواست امن هست یا نه.
• هر فریمورک هم معمولاً راهکار خودش رو برای پیادهسازی چیزی مثل Safe POST داره و استاندارد یکپارچهای وجود نداره.
اینجاست که QUERY وارد میشه.
ایدهی اصلی QUERY اینه که بهترین ویژگیهای GET و POST رو با هم ترکیب کنه. از یه طرف مثل GET فقط برای خوندن اطلاعات استفاده میشه و هیچ تغییری روی وضعیت سرور ایجاد نمیکنه، و از طرف دیگه مثل POST میتونه دادههای پیچیده رو داخل Body درخواست ارسال کنه.
در نتیجه درخواستهامون به این شکل درمیاد:
QUERY /orders HTTP/1.1
Host: api.example.org
Content-Type: application/x-www-form-urlencoded
Accept: application/json
select=surname,givenname,email&limit=10&match="email=@example."
به این ترتیب دیگه محدودیت طول URL وجود نداره و میتونید هر نوع فیلتر پیچیده، کوئری، JSONPath یا هر دادهی دیگهای رو داخل Body ارسال کنید.
اما مزیت QUERY فقط این نیست.
یکی از مهمترین ویژگیهای این متد، Idempotent بودنشه. یعنی اگر به هر دلیلی ارتباط شبکه قطع بشه، کلاینت میتونه همون درخواست رو دوباره ارسال کنه و مطمئن باشه نتیجه دقیقاً همون نتیجهی قبلی خواهد بود. برخلاف POST که ارسال مجددش ممکنه باعث ایجاد دادههای تکراری یا اجرای دوبارهی عملیات بشه.
از طرف دیگه، چون QUERY یک متد Safe محسوب میشه و فقط برای دریافت داده استفاده میشه، زیرساختهای HTTP مثل مرورگرها، Proxyها و CDNها میتونن پاسخش رو مثل GET کش کنن. یعنی درخواستهای پیچیدهای که قبلاً مجبور بودیم با POST بفرستیم، حالا میتونن از مزایای Cache استاندارد HTTP هم استفاده کنن.
یکی دیگه از قابلیتهای جالب QUERY اینه که سرور میتونه برای خودِ درخواست یک URI دائمی ایجاد کنه. یعنی به جای اینکه فقط نتیجهی جستجو قابل دسترس باشه، خود Query هم یک آدرس اختصاصی خواهد داشت. هر بار که اون آدرس فراخوانی بشه، همون جستجو دوباره روی دادههای جدید اجرا میشه. این قابلیت برای Share کردن جستجوها، Bookmark کردنشون یا اجرای دورهای یک Query بدون ارسال دوبارهی Body خیلی کاربردیه.
در نهایت، متد QUERY به صورت رسمی استاندارد شده، اما هنوز راه زیادی تا استفادهی گسترده ازش باقی مونده. بعضی از اکوسیستمها مثل Go و Java کار روی پشتیبانی ازش رو شروع کردن و احتمالاً در آینده اسم این متد رو بیشتر خواهیم شنید. البته فعلاً پشتیبانی ازش محدود به چند کتابخونه و سرور خاصه و هنوز اکثر فریمورکها و API Gatewayها ازش پشتیبانی کامل ندارن.
اگر دوست دارید بیشتر درباره این متد بدونید، پیشنهاد میکنم RFC مربوط بهش رو هم بخونید:
https://www.rfc-editor.org/info/rfc10008
#programming
@Syntax_fa
52 · 2.8K ·