§

آزمایش عبارات JSONPath

قالب خروجی:
مرجع سریع JSONPath
Token Meaning
$عنصر ریشه سند
@عنصر جاری (در داخل عبارات فیلتر استفاده می‌شود)
.عملگر عضو فرزند: یک فرزند نام‌گذاری‌شده را انتخاب می‌کند
..پیمایش بازگشتی: همه فرزندان را جستجو می‌کند
*کارت وحشی: هر عنصر یا ویژگی را تطبیق می‌دهد
[*]همه آیتم‌های یک آرایه
[n]عنصر آرایه در ایندکس n (از صفر شروع می‌شود)
[start:end]برش آرایه از start تا (بدون احتساب) end
[?(@.x)]فیلتر: آیتم‌هایی که ویژگی x در آن‌ها وجود دارد
[?(@.x==1)]فیلتر: آیتم‌هایی که ویژگی x برابر ۱ است
[(@.length-1)]عبارت اسکریپت: آخرین عنصر یک آرایه

در اکوسیستم توسعه‌دهندگان ایران، JSONPath در هر جا که باید پاسخ API در برابر قرارداد بررسی شود ضروری است: تیم‌های Shaparak و بانک مرکزی که مجموعه‌های تست رگرسیون برای API‌های استاندارد بانکداری می‌نویسند، از JSONPath برای تأیید فیلدهای پاسخ استفاده می‌کنند. در اسکریپت‌های بارگذاری k6، عبارت‌های jsonpath() مقادیر را از بدنه‌های پاسخ استخراج می‌کنند تا آستانه‌های SLA را کنترل کنند. اجرای این عبارت‌ها در یک تب مرورگر، داده‌های fixture اختصاصی، اطلاعات شخصی مشتری و پاسخ‌های API پیش‌از-انتشار را از هر سرویس میزبانی شده دور نگه می‌دارد.

JSONPath چیست؟

JSONPath یک زبان پرس‌وجو برای اسناد JSON است، معادل JSON برابر XPath برای XML. Stefan Goessner آن را در سال ۲۰۰۷ به عنوان روشی کوتاه و خوانا برای اشاره به یک گره درون درخت JSON بدون نوشتن پارسر پیشنهاد داد. یک عبارت با انتخاب‌گر ریشه $ شروع می‌شود و دسترسی‌های ویژگی، زیرنویس آرایه، کارت‌های وحشی، پیمایش بازگشتی و شرط‌های فیلتر را زنجیر می‌کند تا گره‌های مورد نظر را انتخاب کند. در سال ۲۰۲۴ IETF RFC 9535 را برای استانداردسازی سینتکسی که در پیاده‌سازی‌های مختلف پراکنده شده بود منتشر کرد؛ این تستر روی jsonpath-plus، یک پیاده‌سازی JavaScript پرکاربرد اجرا می‌شود که پیش‌نویس Goessner، بیشتر RFC 9535 و چند عملگر پسوندی را پوشش می‌دهد.

JSONPath چگونه کار می‌کند

