JSON (JavaScript Object Notation) یک قالب استاندارد شده برای نمایش داده های ساخت (ساختار) یافته است. اگرچه JSON در زبان برنامه نویسی جاوا اسکریپت رشد کرده است، اما اکنون یک روش فراگیر برای تبادل داده بین سیستم ها است. اکثر APIهای امروزی درخواستهای JSON را میپذیرند و پاسخهای JSON را صادر میکنند، بنابراین داشتن دانش کاری خوب از قالب و ویژگیهای آن مفید است. در این مقاله به بررسی این سوال می پردازیم : JSON چیست ؟
در این مقاله، ما توضیح خواهیم داد که JSON چیست، چگونه انواع داده های مختلف را بیان می کند، و روش هایی که می توانید آن را در زبان های برنامه نویسی محبوب تولید و استفاده کنید. ما همچنین برخی از محدودیتهای JSON و جایگزینهایی که ظاهر شدهاند را پوشش خواهیم داد.
JSON چیست
JSON در ابتدا توسط داگلاس کراکفورد به عنوان یک قالب بدون حالت برای برقراری ارتباط بین مرورگرها و سرورها ابداع شد. در اوایل دهه 2000، وب سایت ها شروع به دریافت ناهمزمان داده های اضافی از سرور خود، پس از بارگذاری اولیه صفحه کردند. به عنوان یک فرمت مبتنی بر متن که از جاوا اسکریپت مشتق شده است، JSON آورن و استفاده از داده ها را در این برنامه ها ساده تر کرد. این مشخصات در نهایت به عنوان ECMA-404 در سال 2013 استاندارد شد.
JSON همیشه به عنوان یک رشته (string) ارسال می شود. این رشته ها را می توان به طیف وسیعی از انواع داده های اساسی، از جمله اعداد، بولی ها، آرایه ها و موضوعات رمزگشایی کرد. این بدان معناست که سلسله مراتب و روابط موضوع را می توان در طول انتقال حفظ کرد، سپس در انتهای گیرنده به روشی مناسب برای محیط برنامه نویسی مونتاژ کرد.
یک مثال اساسی JSON
این یک نمایش JSON از یک پست وبلاگ است:
{ "id": 1001, "title": "What is JSON?", "author": { "id": 1, "name": "James Walker" }, "tags": ["api", "json", "programming"], "published": false, "publishedTimestamp": null }
این مثال تمام انواع داده های JSON را نشان می دهد. همچنین خلاصه بودن داده های فرمت JSON را نشان می دهد، یکی از ویژگی هایی که آن را برای استفاده در APIها بسیار جذاب کرده است. علاوه بر این، بر خلاف فرمتهای پرمخاطب تر مانند XML، خواندن JSON همانطور که هست نسبتا آسان است.
انواع داده های JSON
شش نوع داده را می توان به صورت بومی در JSON نشان داد:
- رشته ها – رشته ها بین دو علامت نقل قول نوشته می شوند. کاراکترها ممکن است با استفاده از بک اسلش فرار کنند.
- اعداد – اعداد به صورت رقم بدون علامت نقل قول نوشته می شوند. شما می توانید یک جزء کسری برای نشان دادن یک شناور اضافه کنید. اکثر پیادهسازیهای تجزیه JSON یک عدد صحیح را زمانی فرض میکنند که هیچ نقطه اعشاری وجود ندارد.
- Booleans – مقادیر واقعی true و false پشتیبانی می شوند.
- تهی – از مقدار واقعی کلمه می توان برای نشان دادن مقدار خالی یا حذف شده استفاده کرد.
- آرایه ها – آرایه یک لیست ساده است که با کروشه مشخص می شود. هر عنصر در لیست با کاما از هم جدا می شود. آرایه ها می توانند حاوی هر تعداد آیتم باشند و می توانند از انواع داده های پشتیبانی شده استفاده کنند.
- موضوعات – موضوعات توسط براکت های فرفری ایجاد می شوند. آنها مجموعهای از جفتهای کلید-مقدار هستند که در آن کلیدها رشتههایی هستند که در دو علامت نقل قول قرار گرفته اند. هر کلید مقداری دارد که می تواند هر یک از انواع داده های موجود را بگیرد. شما می توانید موضوعات را برای ایجاد سلسله مراتب آبشاری قرار دهید. یک کاما باید به دنبال هر مقدار باشد که به معنای پایان آن جفت کلید-مقدار است.
تجزیه کننده های JSON به طور خودکار این نوع داده ها را به ساختارهای متناسب با زبان خود تبدیل می کنند. برای مثال، لازم نیست شناسه را به صورت دستی به یک عدد صحیح ارسال کنید. تجزیه کل رشته JSON برای نگاشت (نقشه) مقادیر به قالب داده اصلی کافی است.
معناشناسی و اعتبارسنجی
JSON قوانین خاصی دارد که باید هنگام رمزگذاری داده های خود رعایت شوند. رشته هایی که به نحو پایبند نیستند توسط مصرف کنندگان قابل تجزیه نیستند.
توجه به علامت نقل قول در اطراف رشته ها و کلیدهای موضوع بسیار مهم است. همچنین باید اطمینان حاصل کنید که بعد از هر ورودی در یک موضوع یا آرایه از کاما استفاده می شود. با این حال، JSON اجازه کامای انتهایی را پس از آخرین ورودی نمی دهد – درج ناخواسته یکی از دلایل رایج خطاهای اعتبارسنجی است. اکثر ویرایشگرهای متن مشکلات نحوی را برای شما برجسته می کنند و به کشف اشتباهات کمک می کنند.
با وجود این نقاط مشترک، JSON یکی از ساده ترین فرمت های داده برای نوشتن با دست است. اکثر مردم پس از آشنایی با آن، نحو را سریع و راحت می یابند. به طور کلی، JSON نسبت به XML کمتر مستعد خطا است، جایی که تگهای باز و بسته شدن ناهماهنگ، نوتیفیکیشن های نامعتبر الگو، و مشکلات رمزگذاری کاراکتر اغلب باعث ایجاد مشکلات میشوند.
تعیین محتوای JSON
پسوند json. معمولاً زمانی که JSON در یک فایل ذخیره می شود استفاده می شود. محتوای JSON دارای استاندارد MIME application/json است، اگرچه متن/json گاهی اوقات به دلایل سازگاری استفاده می شود. امروزه برای پذیرش و هدرهای HTTP نوع محتوا باید به application/json تکیه کنید.
اکثر APIهایی که از JSON استفاده می کنند همه چیز را در یک موضوع سطح بالا کپسوله می کنند:
{ "error": 1000 }
اگرچه این مورد لازم نیست – یک نوع تحت اللفظی به عنوان گره سطح بالای یک فایل معتبر است، بنابراین نمونههای زیر همگی JSON معتبر هستند:
1000
true
null
آنها به اسکالرهای مربوطه خود در زبان برنامه نویسی شما رمزگشایی می کنند.
کار با JSON
اکثر زبان های برنامه نویسی دارای پشتیبانی داخلی JSON هستند. در اینجا نحوه تعامل با داده های JSON در چند محیط محبوب آورده شده است.
جاوا اسکریپت
در جاوا اسکریپت از متدهای JSON.stringify() و JSON.parse() برای رمزگذاری و رمزگشایی رشته های JSON استفاده می شود:
const post = { id: 1001, title: "What Is JSON?", author: { id: 1, name: "James Walker" } }; const encodedJson = JSON.stringify(post); // {"id": 1001, "title": "What Is JSON?", ...} console.log(encodedJson); const decodedJson = JSON.parse(encodedJson); // James Walker console.log(decodedJson.author.name);
PHP
توابع معادل در PHP عبارتند از json_encode() و json_decode():
$post = [
"id" => 1001,
"title" => "What Is JSON?",
"author" => [
"id" => 1,
"name" => "James Walker"
]
];
$encodedJson = json_encode($post);
// {"id": 1001, "title": "What Is JSON?", ...}
echo $encodedJson;
$decodedJson = json_decode($encodedJson, true);
// James Walker
echo $decodedJson["author"]["name"];
پایتون
پایتون json.dumps() و json.loads() را به ترتیب برای مرتب کردن (نوبتی کردن) و deserialize فراهم می کند:
import json
post = {
"id": 1001,
"title": "What Is JSON?",
"author": {
"id": 1,
"name": "James Walker"
}
}
encodedJson = json.dumps(post)
# {"id": 1001, "title": "What Is JSON?", ...}
print(encodedJson)
decodedJson = json.loads(encodedJson)
# James Walker
print(decodedJson["author"]["name"])
Ruby
روبی JSON.generate و JSON.parse را ارائه می دهد:
require "json"
post = {
"id" => 1001,
"title" => "What Is JSON?",
"author" => {
"id" => 1,
"name" => "James Walker"
}
}
encodedJson = JSON.generate(post)
# {"id": 1001, "title": "What Is JSON?", ...}
puts encodedJson
decodedJson = JSON.parse(encodedJson)
# James Walker
puts decodedJson["author"]["name"]
محدودیت های JSON
JSON یک فرمت سبک وزن است که بر انتقال مقادیر در ساختار داده شما متمرکز شده است. این باعث می شود تجزیه سریع و کار با آن آسان باشد، اما به این معنی است که اشکالاتی وجود دارد که می تواند باعث ناامیدی شود. در اینجا برخی از بزرگترین مشکلات وجود دارد.
بدون نظر
دادههای JSON نمیتوانند شامل نظرات باشند. فقدان حاشیه نویسی وضوح را کاهش می دهد و شما را مجبور می کند داکیونت ها را در جای دیگری قرار دهید. این میتواند JSON را برای موقعیتهایی مانند فایلهای پیکربندی نامناسب کند، جایی که تغییرات به ندرت انجام میشود و ممکن است اهداف فیلدها نامشخص باشد.
بدون الگوها
JSON به شما اجازه نمی دهد یک الگو برای داده های خود تعریف کنید. به عنوان مثال، هیچ راهی برای اعمال این موضوع وجود ندارد که id یک فیلد عدد صحیح ضروری است. این می تواند به ساختارهای داده ناخواسته منجر شود.
بدون ارجاع (رفرنس)
فیلدها نمی توانند به مقادیر دیگری در ساختار داده ارجاع دهند. این اغلب باعث تکرار می شود که حجم فایل را افزایش می دهد. با بازگشت به نمونه پست وبلاگ قبلی، می توانید لیستی از پست های وبلاگ را به شرح زیر داشته باشید:
{
"posts": [
{
"id": 1001,
"title": "What is JSON?",
"author": {
"id": 1,
"name": "James Walker"
}
},
{
"id": 1002,
"title": "What is SaaS?",
"author": {
"id": 1,
"name": "James Walker"
}
}
]
}
هر دو پست نویسنده یکسانی دارند، اما اطلاعات مرتبط با آن موضوع باید کپی می شد. در یک دنیای ایدهآل، پیادهسازی تجزیهکننده JSON میتواند ساختار نشانداده شده در بالا را از ورودی مشابه زیر تولید کند:
{
"posts": [
{
"id": 1001,
"title": "What is JSON?",
"author": "{{ .authors.james }}"
},
{
"id": 1002,
"title": "What is SaaS?",
"author": "{{ .authors.james }}"
}
],
"authors": {
"james": {
"id": 1,
"name": "James Walker"
}
}
}
این در حال حاضر با JSON استاندارد امکان پذیر نیست.
بدون انواع داده های پیشرفته
شش نوع داده پشتیبانی شده بسیاری از انواع رایج ارزش را حذف می کنند. JSON نمی تواند تاریخ، زمان، یا نقاط موقعیت جغرافیایی را به صورت بومی ذخیره کند، بنابراین باید در مورد قالب خود برای این اطلاعات تصمیم بگیرید.
این باعث ایجاد اختلافات ناخوشایند می شود. اگر برنامه شما مُهرهای زمانی را بهعنوان رشته مدیریت میکند، مانند 2022-07-01T12:00:00+00:00، اما یک API خارجی زمان را بهعنوان ثانیههای گذشته از دوره یونیکس – 1657287000 – نشان میدهد، باید به یاد داشته باشید که چه زمانی از هر یک از فرمتها استفاده کنید.
جایگزین های JSON
YAML جایگزین پیشرو JSON است. یک ابرمجموعه از فرمت است که دارای ارائه قابل خواندن برای انسان، انواع داده های سفارشی و پشتیبانی از مراجع است. در نظر گرفته شده است که بیشتر چالشهای قابلیت استفاده مرتبط با JSON را برطرف کند.
YAML برای فایل های پیکربندی و در DevOps، IaC و ابزارهای مشاهده پذیری استقبال گسترده ای داشته است. کمتر به عنوان فرمت تبادل داده برای APIها استفاده می شود. پیچیدگی نسبی YAML به این معنی است که برای تازه واردان کمتر قابل دسترسی است. خطاهای نحوی کوچک می تواند باعث خرابی تجزیه گیج کننده شود.
بافرهای پروتکل (protobufs) یکی دیگر از رقبای در حال ظهور JSON هستند که برای مرتب سازی داده های دارای ساخت طراحی شده اند. Protobuf ها دارای نوتیفیکیشن های نوع داده، فیلدهای مورد نیاز و پشتیبانی از اکثر زبان های برنامه نویسی اصلی هستند. این سیستم به عنوان یک روش کارآمدتر برای انتقال داده ها از طریق شبکه ها محبوبیت پیدا می کند.
خلاصه
JSON یک فرمت نمایش داده مبتنی بر متن است که می تواند شش نوع داده مختلف را رمزگذاری کند. JSON به یکی از اجزای اصلی اکوسیستم توسعه نرم افزار تبدیل شده است. توسط تمام زبان های برنامه نویسی اصلی پشتیبانی می شود و به انتخاب پیش فرض اکثر API های REST که در چند دهه گذشته توسعه یافته اند تبدیل شده است.
در حالی که سادگی JSON بخشی از محبوبیت آن است، محدودیت هایی را نیز در مورد آنچه می توانید با فرمت به دست آورید تحمیل می کند. عدم پشتیبانی از الگوها، نظرات، ارجاعات موضوع و انواع دادههای سفارشی به این معنی است که برخی از برنامهها متوجه میشوند که از آنچه با JSON ممکن است رشد میکنند. جایگزینهای جدید تر مانند YAML و Protobuf به رفع این چالشها کمک کردهاند، در حالی که XML یک رقیب برای برنامههایی است که میخواهند یک طرح داده تعریف کنند و به پرحرفی اهمیتی نمیدهند.