یک عبارت JSONPath از چپ به راست خوانده می‌شود و یک سند JSON را گام به گام پیمایش می‌کند. هر گام مجموعه گره‌هایی را که از گام قبل باقی مانده‌اند می‌گیرد و آن‌ها را بیشتر محدود می‌کند. خط لوله ارزیابی کامل:

  1. لنگر انداختن با انتخاب‌گر ریشه $. هر عبارت از اینجا شروع می‌شود و به مقدار سطح بالا، چه یک شیء باشد چه یک آرایه، اشاره می‌کند. نام‌های ویژگی بدون $ پیشرو JSONPath معتبر نیستند.
  2. پیمایش به اعضای فرزند با نوتیشن نقطه ($.store.book) یا نوتیشن براکت ($['store']['book']). نوتیشن براکت زمانی الزامی است که یک کلید حاوی فاصله، خط تیره یا هر کاراکتری که یک شناسه معتبر نیست باشد.
  3. جستجو در همه سطوح به یکباره با عملگر پیمایش بازگشتی ... عبارت $..author همه مقادیر author را در هر نقطه‌ای از درخت، صرف‌نظر از عمق، جمع‌آوری می‌کند. این عملگری است که JMESPath ندارد.
  4. انتخاب عناصر آرایه بر اساس ایندکس ([0]، [-1] برای آخرین آیتم در jsonpath-plus)، برش آن‌ها با نوتیشن [start:end] ([0:3] سه عنصر اول را برمی‌گرداند)، یا گرفتن همه عناصر با کارت وحشی [*].
  5. فیلتر کردن عناصر با یک شرط داخل [?(...)]. در داخل شرط، @ به عنصر جاری اشاره می‌کند، بنابراین [?(@.price<10)] فقط آیتم‌هایی را نگه می‌دارد که فیلد price آن‌ها کمتر از ۱۰ است. فیلترها با بقیه مسیر ترکیب می‌شوند، بنابراین می‌توانید فیلتر کنید سپس پیمایش کنید، یا پیمایش کنید سپس فیلتر کنید.
  6. انتخاب قالب خروجی. مقادیر خود داده تطبیق‌یافته را برمی‌گرداند. مسیرها JSONPath هر تطابق را برمی‌گرداند تا ببینید موتور چه چیزی را حل کرده است. اشاره‌گرها معادل RFC 6901 JSON Pointer را برای هر تطابق برمی‌گرداند، مفید وقتی مصرف‌کننده پایین‌دستی JSON Patch یا یک اعتبارسنج JSON Schema است.

چرا از این تستر JSONPath استفاده کنیم؟

  • JSON شما هرگز مرورگر را ترک نمی‌کند. پرس‌وجو داخل صفحه اجرا می‌شود، بنابراین fixture‌های تولیدی، اطلاعات شخصی مشتری و پاسخ‌های API پیش‌از-انتشار روی دستگاه شما باقی می‌مانند.
  • موتور jsonpath-plus 9.x است، همان کتابخانه‌ای که بسیاری از مجموعه‌های تست تولیدی و ادعاهای CI را پشتیبانی می‌کند. نتایجی که اینجا می‌بینید با نتایجی که خط لوله build شما می‌بیند مطابقت دارد.
  • سه حالت خروجی مصرف‌کنندگان پایین‌دستی رایج را پوشش می‌دهند: مقادیر خام برای کپی-پیست، مسیرها برای اشکال‌زدایی حل‌وفصل موتور، و RFC 6901 اشاره‌گرها برای جریان‌های کاری JSON Patch و JSON Schema.
  • عبارات فیلتر با preventEval: true اجرا می‌شوند، بنابراین یک پرس‌وجوی پیست‌شده نمی‌تواند JavaScript دلخواه را در برابر صفحه میزبان اجرا کند. این موضوع زمانی اهمیت دارد که عبارت از یک پیام Slack، یک تیکت Jira یا کلیپ‌بورد همکار آمده باشد.

کاربردهای رایج JSONPath

JSONPath در هر جا که کد باید بدون نوشتن پیمایش بازگشتی دستی یک فیلد از payload JSON استخراج کند ظاهر می‌شود:

  • تست‌های Postman: تب Tests در Postman pm.response.json() را به همراه دسترسی JSONPath برای ادعاها در معرض دید قرار می‌دهد. تیم‌ها یک عبارت واحد مانند $.data.user.email می‌نویسند تا یک فیلد از پاسخ استخراج کنند و در CI ادعا کنند.
  • تست‌های بارگذاری k6: اسکریپت‌های k6 داخل یک بلاک check() تابع jsonpath() را صدا می‌زنند تا مقادیر را از بدنه‌های پاسخ استخراج کنند و آستانه‌های SLA را تأیید کنند. همان عبارتی که یک قرارداد را در Postman اثبات کرد می‌تواند یک تست بارگذاری را در k6 متوقف کند.
  • JSON DSL برای تبدیل داده: AWS Step Functions داخل InputPath، ResultPath و Parameters JSONPath را ارزیابی می‌کند تا payload‌های رویداد را بین حالت‌ها تغییر شکل دهد. Argo Workflows از JSONPath در withParam برای fan-out وظایف روی یک آرایه استفاده می‌کند. kubectl -o jsonpath از همان سینتکس برای استخراج فیلدها از اشیاء cluster استفاده می‌کند.

مثال عملی

fixture کانونیک Goessner سند کتابفروشی با چهار کتاب است که هر کدام دارای category، author، title و price هستند. در برابر آن fixture، عبارت $.store.book[?(@.price<10)].title در سه گام اجرا می‌شود. اول، $.store.book به آرایه همه چهار کتاب حل می‌شود. سپس، فیلتر [?(@.price<10)] فقط کتابی را نگه می‌دارد که قیمت آن زیر ۱۰ است (ورودی با قیمت ۸.۹۵). در نهایت، .title عنوان آن کتاب را استخراج می‌کند. نتیجه ["Sayings of the Century"] است. تغییر به مسیرها ["$['store']['book'][0]['title']"] را برمی‌گرداند، و اشاره‌گرها ["/store/book/0/title"] را برمی‌گرداند.

عبارات خود را اینجا نمونه‌سازی کنید، سپس مستقیماً به Postman، k6، kubectl یا یک ماشین حالت Step Functions منتقل کنید. پیست کنید، پرس‌وجو کنید، کپی کنید. هیچ‌چیز از شبکه عبور نمی‌کند.

JSONPath چیست؟

JSONPath یک زبان پرس‌وجو برای اسناد JSON است، مشابه XPath برای XML. توسط Stefan Goessner در سال ۲۰۰۷ پیشنهاد شد و توسط IETF به عنوان RFC 9535 در سال ۲۰۲۴ استانداردسازی شد.

از سینتکس عبارت فشرده‌ای استفاده می‌کند که با $ (ریشه سند) شروع می‌شود و از نوتیشن نقطه، زیرنویس آرایه، کارت‌های وحشی، برش، پیمایش بازگشتی (..) و عبارات فیلتر ([?(...)]) برای انتخاب گره‌ها داخل درخت JSON پشتیبانی می‌کند.

تفاوت JSONPath با JMESPath یا jq چیست؟

هر سه JSON را پرس‌وجو می‌کنند، اما دستور زبان و اهدافشان متفاوت است. JMESPath استاندارد AWS CLI / SDK است: سخت‌گیرانه‌تر از JSONPath، بدون پیمایش بازگشتی، ساخته‌شده برای projection قابل‌پیش‌بینی بدون عوارض جانبی.

jq یک زبان اسکریپت‌نویسی Turing-complete است که نه‌تنها JSON را پرس‌وجو می‌کند بلکه آن را تبدیل، کاهش و جریان می‌دهد. JSONPath بین آن‌ها قرار دارد: بیان‌گرتر از JMESPath به لطف پیمایش بازگشتی و فیلترها، سبک‌تر از jq، و پرکاربردترین سینتکس در ابزار تست عمومی (Postman، Playwright، REST Assured، kubectl، Step Functions). این تستر JSONPath را پیاده‌سازی می‌کند.

این تستر از چه dialect استفاده می‌کند؟

این تستر jsonpath-plus 9.x را اجرا می‌کند. آن کتابخانه مشخصات Goessner 2007 را پیاده‌سازی می‌کند، بیشتر RFC 9535 را پوشش می‌دهد، و عملگرهای پسوندی مانند بررسی نوع (@.string()، @.number()، @.boolean()) و ناوبری والد (^) را اضافه می‌کند.

پرچم preventEval: true همیشه تنظیم است، بنابراین شرط‌های فیلتر از طریق یک مفسر امن اجرا می‌شوند نه تابع داخلی JavaScript eval(). یک پرس‌وجوی پیست‌شده نمی‌تواند کد دلخواه را در برابر این صفحه اجرا کند.

آیا می‌توانم مقادیر تطابق‌یافته فردی را کپی کنم؟

بله. دکمه کپی در کلیپ‌بورد بلاک نتیجه کامل را به عنوان یک آرایه JSON کپی می‌کند. برای گرفتن یک مقدار واحد، حالت خروجی را به مقادیر تغییر دهید، سپس خطی که می‌خواهید در textarea نتیجه انتخاب کنید و از میانبر کپی معمول مرورگر خود (Ctrl/Cmd + C) استفاده کنید.

خروجی متن JSON ساده است، بنابراین به طور تمیز در ویرایشگر کد، ترمینال، یک تست Postman یا یک پیام Slack پیست می‌شود.