<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged json</title>
<link>https://coderlegion.com/tag/json</link>
<description>Powered by Question2Answer</description>
<item>
<title>Three ways a jq one-liner lies to your bash script</title>
<link>https://coderlegion.com/28027/three-ways-a-jq-one-liner-lies-to-your-bash-script</link>
<description>&lt;p&gt;Most &quot;the filter looks right but the script misbehaves&quot; bugs come down to three silent failure modes.&lt;/p&gt;
&lt;p&gt;First, a missing &lt;code&gt;-r&lt;/code&gt;. jq outputs JSON by default, so a string arrives with its quotes attached — your variable holds &lt;code&gt;&quot;web-01&quot;&lt;/code&gt;, quotes included, and a comparison against web-01 never matches. Any value headed into a shell variable, filename, or test wants &lt;code&gt;-r&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Second, missing keys don't error. jq emits &lt;code&gt;null&lt;/code&gt;, which lands in bash as a literal four-character string — non-empty, so &lt;code&gt;[ -n ]&lt;/code&gt; guards pass and backup-null.tar.gz gets written. The &lt;code&gt;//&lt;/code&gt; operator supplies a real fallback.&lt;/p&gt;
&lt;p&gt;Third, select() compares exactly. A value that is almost right matches nothing, and nothing is not an error:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;jq -r '.items[] | select(.active == true) | .name'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the API sends &lt;code&gt;&quot;active&quot;: &quot;true&quot;&lt;/code&gt; as a string, that item is skipped. If you match &lt;code&gt;&quot;Web-01&quot;&lt;/code&gt; against &lt;code&gt;&quot;web-01&quot;&lt;/code&gt;, zero elements come back. Either way jq prints nothing and exits 0, so the silence reads as success.&lt;/p&gt;
&lt;p&gt;All three share the same fingerprint: exit code zero, plausible output, wrong result. The fastest way I've found to catch them before they ship is building the filter against the actual response: this &lt;a rel=&quot;nofollow&quot; href=&quot;https://bashsnippets.xyz/tools/jq-filter-builder&quot;&gt;interactive jq filter builder with a live in-browser preview&lt;/a&gt; lets you click through your real JSON to build the path, handles the &lt;code&gt;-r&lt;/code&gt;, the &lt;code&gt;//&lt;/code&gt; fallback and select() quoting for you, and shows exactly what the filter emits before anything runs.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28027/three-ways-a-jq-one-liner-lies-to-your-bash-script</guid>
<pubDate>Tue, 27 Oct 2026 13:00:00 +0000</pubDate>
</item>
<item>
<title>The Trigger Swap That Broke Every Downstream Reference</title>
<link>https://coderlegion.com/27289/the-trigger-swap-that-broke-every-downstream-reference</link>
<description>&lt;p&gt;I built this workflow — a lead intake automation for a made-up client, Ferrer Window Co. — with a Form Trigger first, even though I knew from the start it needed to end up on a Webhook. That wasn't the plan drifting. It was deliberate: I'd used webhooks before and Form Trigger less, so building with Form Trigger first let me see real data coming through without also holding webhook payload structure in my head at the same time. Get the logic right, then swap the trigger once everything else was solid.&lt;/p&gt;
&lt;p&gt;And the logic did get solid. By the time I was ready to swap, I had a full chain working: an IF node filtering out junk leads (both phone and email empty), a Set node defaulting empty message fields to &quot;No message provided,&quot; and Sheets and Slack both branching off that same cleaned data independently. Tested both edge cases — junk lead correctly stopped, empty message correctly defaulted. Everything passed.&lt;/p&gt;
&lt;p&gt;Then I deleted the Form Trigger, added a Webhook node, and sent a test payload through Postman.&lt;/p&gt;
&lt;p&gt;It broke immediately.&lt;/p&gt;
&lt;p&gt;Not the logic — the logic was fine. What broke was every single reference to the data. With Form Trigger, the payload had come through flat:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;Name&quot;: &quot;Tarek&quot;,
  &quot;Phone&quot;: &quot;02-011-41104-582&quot;,
  &quot;Email&quot;: &quot;*Emails are not allowed*&quot;,
  &quot;Service address&quot;: &quot;Primary school st&quot;,
  &quot;Message&quot;: &quot;I want to request an order&quot;,
  &quot;submittedAt&quot;: &quot;2026-08-24T03:24:50.089-04:00&quot;,
  &quot;formMode&quot;: &quot;test&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With Webhook, everything I actually wanted was nested one level down, sitting alongside a pile of raw HTTP metadata I didn't need:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;headers&quot;: {...},
  &quot;body&quot;: {
    &quot;Name&quot;: &quot;Tarek&quot;,
    &quot;Phone&quot;: &quot;02-011-41104-582&quot;,
    ...
  },
  &quot;webhookUrl&quot;: &quot;...&quot;,
  &quot;executionMode&quot;: &quot;test&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every reference I'd written — the IF node's condition, the Set node's field mappings — pointed at &lt;code&gt;$json.Name&lt;/code&gt;, &lt;code&gt;$json.Phone&lt;/code&gt;, and so on. None of it was wrong, exactly. It was just pointed at a shape of data that no longer existed. The whole workflow's reasoning was intact and now unreachable.&lt;/p&gt;
&lt;p&gt;So I went back through it node by node — the IF node's conditions, the Set node's mappings — and repointed every one from &lt;code&gt;$json.X&lt;/code&gt; to &lt;code&gt;$json.body.X&lt;/code&gt;. Nothing about &lt;em&gt;what&lt;/em&gt; the workflow decided changed. Only &lt;em&gt;where it looked&lt;/em&gt; for the thing it was deciding about.&lt;/p&gt;
&lt;p&gt;Once that was done, I didn't just assume it worked because the references compiled. I re-ran both edge cases through the webhook path — both phone and email empty, and an empty message field — to confirm the filter still stopped junk leads and the default still kicked in, now that the data was arriving through a different shape entirely.&lt;/p&gt;
&lt;p&gt;The part I'd flag for anyone doing this same swap later: it's not a dramatic failure. Nothing throws a loud error that points you at the fix. The workflow just quietly stops seeing the data it expects, because the trigger node changed the shape of what &quot;the data&quot; even means. If you built your logic against one trigger's payload structure, swapping the trigger isn't a drop-in replacement — it's a second pass through everything downstream, checking what each node thinks it's looking at.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/27289/the-trigger-swap-that-broke-every-downstream-reference</guid>
<pubDate>Tue, 15 Sep 2026 13:15:42 +0000</pubDate>
</item>
<item>
<title>Why Your LLM Still Returns Broken JSON</title>
<link>https://coderlegion.com/26422/why-your-llm-still-returns-broken-json</link>
<description>&lt;p&gt;Most of us here have shipped something that calls a model and then spends half its code cleaning up whatever came back. This is the writeup I wish I had the first time I wired an LLM into a real pipeline, so I am leaving it here for anyone about to do the same.&lt;/p&gt;
&lt;h3 id=&quot;the-three-workarounds-we-all-wrote-first&quot;&gt;The Three Workarounds We All Wrote First&lt;/h3&gt;
&lt;p&gt;Prompt engineering: tell the model to respond in JSON with these exact fields, and hope. That holds roughly 85 to 95 percent of the time depending on the model, which sounds fine until you are handling real traffic and it fails a few hundred times a day.&lt;/p&gt;
&lt;p&gt;Post processing: regex parsers, JSON repair libraries, retry loops. Adds latency and a whole class of bugs that have nothing to do with your actual business logic.&lt;/p&gt;
&lt;p&gt;Function calling: works well for invoking a tool, semantically awkward when all you want is data back rather than a call made.&lt;/p&gt;
&lt;h3 id=&quot;what-constrained-decoding-actually-does&quot;&gt;What Constrained Decoding Actually Does&lt;/h3&gt;
&lt;p&gt;At each generation step the model produces a probability distribution over its entire vocabulary. Constrained decoding masks out every token that would take the output off a valid path through your schema, before sampling happens.&lt;/p&gt;
&lt;p&gt;If your schema says sentiment must be one of positive, negative or neutral, the model cannot emit &quot;somewhat positive&quot;. Those tokens are not available to it. That is enforced in the inference stack rather than in your prompt, which is why the guarantee is absolute instead of probabilistic.&lt;/p&gt;
&lt;h3 id=&quot;json-mode-is-not-schema-enforcement&quot;&gt;JSON Mode Is Not Schema Enforcement&lt;/h3&gt;
&lt;p&gt;This one trips people up constantly. JSON mode guarantees the response parses. It does not guarantee the response has your fields. You can ask for a sentiment and a confidence score and get back &lt;code&gt;{&quot;answer&quot;: &quot;yes&quot;}&lt;/code&gt;, which is perfectly valid JSON and useless to your code.&lt;/p&gt;
&lt;p&gt;Schema enforcement guarantees conformance to the contract: your fields, your types, your enums. If you are shipping to production, that is the one you want.&lt;/p&gt;
&lt;h3 id=&quot;what-it-still-does-not-give-you&quot;&gt;What It Still Does Not Give You&lt;/h3&gt;
&lt;p&gt;The schema promises that price is a number. It does not promise the number is positive, or that the email string is a real address. Schema enforcement removes structural errors and leaves semantic ones, so keep a validation layer such as Pydantic sitting on top of it.&lt;/p&gt;
&lt;p&gt;Worth knowing before you design around it: most providers cap nesting around five levels, strict mode wants every property listed in the required array, and optional fields get expressed as anyOf with a null type.&lt;/p&gt;
&lt;p&gt;The full breakdown, including provider by provider support and the migration path off JSON mode, is here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.adaptiverecall.com/structured-output/&quot;&gt;LLM structured output&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you have hit a case where schema enforcement made things worse rather than better, I would like to hear it. The failure modes are far less documented than the happy path.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/26422/why-your-llm-still-returns-broken-json</guid>
<pubDate>Mon, 07 Sep 2026 16:12:41 +0000</pubDate>
</item>
<item>
<title>JsonToolBox</title>
<link>https://coderlegion.com/26226/jsontoolbox</link>
<description>&lt;p&gt;JsonToolBox is a free, open-source JSON toolkit built for developers, testers, technical writers, and anyone who works with structured data.&lt;/p&gt;
&lt;p&gt;It provides browser-based tools for common JSON tasks, including formatting and beautifying JSON, validating syntax, minifying output, viewing JSON in a structured tree, comparing two JSON documents, and converting JSON to other commonly used formats.&lt;/p&gt;
&lt;p&gt;JsonToolBox is designed for fast, focused use. You can open a tool, paste your data, perform the required operation, and copy or download the result without creating an account. JSON processing is performed locally in your browser, so your JSON content is not uploaded to a remote server for processing.&lt;/p&gt;
&lt;p&gt;Typical use cases include inspecting API responses, debugging configuration files, checking JSON before deployment, preparing examples for documentation, comparing payloads, and converting structured data for development workflows.&lt;/p&gt;
&lt;p&gt;The project is open source and available under the MIT License. The complete source code and development information are available on GitHub.&lt;/p&gt;
&lt;p&gt;Website: &lt;a rel=&quot;nofollow&quot; href=&quot;https://jsontoolbox.cc/&quot;&gt;https://jsontoolbox.cc&lt;/a&gt;&lt;br&gt;
Source code: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kbmjj123/jsontoolbox.cc&quot;&gt;https://github.com/kbmjj123/jsontoolbox.cc&lt;/a&gt;&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/26226/jsontoolbox</guid>
<pubDate>Fri, 04 Sep 2026 22:58:29 +0000</pubDate>
</item>
<item>
<title>Replay a Flight After It Lands: Historical Flight Tracker API</title>
<link>https://coderlegion.com/25985/replay-a-flight-after-it-lands-historical-flight-tracker-api</link>
<description>&lt;p&gt;For developers, historical flight data opens up a more useful layer of analysis. Instead of working with only a final flight status, you can work with timestamped aircraft positions, altitude changes, speed values, route movement, ground status, and aircraft identifiers after the flight is completed.&lt;/p&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://aviation-edge.com/historical-flight-radar-and-flight-tracker-api/&quot;&gt;Aviation Edge Historical Flight Tracker API&lt;/a&gt; provides past flight movement data through a REST API. It returns recorded aircraft positions, altitude, direction, speed, timestamps, airline details, aircraft identifiers, route information, and final flight status.&lt;/p&gt;
&lt;p&gt;In this article, we will look at what the API returns, how developers can work with the data, and what you can build with past flight tracker data.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/4tqxj795wrw907faadvu.jpg&quot; alt=&quot;Historical Flight Tracker API&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-the-api-returns&quot;&gt;What The API Returns&lt;/h3&gt;
&lt;p&gt;The Historical Flight Tracking API is built for retrieving detailed position data for past flights.&lt;/p&gt;
&lt;p&gt;A response includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Departure and arrival airport codes&lt;/li&gt;
&lt;li&gt;Scheduled departure and arrival times&lt;/li&gt;
&lt;li&gt;Airline IATA and ICAO codes&lt;/li&gt;
&lt;li&gt;Flight IATA and ICAO numbers&lt;/li&gt;
&lt;li&gt;Aircraft ICAO24, aircraft type code, and registration number&lt;/li&gt;
&lt;li&gt;Final flight status&lt;/li&gt;
&lt;li&gt;Squawk information when available&lt;/li&gt;
&lt;li&gt;A flightPositions array with recorded movement points&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each item in the flightPositions array represents a point in the aircraft’s journey.&lt;/p&gt;
&lt;p&gt;Those position points include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;latitude&lt;/li&gt;
&lt;li&gt;longitude&lt;/li&gt;
&lt;li&gt;altitude&lt;/li&gt;
&lt;li&gt;direction&lt;/li&gt;
&lt;li&gt;horizontal speed&lt;/li&gt;
&lt;li&gt;vertical speed&lt;/li&gt;
&lt;li&gt;ground/airborne status&lt;/li&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That makes the API useful for rebuilding a past flight path, plotting aircraft movement on a map, or analyzing how a flight progressed from gate to gate.&lt;/p&gt;
&lt;hr&gt;
&lt;h5 id=&quot;example-request&quot;&gt;Example Request&lt;/h5&gt;
&lt;p&gt;Here is an example request for historical tracking data for a flight from London Heathrow.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;GET https://aviation-edge.com/v2/public/flight_track_history?key=YOUR_API_KEY&amp;amp;depIata=LHR&amp;amp;flightIata=BA203&amp;amp;depDate=2025-10-20
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;You can review the full parameter list and API specs in the &lt;a rel=&quot;nofollow&quot; href=&quot;https://aviation-edge.com/developers/#historical_tracker&quot;&gt;Historical Flight Tracker API documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h5 id=&quot;example-output&quot;&gt;Example Output&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;[
  {
    &quot;aircraft&quot;: {
      &quot;icao24&quot;: &quot;40749B&quot;,
      &quot;icaoCode&quot;: &quot;B789&quot;,
      &quot;regNumber&quot;: &quot;G-ZBKR&quot;
    },
    &quot;airline&quot;: {
      &quot;iataCode&quot;: &quot;BA&quot;,
      &quot;icaoCode&quot;: &quot;BAW&quot;
    },
    &quot;arrival&quot;: {
      &quot;iataNumber&quot;: &quot;BOS&quot;,
      &quot;icaoNumber&quot;: &quot;KBOS&quot;,
      &quot;scheduledTime&quot;: &quot;2025-10-20T20:10:00.000&quot;
    },
    &quot;departure&quot;: {
      &quot;iataNumber&quot;: &quot;LHR&quot;,
      &quot;icaoNumber&quot;: &quot;EGLL&quot;,
      &quot;scheduledTime&quot;: &quot;2025-10-20T17:35:00.000&quot;
    },
    &quot;flight&quot;: {
      &quot;iataNumber&quot;: &quot;BA203&quot;,
      &quot;icaoNumber&quot;: &quot;BAW50G&quot;
    },
    &quot;flightPositions&quot;: [
      {
        &quot;altitude&quot;: &quot;0.00&quot;,
        &quot;direction&quot;: &quot;90.00&quot;,
        &quot;horizontal_speed&quot;: &quot;1.85&quot;,
        &quot;isGround&quot;: 1,
        &quot;latitude&quot;: &quot;51.469400&quot;,
        &quot;longitude&quot;: &quot;-0.471700&quot;,
        &quot;updated&quot;: 1760978610,
        &quot;vspeed&quot;: &quot;0.00&quot;
      },
      {
        &quot;altitude&quot;: &quot;0.00&quot;,
        &quot;direction&quot;: &quot;90.00&quot;,
        &quot;horizontal_speed&quot;: &quot;0.00&quot;,
        &quot;isGround&quot;: 1,
        &quot;latitude&quot;: &quot;51.469400&quot;,
        &quot;longitude&quot;: &quot;-0.471700&quot;,
        &quot;updated&quot;: 1760978792,
        &quot;vspeed&quot;: &quot;0.00&quot;
      },
...
...
      {
        &quot;altitude&quot;: &quot;0.00&quot;,
        &quot;direction&quot;: &quot;33.00&quot;,
        &quot;horizontal_speed&quot;: &quot;33.34&quot;,
        &quot;isGround&quot;: 1,
        &quot;latitude&quot;: &quot;42.365300&quot;,
        &quot;longitude&quot;: &quot;-71.012400&quot;,
        &quot;updated&quot;: 1761004300,
        &quot;vspeed&quot;: &quot;0.00&quot;
      },
      {
        &quot;altitude&quot;: &quot;0.00&quot;,
        &quot;direction&quot;: &quot;303.00&quot;,
        &quot;horizontal_speed&quot;: &quot;11.11&quot;,
        &quot;isGround&quot;: 1,
        &quot;latitude&quot;: &quot;42.373000&quot;,
        &quot;longitude&quot;: &quot;-71.018500&quot;,
        &quot;updated&quot;: 1761004451,
        &quot;vspeed&quot;: &quot;0.00&quot;
      }
    ],
    &quot;status&quot;: &quot;landed&quot;,
    &quot;system&quot;: {
      &quot;squawk&quot;: null,
      &quot;updated&quot;: 1761004451
    }
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;flightPositions&lt;/code&gt; array is updated with recorded position points throughout the flight, typically at around 10-minute intervals, and added to the output as part of the historical flight track.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Field &lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;latitude&lt;/code&gt; / &lt;code&gt;longitude&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Aircraft position&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;altitude&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Aircraft altitude&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;direction&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Direction of travel&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;horizontal_speed&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Horizontal speed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;vspeed&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Vertical speed&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;isGround&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Whether the aircraft is on the ground&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;updated&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Unix timestamp for that position point&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h4 id=&quot;fetching-historical-flight-data-in-javascript&quot;&gt;Fetching Historical Flight Data in JavaScript&lt;/h4&gt;
&lt;p&gt;Here is a basic Axios example.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const axios = require(&quot;axios&quot;);

const API_KEY = &quot;YOUR_API_KEY&quot;;

const endpoint = `https://aviation-edge.com/v2/public/flight_track_history?key=${API_KEY}&amp;amp;depIata=LHR&amp;amp;flightIata=BA203&amp;amp;depDate=2025-10-20`;

async function fetchHistoricalFlight() {
  try {
    const response = await axios.get(endpoint);
    return response.data;
  } catch (error) {
    console.error(&quot;Error fetching historical flight data:&quot;, error.message);
    return null;
  }
}

fetchHistoricalFlight().then((data) =&amp;gt; {
  if (!data || data.length === 0) {
    console.log(&quot;No historical flight data found.&quot;);
    return;
  }

  console.log(data[0]);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;extracting-the-flight-path&quot;&gt;Extracting the Flight Path&lt;/h4&gt;
&lt;p&gt;To plot the aircraft path on a map, you usually only need latitude and longitude from each position point. The output can be passed into a mapping library such as Leaflet, Mapbox, or Google Maps to draw the route.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function getFlightPath(flight) {
  return flight.flightPositions.map((point) =&amp;gt; ({
    lat: Number(point.latitude),
    lng: Number(point.longitude),
    timestamp: point.updated
  }));
}

fetchHistoricalFlight().then((data) =&amp;gt; {
  const flight = data[0];
  const path = getFlightPath(flight);

  console.log(path);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;finding-the-max-altitude&quot;&gt;Finding the Max Altitude&lt;/h4&gt;
&lt;p&gt;A simple way to find the highest recorded altitude in the position array.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function getMaxAltitude(flight) {
  return Math.max(
    ...flight.flightPositions.map((point) =&amp;gt; Number(point.altitude))
  );
}

fetchHistoricalFlight().then((data) =&amp;gt; {
  const flight = data[0];

  console.log(&quot;Max altitude:&quot;, getMaxAltitude(flight));
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;example-use-cases-for-past-flight-track-data&quot;&gt;Example Use Cases for Past Flight Track Data&lt;/h4&gt;
&lt;p&gt;Historical flight tracking data can be used in many aviation and data products.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flight Replay&lt;/strong&gt;: Use the latitude, longitude, altitude, speed, and timestamp fields to replay a flight on a map after it has landed and visualize a past flight.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flight Analytics&lt;/strong&gt;: Analyze altitude changes, speed changes, route shape, ground movement and airborne movement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Airline or Airport Dashboards&lt;/strong&gt;: Build dashboards showing past flight movement data for specific flights, airlines, airports, or aircraft.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Aircraft History Tools&lt;/strong&gt;: Use aircraft registration number or ICAO24 filters to review past aircraft movement data for a specific aircraft.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;bringing-past-flights-back-to-life---all-with-data-&quot;&gt;Bringing Past Flights Back to Life - All With Data!&lt;/h4&gt;
&lt;p&gt;The Aviation Edge Historical Flight Tracking API is designed for developers who need more than a static flight record.&lt;/p&gt;
&lt;p&gt;It gives you timestamped aircraft movement data that can be mapped, replayed, filtered, stored, and analyzed.&lt;/p&gt;
&lt;p&gt;Whether you are building a flight replay tool, an aviation dashboard, an aircraft history feature, or a route analysis product, past flight tracking data gives you the raw movement layer behind a completed flight.&lt;/p&gt;
&lt;p&gt;You can explore the Historical Flight Tracker API firsthand by getting your personal &lt;a rel=&quot;nofollow&quot; href=&quot;https://aviation-edge.com/premium-api/&quot;&gt;API key here&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/raqlonygr49k6w0f7ran.png&quot; alt=&quot;Aviation Edge&quot;&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/25985/replay-a-flight-after-it-lands-historical-flight-tracker-api</guid>
<pubDate>Tue, 01 Sep 2026 10:26:12 +0000</pubDate>
</item>
<item>
<title>A JSONPath engine that follows the spec and can't run code</title>
<link>https://coderlegion.com/25345/a-jsonpath-engine-that-follows-the-spec-and-cant-run-code</link>
<description>&lt;p&gt;I needed to pull a few fields out of some JSON. Nothing exotic, a couple of nested values and one filtered list. So I did the ordinary thing, reached for a JSONPath library, wrote a query, and moved on.&lt;/p&gt;
&lt;p&gt;A week later I swapped that library for an unrelated reason, and the same query came back with different results. Not wrong exactly, just different. My &lt;code&gt;$..author&lt;/code&gt; matched one extra node, a slice counted from the other end, and a filter that worked before now threw. Welcome to JSONPath, where for the better part of two decades every implementation agreed on the dollar sign and improvised the rest.&lt;/p&gt;
&lt;h3 id=&quot;the-standard-nobody-had&quot;&gt;The standard nobody had&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://goessner.net/articles/JsonPath/&quot;&gt;Stefan Gössner's original write-up&lt;/a&gt; from 2007 sketched the idea and left the corners to the reader. Everyone filled them in differently. Does &lt;code&gt;$..book[0]&lt;/code&gt; give you the first book in each array or the first book overall? Do you write a filter &lt;code&gt;[?(@.price)]&lt;/code&gt; or &lt;code&gt;[?@.price]&lt;/code&gt;? What does a negative index do at the edge of an array? Pick two libraries and you could get two answers to each.&lt;/p&gt;
&lt;p&gt;That changed in February 2024, when the IETF published &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.rfc-editor.org/rfc/rfc9535&quot;&gt;RFC 9535&lt;/a&gt; and wrote the rules down: the selectors, the filter grammar, the meaning of a missing value, with a &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/jsonpath-standard/jsonpath-compliance-test-suite&quot;&gt;compliance test suite&lt;/a&gt; so you can check yourself against them. JSONPath went from folklore to specification.&lt;/p&gt;
&lt;p&gt;So I wanted a library that actually followed it. Reading the spec, I noticed the part that makes JSONPath worth using is also the part that keeps turning up in security advisories.&lt;/p&gt;
&lt;h3 id=&quot;the-filter-that-runs-a-shell&quot;&gt;The filter that runs a shell&lt;/h3&gt;
&lt;p&gt;Filters are the reason you pick JSONPath over a hand-written loop. &lt;code&gt;$..book[?@.price &amp;lt; 10]&lt;/code&gt; reads like a sentence and does real work: keep the nodes where the comparison holds.&lt;/p&gt;
&lt;p&gt;Evaluating that comparison is where libraries cut corners. &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/JSONPath-Plus/JSONPath&quot;&gt;jsonpath-plus&lt;/a&gt;, the most-downloaded option on npm, built its filters on generated code. That works right up until part of the query comes from somewhere you don't control. At that point a filter is no longer a filter, it is a program running with your process's permissions, and that is exactly how it went: &lt;a rel=&quot;nofollow&quot; href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2024-21534&quot;&gt;CVE-2024-21534&lt;/a&gt; was a remote code execution through a crafted JSONPath, with more to follow when the first patch left a gap.&lt;/p&gt;
&lt;p&gt;There is a quieter cost too. Generating code at runtime needs &lt;code&gt;'unsafe-eval'&lt;/code&gt; in your Content Security Policy, and if you have already shipped a strict CSP, granting that back undoes most of the reason you shipped it.&lt;/p&gt;
&lt;h3 id=&quot;a-scout-that-stays-on-the-path&quot;&gt;A scout that stays on the path&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/robinvdvleuten/padvinder&quot;&gt;padvinder&lt;/a&gt; is my answer to both. The name is Dutch for &quot;pathfinder&quot;, and also the word for a scout, which fit something whose entire job is to go find a node and come back without disturbing anything on the way. It implements RFC 9535 in roughly 2.75KB min+gzip with no dependencies, and it clears all 456 valid-selector cases in the official suite.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { query, find } from 'padvinder';

const data = { store: { book: [
  { title: 'Sayings of the Century', price: 8.95, category: 'reference' },
  { title: 'Sword of Honour', price: 12.99, category: 'fiction' },
  { title: 'Moby Dick', price: 8.99, category: 'fiction' },
] } };

find('$..book[?@.price &amp;lt; 10].title', data);
// =&amp;gt; ['Sayings of the Century', 'Moby Dick']

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;find&lt;/code&gt; runs a query once. For a path you will reuse, &lt;code&gt;query&lt;/code&gt; compiles it and returns a runner you can point at different data:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const fiction = query('$.store.book[?@.category == &quot;fiction&quot;].title');
fiction(data); // =&amp;gt; ['Sword of Honour', 'Moby Dick']

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hand it a broken path and it throws a &lt;code&gt;SyntaxError&lt;/code&gt; at compile time, not partway through your data. A path that matches nothing returns &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-parts-of-the-spec-worth-carrying-around&quot;&gt;The parts of the spec worth carrying around&lt;/h3&gt;
&lt;p&gt;Selectors are the dependable half. If you have written JSONPath they hold no surprises: &lt;code&gt;$&lt;/code&gt; for the root, &lt;code&gt;.name&lt;/code&gt; or &lt;code&gt;['name']&lt;/code&gt; for a child, &lt;code&gt;[0]&lt;/code&gt; and &lt;code&gt;[-1]&lt;/code&gt; for indexes, &lt;code&gt;[1:3:2]&lt;/code&gt; for a stepped slice, &lt;code&gt;*&lt;/code&gt; for every child, &lt;code&gt;..&lt;/code&gt; for a recursive descent, and &lt;code&gt;[0, 2]&lt;/code&gt; to union a handful of selectors.&lt;/p&gt;
&lt;p&gt;Filters are where RFC 9535 spends its pages, and a few of its rulings are worth keeping in your head:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Existence is not truthiness.&lt;/strong&gt; A bare &lt;code&gt;[?@.discount]&lt;/code&gt; keeps every child that &lt;em&gt;has&lt;/em&gt; a &lt;code&gt;discount&lt;/code&gt;, even one set to &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;. It asks whether the path exists, not whether the value is truthy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A missing path is &quot;nothing&quot;, not an error.&lt;/strong&gt; In a comparison, &lt;code&gt;[?@.a.b == 1]&lt;/code&gt; just fails to match when &lt;code&gt;a&lt;/code&gt; is absent instead of throwing, so filters stay safe to write against ragged data.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;strong&amp;gt;==&amp;lt;/strong&amp;gt;&lt;/code&gt; &lt;strong&gt;is deep equality.&lt;/strong&gt; &lt;code&gt;[?@.tags == [&quot;new&quot;, &quot;sale&quot;]]&lt;/code&gt; compares structure, and none of JavaScript's loose coercion tags along.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;strong&amp;gt;$&amp;lt;/strong&amp;gt;&lt;/code&gt; &lt;strong&gt;is still the root inside a filter.&lt;/strong&gt; A child can be measured against something elsewhere in the document: &lt;code&gt;[?@.price &amp;gt; $.store.bicycle.price]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Five functions ship built in, taken straight from the RFC: &lt;code&gt;length()&lt;/code&gt;, &lt;code&gt;count()&lt;/code&gt;, &lt;code&gt;value()&lt;/code&gt;, and the regex tests &lt;code&gt;match()&lt;/code&gt; for a whole string and &lt;code&gt;search()&lt;/code&gt; for a substring. For anything else you pass your own and call it with &lt;code&gt;@&lt;/code&gt; as the current node:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;find('$..book[?discounted(@)].title', data, { discounted: b =&amp;gt; b.price &amp;lt; 9 });

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That registry is the single place executable code enters, and it enters from your side, by name. Whoever writes the query chooses &lt;em&gt;which&lt;/em&gt; of your functions to call, never what it does.&lt;/p&gt;
&lt;h3 id=&quot;the-part-i-tried-to-borrow&quot;&gt;The part I tried to borrow&lt;/h3&gt;
&lt;p&gt;padvinder started out leaning on xprsn. A JSONPath filter is an expression over the current node, so my first version handed each &lt;code&gt;[?...]&lt;/code&gt; straight to &lt;a rel=&quot;nofollow&quot; href=&quot;https://robinvdvleuten.nl/post/let-users-write-rules-without-letting-them-write-javascript&quot;&gt;xprsn&lt;/a&gt; and let it do the evaluating. The easy queries passed. The spec did not.&lt;/p&gt;
&lt;p&gt;RFC 9535 filters only look like ordinary expressions. Their operands are queries as often as values, so &lt;code&gt;@.a.b&lt;/code&gt; is a small path that runs and may match nothing at all. A bare &lt;code&gt;@.discount&lt;/code&gt; is an existence test, not a truthiness check. Equality is structural. A missing singular query turns into a special &quot;nothing&quot; that compares equal to no value on earth. A general expression evaluator has no reason to think in any of those terms, and bending xprsn to fit would have meant loading it with JSONPath rules it has no business carrying.&lt;/p&gt;
&lt;p&gt;So I stopped borrowing. The filter grammar moved into padvinder as its own recursive-descent parser written against the RFC, and the xprsn dependency came out with it. That is the real reason padvinder has zero runtime dependencies: the one piece it could have reused is the one piece the standard needed it to own.&lt;/p&gt;
&lt;h3 id=&quot;why-it-can-t-be-turned-into-code&quot;&gt;Why it can't be turned into code&lt;/h3&gt;
&lt;p&gt;The safety is the same compile-to-closures technique I wrote up for xprsn, so here is only its shape. Every selector and every filter becomes a small function that already exists in the shipped source, and a parser wires them together. Query text never gets reassembled into JavaScript, which leaves nothing to inject into and nothing for a CSP to block.&lt;/p&gt;
&lt;p&gt;The test suite keeps that honest by running under &lt;code&gt;node --disallow-code-generation-from-strings&lt;/code&gt;, the flag that turns every eval-shaped call into a thrown error, exactly as a strict CSP does in the browser.&lt;/p&gt;
&lt;p&gt;The prototype escapes are closed as well. &lt;code&gt;__proto__&lt;/code&gt;, &lt;code&gt;constructor&lt;/code&gt;, and &lt;code&gt;prototype&lt;/code&gt; never match, in a path or a filter, so &lt;code&gt;[?@.constructor]&lt;/code&gt; finds nothing rather than climbing toward &lt;code&gt;Function&lt;/code&gt;. Matching reads own properties only, and a query never writes back to the data you gave it. A test snapshots the input and compares it afterward to prove that last one.&lt;/p&gt;
&lt;h3 id=&quot;is-it-the-right-tool-&quot;&gt;Is it the right tool?&lt;/h3&gt;
&lt;p&gt;If your paths are all written by you, committed to your repo, and never near a strict CSP, you do not need any of this, and a bigger library with a wider feature set is a reasonable pick. padvinder is built for the narrower spot: the query might come from a user or a config row, the page runs under a CSP you will not weaken, and you would rather the results match the standard than one project's reading of it. The 456-case suite is what I lean on there. It is not my definition of correct, it is the RFC's.&lt;/p&gt;
&lt;h3 id=&quot;getting-started&quot;&gt;Getting started&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;npm install padvinder

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/robinvdvleuten/padvinder&quot;&gt;README&lt;/a&gt; has the full selector table, the filter grammar, and the safety notes. Use &lt;code&gt;find&lt;/code&gt; when you want an answer now and &lt;code&gt;query&lt;/code&gt; when you will ask the same question a lot.&lt;/p&gt;
&lt;h3 id=&quot;closing-thoughts&quot;&gt;Closing thoughts&lt;/h3&gt;
&lt;p&gt;The satisfying part of this one was not the size or even the safety. It was having a compliance suite play judge. Most of my small libraries are correct by my own definition, which is a comfortable and slightly circular place to sit. Here, 456 cases I did not write got a vote, and &quot;I think this is right&quot; became &quot;the standard says this is right.&quot; That judge is also what ended the borrowing: you do not approximate your way through 456 cases, so the evaluator I had hoped to reuse had to go. I would take the trade on more projects if the specs existed for them.&lt;/p&gt;
&lt;p&gt;If you have been running JSONPath over input you did not write yourself, I would like to hear how you drew the line around it.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/25345/a-jsonpath-engine-that-follows-the-spec-and-cant-run-code</guid>
<pubDate>Tue, 25 Aug 2026 11:53:27 +0000</pubDate>
</item>
<item>
<title>Working with nested JSON: exploring it, mocking it, and querying it in Postgres</title>
<link>https://coderlegion.com/21844/working-with-nested-json-exploring-it-mocking-it-and-querying-it-in-postgres</link>
<description>&lt;p&gt;Flat JSON is easy. Nested JSON is where the day goes: an API response with orders inside customers inside accounts, a jsonb column three levels deep, a config file that grew a tree. Three tasks come up over and over, and each one has a trick that makes it painless. Here they are.&lt;/p&gt;
&lt;h3 id=&quot;1-reading-a-huge-nested-payload&quot;&gt;1. Reading a huge nested payload&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=5919876841020931874&quot; alt=&quot;Tree View&quot;&gt;&lt;/p&gt;
&lt;p&gt;Pretty-printing a 4,000-line response does not actually help. The indentation is correct, but finding one thing still means scrolling through thousands of lines. The fix is to stop treating JSON as text to scroll and start treating it as data to query.&lt;/p&gt;
&lt;p&gt;Say the question is: does any item in this order have a null price?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;account&quot;: {
    &quot;id&quot;: 91,
    &quot;customer&quot;: {
      &quot;orders&quot;: [
        { &quot;id&quot;: 4821, &quot;items&quot;: [ { &quot;sku&quot;: &quot;A-19&quot;, &quot;price&quot;: 12.5 } ] },
        { &quot;id&quot;: 4822, &quot;items&quot;: [ { &quot;sku&quot;: &quot;B-04&quot;, &quot;price&quot;: null } ] }
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three moves turn this from a scroll into a lookup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Filter by path, key, type, or value. Filtering to price pulls every price field out of the whole tree at once. Filtering by the value null jumps straight to the offending row. The needle in 4,000 lines becomes a single filtered result.&lt;/li&gt;
&lt;li&gt;Select the nesting level. Instead of expanding everything, expand the tree to level 2 to see the shape of the data, then drill only into the branch that matters. This is the difference between reading structure and drowning in leaves.&lt;/li&gt;
&lt;li&gt;Switch to a table view when a branch is really a list of records. Two hundred objects with the same keys is a spreadsheet pretending to be JSON, and reading it as rows and columns is far faster than reading it as nested braces.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once JSON is filterable and foldable, payload size stops mattering.&lt;/p&gt;
&lt;h3 id=&quot;2-generating-realistic-nested-json-fast&quot;&gt;2. Generating realistic nested JSON, fast&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4516247635221435725&quot; alt=&quot;Generate Mock JSON&quot;&gt;&lt;/p&gt;
&lt;p&gt;The opposite problem: there is no payload yet, and building a parser, a UI, or a test needs one. Hand-writing mock data is slow, and worse, it is too clean. Every record ends up with the same id, the same date, the same shape, which is exactly the uniformity that hides off-by-one bugs, dedupe bugs, and sort bugs.&lt;/p&gt;
&lt;p&gt;Two shortcuts cover most cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load a realistic nested sample. Start from a ready-made nested document (an order, a log line, an analytics event) and adapt it, instead of inventing structure from scratch.&lt;/li&gt;
&lt;li&gt;Multiply one object into many varied records. Write a single object by hand, pick a count, and get back an array where fields like id, email, and dates actually vary per record. That variation is the point: a list of 50 rows that are genuinely different is what surfaces the bug that 50 identical rows would hide.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Realistic nested test data in seconds beats a hand-typed array of clones every time.&lt;/p&gt;
&lt;h3 id=&quot;3-querying-and-updating-nested-json-in-postgres&quot;&gt;3. Querying and updating nested JSON in Postgres&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=14815475663515361781&quot; alt=&quot;Querying in PostgreSQL&quot;&gt;&lt;/p&gt;
&lt;p&gt;Eventually that nested JSON lands in a jsonb column, and a viewer cannot help anymore. This is where people get stuck, so here is the practical core.&lt;/p&gt;
&lt;p&gt;Assume a table orders with a jsonb column data holding the payload above.&lt;/p&gt;
&lt;p&gt;Selecting. The two operators to internalize are &lt;code&gt;-&amp;gt;&lt;/code&gt; and &lt;code&gt;-&amp;gt;&amp;gt;&lt;/code&gt;. &lt;code&gt;-&amp;gt;&lt;/code&gt; returns JSON, &lt;code&gt;-&amp;gt;&amp;gt;&lt;/code&gt; returns text:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- returns jsonb
SELECT data -&amp;gt; 'account' -&amp;gt; 'customer' FROM orders;

-- returns text (note the final -&amp;gt;&amp;gt;)
SELECT data -&amp;gt; 'account' -&amp;gt;&amp;gt; 'id' AS account_id FROM orders;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a deep path, &lt;code&gt;#&amp;gt;&lt;/code&gt; and &lt;code&gt;#&amp;gt;&amp;gt;&lt;/code&gt; take an array of keys and are much cleaner than chaining arrows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- text value deep in the structure
SELECT data #&amp;gt;&amp;gt; '{account,customer,orders,0,id}' AS first_order_id
FROM orders;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To filter rows by a nested value, containment (&lt;code&gt;@&amp;gt;&lt;/code&gt;) is both readable and indexable with a GIN index:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM orders
WHERE data @&amp;gt; '{&quot;account&quot;: {&quot;id&quot;: 91}}';
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And to work across an array, expand it into rows with &lt;code&gt;jsonb_array_elements&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT elem -&amp;gt;&amp;gt; 'id' AS order_id
FROM orders,
     jsonb_array_elements(data #&amp;gt; '{account,customer,orders}') AS elem;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Updating. The workhorse is &lt;code&gt;jsonb_set(target, path, new_value)&lt;/code&gt;. The gotcha that trips everyone: &lt;code&gt;new_value&lt;/code&gt; must itself be &lt;code&gt;jsonb&lt;/code&gt;, so cast it.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- set a deep scalar (note the ::jsonb cast)
UPDATE orders
SET data = jsonb_set(data, '{account,customer,orders,0,id}', '9001'::jsonb)
WHERE id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add or replace a key at a level with the || merge operator, and remove a path with &lt;code&gt;#-&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- shallow-merge a new key into the top level
UPDATE orders SET data = data || '{&quot;archived&quot;: true}'::jsonb WHERE id = 1;

-- delete a nested key
UPDATE orders SET data = data #- '{account,customer,orders,0,items}' WHERE id = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One honest warning: &lt;code&gt;||&lt;/code&gt; merges only one level deep, so it will not deep-merge nested objects. For nested changes, reach for &lt;code&gt;jsonb_set&lt;/code&gt;. And the genuinely hard case, updating a specific array element chosen by a condition rather than a fixed index, needs more than &lt;code&gt;jsonb_set&lt;/code&gt; alone. That is a whole topic on its own, and it is the one worth reading a dedicated write-up on before you fight it in production.&lt;/p&gt;
&lt;p&gt;Here is the honest reason all of this matters: nobody keeps these operators in their head. It is &lt;code&gt;-&amp;gt;&lt;/code&gt; versus &lt;code&gt;-&amp;gt;&amp;gt;&lt;/code&gt;, the &lt;code&gt;#&amp;gt;&amp;gt;&lt;/code&gt; path syntax, the &lt;code&gt;::jsonb&lt;/code&gt; cast that &lt;code&gt;jsonb_set&lt;/code&gt; quietly requires, the fact that &lt;code&gt;||&lt;/code&gt; only merges one level. I forget them between projects every single time. So I wrote them down as a permanent, on-page reference next to the formatter: &lt;a rel=&quot;nofollow&quot; href=&quot;https://catssaymeow.org/json-formatter/#querying-json-in-postgresql&quot;&gt;Querying nested JSON in PostgreSQL (SELECT and UPDATE)&lt;/a&gt; collects the common reads and writes in one place, for the moment memory does not serve. It is reference for the everyday cases, not a full Postgres manual.&lt;/p&gt;
&lt;h3 id=&quot;where-the-tool-fits&quot;&gt;Where the tool fits&lt;/h3&gt;
&lt;p&gt;I built all three of these into one place, at &lt;a rel=&quot;nofollow&quot; href=&quot;https://catssaymeow.org/json-formatter/&quot;&gt;catssaymeow.org/json-formatter&lt;/a&gt;, because I got tired of one tab that only pretty-prints and another that only explores.&lt;/p&gt;
&lt;p&gt;It formats, validates, and minifies (invalid JSON is pinpointed by line and column, not a bare &quot;invalid&quot;), and then lets you actually work with the structure: explore it as a tree, graph, or table, filter by path, key, type, or value, and expand to a chosen nesting level. When there is no data to work with yet, it can load a realistic nested sample or multiply one object into an array of varied mock records. It runs as client-side JavaScript, so the JSON stays in the browser, and clean JSON can be sent straight to a built-in API Client as a request body.&lt;/p&gt;
&lt;p&gt;And for the part that happens after the database call, the same page carries a &lt;a rel=&quot;nofollow&quot; href=&quot;https://catssaymeow.org/json-formatter/#querying-json-in-postgresql&quot;&gt;Postgres jsonb querying reference&lt;/a&gt; for the SELECT and UPDATE syntax that never sticks. Three recurring nested-JSON tasks, one page to come back to.&lt;/p&gt;
&lt;p&gt;If you put it up against your own worst nested payload, I would like to hear what it struggles with.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21844/working-with-nested-json-exploring-it-mocking-it-and-querying-it-in-postgres</guid>
<pubDate>Fri, 03 Jul 2026 13:52:48 +0000</pubDate>
</item>
<item>
<title>How to View and Analyze Large JSON Files Without Getting Lost</title>
<link>https://coderlegion.com/20085/how-to-view-and-analyze-large-json-files-without-getting-lost</link>
<description>&lt;p&gt;You open a JSON file. Your text editor freezes for three seconds. When it finally loads, you're staring at 80,000 lines of tightly packed, unindented data — no line breaks, no color, no structure. You need to find one specific value buried somewhere in a deeply nested object. You scroll. You squint. You ctrl+F for a key name and get 47 matches.&lt;/p&gt;
&lt;p&gt;Sound familiar?&lt;/p&gt;
&lt;p&gt;Working with large JSON files is one of those quietly painful parts of being a developer, data analyst, or QA engineer. JSON is everywhere — API responses, config files, exported datasets, logs, database snapshots — and while the format itself is elegantly simple, it scales poorly to human readability. A 200-line JSON file is manageable. A 20,000-line file is a different beast entirely.&lt;/p&gt;
&lt;p&gt;This guide walks you through the practical strategies, tools, and techniques that make it possible to inspect, navigate, and analyze JSON data efficiently — without losing your mind in the process.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-large-json-files-are-so-hard-to-read&quot;&gt;Why Large JSON Files Are So Hard to Read&lt;/h3&gt;
&lt;p&gt;JSON's design is optimized for machines, not humans. It's a lightweight data interchange format, which means it prioritizes parsability over readability. When you're dealing with small payloads, this doesn't matter much. But as files grow, a few structural realities make things difficult:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deeply nested objects.&lt;/strong&gt; Real-world JSON structures often have five, six, or even ten levels of nesting. An e-commerce API response, for example, might have an order object that contains a customer object, which contains an address object, which contains a coordinates object — and you need to reach &lt;code&gt;order.customer.address.coordinates.lat&lt;/code&gt;. In raw text, tracing that path is genuinely difficult.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minification.&lt;/strong&gt; Many APIs and systems return minified JSON — everything on a single line, all whitespace stripped. This is efficient for transmission but completely unreadable without formatting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lack of visual hierarchy.&lt;/strong&gt; Without indentation and color coding, objects and arrays blur together. You lose track of where one object ends and another begins.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scale.&lt;/strong&gt; A paginated API response with 500 records, each containing 30 fields, produces 15,000 key-value pairs. A database export can easily run into millions of lines. Searching linearly through that volume is impractical.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;common-challenges-when-working-with-large-json-datasets&quot;&gt;Common Challenges When Working with Large JSON Datasets&lt;/h3&gt;
&lt;p&gt;Before diving into solutions, it helps to name the specific problems developers encounter most often:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finding a specific key or value&lt;/strong&gt; is the most common task, and it's deceptively hard when a key name like &lt;code&gt;id&lt;/code&gt; or &lt;code&gt;status&lt;/code&gt; appears hundreds of times across different nested levels.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understanding the overall structure&lt;/strong&gt; is another major challenge. Before you can work with a JSON file, you need to understand its shape — what top-level keys exist, what type each value is, how deep the nesting goes. In a large file, this isn't obvious at a glance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comparing records&lt;/strong&gt; across a large array is tedious without a proper view. If you're reviewing 200 user objects and need to spot inconsistencies in their data structure, raw text makes this nearly impossible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validating data integrity&lt;/strong&gt; — checking that required keys exist, values are the right type, arrays aren't unexpectedly empty — is a real task for QA engineers and data analysts that becomes error-prone without the right tooling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Performance issues&lt;/strong&gt; are practical too. Many text editors struggle to syntax-highlight or even open files larger than a few megabytes. Some will outright crash.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;getting-oriented-understanding-json-structure&quot;&gt;Getting Oriented: Understanding JSON Structure&lt;/h3&gt;
&lt;p&gt;Before you can analyze large JSON files, you need a solid mental model of JSON structure. Everything in JSON falls into one of these types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Objects&lt;/strong&gt;: Curly braces &lt;code&gt;{}&lt;/code&gt;, containing key-value pairs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Arrays&lt;/strong&gt;: Square brackets &lt;code&gt;[]&lt;/code&gt;, containing ordered lists of values&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strings&lt;/strong&gt;: Quoted text like &lt;code&gt;&quot;hello&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Numbers&lt;/strong&gt;: Numeric values like &lt;code&gt;42&lt;/code&gt; or &lt;code&gt;3.14&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Booleans&lt;/strong&gt;: &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Null&lt;/strong&gt;: The absence of a value&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's a small example to illustrate a real-world nested structure:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;order&quot;: {
    &quot;id&quot;: &quot;ORD-9921&quot;,
    &quot;status&quot;: &quot;shipped&quot;,
    &quot;customer&quot;: {
      &quot;name&quot;: &quot;Priya Sharma&quot;,
      &quot;email&quot;: &quot;*Emails are not allowed*&quot;
    },
    &quot;items&quot;: [
      {
        &quot;product_id&quot;: &quot;P-441&quot;,
        &quot;name&quot;: &quot;Wireless Keyboard&quot;,
        &quot;quantity&quot;: 1,
        &quot;price&quot;: 49.99
      },
      {
        &quot;product_id&quot;: &quot;P-882&quot;,
        &quot;name&quot;: &quot;USB Hub&quot;,
        &quot;quantity&quot;: 2,
        &quot;price&quot;: 19.99
      }
    ],
    &quot;total&quot;: 89.97
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is manageable at 25 lines. Now imagine 500 orders in an array, each with a deeper customer profile, multiple shipping addresses, discount codes, tax breakdowns, and fulfillment metadata. That's when JSON file analysis becomes a serious challenge.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-power-of-json-tree-view&quot;&gt;The Power of JSON Tree View&lt;/h3&gt;
&lt;p&gt;The single biggest improvement you can make when working with large JSON files is switching from a flat text view to a &lt;strong&gt;JSON tree view&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A tree view presents the JSON structure hierarchically, like a file explorer. Top-level keys are shown as expandable nodes. You click a node to expand it and see its children. Arrays show item counts. Objects show their keys. You can collapse an entire branch when you're not interested in it, and expand only the paths you care about.&lt;/p&gt;
&lt;p&gt;This changes the experience fundamentally. Instead of reading 10,000 lines of text sequentially, you navigate a structure. You instantly see that the top-level object has four keys. You expand &lt;code&gt;data&lt;/code&gt;, see it's an array of 200 items. You expand the first item to understand the record schema. You check that the schema looks consistent across a few more items. You've oriented yourself in thirty seconds instead of five minutes.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://99tools.net/json-viewer/&quot;&gt;JSON Viewer&lt;/a&gt; is a tool that does exactly this. Paste your JSON or upload a file, and it renders the structure as an interactive tree. Nodes expand and collapse on click. You can see at a glance whether a value is a string, number, array, or nested object. For anyone regularly dealing with complex API responses or large configuration files, this kind of visualization is not a luxury — it's a practical necessity.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;techniques-for-navigating-nested-json-structures&quot;&gt;Techniques for Navigating Nested JSON Structures&lt;/h3&gt;
&lt;p&gt;Once you have a tree view available, there are specific techniques that make navigation faster and more reliable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Start from the top level.&lt;/strong&gt; Before drilling into any specific part of the data, expand only the top-level keys to understand the overall shape of the file. Is the root an object or an array? How many top-level keys are there? What are their names? This gives you a map before you start exploring.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use expand/collapse aggressively.&lt;/strong&gt; When inspecting large JSON data, treat collapsed nodes as closed drawers. Only open the ones you need. This prevents cognitive overload and keeps your focus on the relevant portion of the data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow the path, don't scroll.&lt;/strong&gt; When you need to reach a specific nested value, traverse the tree path deliberately: expand the parent key, then the child, then the next level. This is far faster than scrolling through raw text looking for the matching closing brace.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pay attention to types.&lt;/strong&gt; A tree viewer makes it easy to spot when a value that should be a string is actually a number, or when a field that should always be an array is sometimes null. These type inconsistencies are common bugs in API integrations and are very easy to miss in raw text.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-to-search-within-large-json-files&quot;&gt;How to Search Within Large JSON Files&lt;/h3&gt;
&lt;p&gt;Searching is where many developers waste the most time. Using a plain text search (ctrl+F) in a JSON file is blunt: it finds all occurrences of a string, regardless of where they appear in the structure. If you're searching for &lt;code&gt;&quot;status&quot;&lt;/code&gt; in an API response that has nested objects for orders, line items, shipping, and payment — you'll get matches on every level.&lt;/p&gt;
&lt;p&gt;Smarter approaches:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use JSON path notation mentally.&lt;/strong&gt; Before searching, identify the path you're interested in. For example, you're not looking for &lt;code&gt;status&lt;/code&gt; anywhere — you're looking for &lt;code&gt;order.payment.status&lt;/code&gt;. This narrows your target significantly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;jq&lt;/code&gt; for command-line filtering.&lt;/strong&gt; &lt;code&gt;jq&lt;/code&gt; is a lightweight command-line tool for querying JSON. It's powerful and precise:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Extract all order IDs from a large orders array
cat orders.json | jq '.orders[].id'

# Find all items where status is &quot;failed&quot;
cat response.json | jq '.[] | select(.status == &quot;failed&quot;)'

# Get a specific nested value
cat data.json | jq '.results[0].customer.email'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;jq&lt;/code&gt; is especially valuable when dealing with large JSON files in automated pipelines or when you need to extract specific data without loading the entire file into an editor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use Python for structured inspection.&lt;/strong&gt; For one-off analysis tasks, Python's &lt;code&gt;json&lt;/code&gt; module lets you load and query JSON data with full programming logic:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import json

with open('large_data.json') as f:
    data = json.load(f)

# Check the top-level structure
print(type(data))
print(data.keys() if isinstance(data, dict) else f&quot;Array with {len(data)} items&quot;)

# Find all unique status values
statuses = set(item['status'] for item in data['orders'])
print(statuses)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This approach is ideal when you need to understand patterns across a large dataset, not just find a single value.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;analyzing-api-responses-that-span-thousands-of-lines&quot;&gt;Analyzing API Responses That Span Thousands of Lines&lt;/h3&gt;
&lt;p&gt;API responses are one of the most common sources of large JSON files. When you're debugging an integration, reviewing a webhook payload, or testing a third-party API, the response might contain thousands of lines with nested pagination metadata, embedded related objects, and arrays of arrays.&lt;/p&gt;
&lt;p&gt;A few practical strategies:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inspect the envelope first.&lt;/strong&gt; Most APIs wrap their data in a standard envelope: &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;results&lt;/code&gt;, &lt;code&gt;items&lt;/code&gt;, or &lt;code&gt;records&lt;/code&gt; as the main payload, alongside &lt;code&gt;meta&lt;/code&gt;, &lt;code&gt;pagination&lt;/code&gt;, &lt;code&gt;errors&lt;/code&gt;, or &lt;code&gt;status&lt;/code&gt; at the top level. Understanding the envelope structure tells you where the actual data lives and where the metadata lives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sample your records.&lt;/strong&gt; When the response contains a large array of records, you don't need to look at all of them to understand the schema. Inspect three to five items in detail — the first, one from the middle, and the last. Look for any structural differences. If the schema is inconsistent across records, that's a bug worth flagging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Check for nulls and empty arrays.&lt;/strong&gt; Large API responses often contain optional fields that are populated inconsistently. A field that's an object in one record might be &lt;code&gt;null&lt;/code&gt; in another. A tree view makes these stand out visually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compare actual vs. expected structure.&lt;/strong&gt; If you have API documentation, use it alongside a tree view of the actual response. Discrepancies — missing fields, wrong types, unexpected nesting — are much easier to spot when you can see the full structure laid out visually.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;reviewing-config-files-and-exported-datasets&quot;&gt;Reviewing Config Files and Exported Datasets&lt;/h3&gt;
&lt;p&gt;Configuration files in JSON format — think &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;.prettierrc&lt;/code&gt;, AWS CloudFormation templates, or Kubernetes config files — have their own inspection challenges. They're typically not large by record count, but they're structurally complex, with nested objects for different environments, feature flags, permissions, and resource definitions.&lt;/p&gt;
&lt;p&gt;When reviewing these:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Understand the schema before editing.&lt;/strong&gt; Modifying a deeply nested config without understanding its parent structure is a common source of bugs. Use a tree view to confirm the full path to the value you're changing before touching anything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validate before deploying.&lt;/strong&gt; Many config formats have strict schema requirements. A JSON viewer that highlights syntax errors saves significant debugging time.&lt;/p&gt;
&lt;p&gt;Exported datasets from databases or analytics tools present a different challenge: they're often large flat arrays with many fields per record. For these, tools like &lt;code&gt;jq&lt;/code&gt; or Python's pandas library are more appropriate for analysis than a tree viewer, since you're doing aggregate analysis rather than structural inspection.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;common-mistakes-to-avoid&quot;&gt;Common Mistakes to Avoid&lt;/h3&gt;
&lt;p&gt;Even experienced developers make these mistakes when dealing with large JSON files:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Opening raw JSON in a basic text editor.&lt;/strong&gt; Notepad, nano, or even VS Code without a JSON extension will show you a wall of text. Always use a viewer or formatter as your first step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Searching too broadly.&lt;/strong&gt; Searching for a key name without considering where in the structure it appears leads to confusing results. Be specific about the path you're looking for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ignoring schema inconsistencies.&lt;/strong&gt; When a field is missing from some records or has an unexpected type, it's easy to dismiss it as a fluke. It rarely is. Schema inconsistencies are almost always bugs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Editing large JSON files manually without validation.&lt;/strong&gt; Adding a comma in the wrong place, forgetting a closing bracket, or mismatching braces will silently break your file. Always validate after editing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Assuming minified JSON is corrupted.&lt;/strong&gt; Minified JSON looks like garbage but is valid. Run it through a formatter before assuming something is wrong.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;practical-tips-that-save-real-time&quot;&gt;Practical Tips That Save Real Time&lt;/h3&gt;
&lt;p&gt;To close out, here are the habits that make a measurable difference when you work with JSON data regularly:&lt;/p&gt;
&lt;p&gt;Always &lt;strong&gt;format before you read&lt;/strong&gt;. Paste minified JSON into a formatter or viewer as your first step, every time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Use a tree view for structure, jq for data extraction&lt;/strong&gt;. These two tools complement each other: the tree view tells you the shape, jq lets you query the content.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep a scratch file&lt;/strong&gt;. When analyzing a large file, paste the specific subtree you're working with into a scratch file. You don't need to keep the whole 10,000-line file open to work on one nested object.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note the array lengths&lt;/strong&gt;. When a field is an array, check its length. An empty array where you expect data is a very common source of bugs that's easy to overlook in raw text but obvious in a tree view.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validate early and often&lt;/strong&gt;. If you're writing or modifying JSON, validate it before it goes anywhere. A quick paste into a JSON viewer catches most structural errors immediately.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Working with large JSON files doesn't have to be a frustrating experience. The core problem — that JSON scales poorly to human readability — is solvable with the right tools and techniques. A tree view transforms an opaque wall of text into a navigable structure. Command-line tools like &lt;code&gt;jq&lt;/code&gt; let you query precisely instead of searching blindly. Python gives you full analytical power when you need to understand patterns across thousands of records.&lt;/p&gt;
&lt;p&gt;The key takeaways: always format before you read, use tree views to understand structure, search with path awareness instead of plain text search, and validate often. Whether you're debugging an API integration, reviewing a configuration file, or analyzing an exported dataset, these habits will consistently save you time and prevent the kind of errors that only show up in production.&lt;/p&gt;
&lt;p&gt;JSON is a tool, and like any tool, it rewards the people who learn to use it properly.&lt;/p&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/20085/how-to-view-and-analyze-large-json-files-without-getting-lost</guid>
<pubDate>Tue, 09 Jun 2026 19:00:32 +0000</pubDate>
</item>
<item>
<title>Why Your React Frontend Crashes When an LLM Streams Malformed JSON</title>
<link>https://coderlegion.com/20041/why-your-react-frontend-crashes-when-an-llm-streams-malformed-json</link>
<description>&lt;p&gt;&lt;strong&gt;A production walkthrough with a live Next.js demo - JSON.parse() vs partial-json + Zod for real-time AI dashboards.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We don't prompt AI, we architect it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Article content&lt;br&gt;
If you ship real-time AI dashboards in React, you have probably seen this pattern:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stream starts.&lt;/li&gt;
&lt;li&gt;Metrics update for a few chunks.&lt;/li&gt;
&lt;li&gt;Console throws SyntaxError.&lt;/li&gt;
&lt;li&gt;UI goes blank.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The bug is usually not React. It is not Next.js.&lt;/p&gt;
&lt;p&gt;It is calling JSON.parse() on a live stream buffer an unterminated string that is incomplete by design.&lt;/p&gt;
&lt;p&gt;I built an open-source demo to make this failure obvious - and to show a resilient parsing pipeline you can copy into production.&lt;/p&gt;
&lt;p&gt;Most tutorials teach you to crash. Production demands resilience.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tutorial path:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;→ JSON.parse(buffer) on every chunk&lt;/p&gt;
&lt;p&gt;→ UI crashes on a single missing bracket&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Production path:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;→ partial-json + Zod .partial()&lt;/p&gt;
&lt;p&gt;→ UI updates live, ignoring malformed chunks&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Error boundaries: seatbelt, not engine&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;StreamErrorBoundary catches render errors in children. It does not replace safe streaming parse logic or catch async errors inside useEffect.&lt;/p&gt;
&lt;p&gt;Use error boundaries as a safety net after you fix parsing strategy.&lt;/p&gt;
&lt;p&gt;Run it locally in 5 minutes&lt;/p&gt;
&lt;p&gt;git clone &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/gauravthorath/react-llm-stream-json-demo.git&quot;&gt;https://github.com/gauravthorath/react-llm-stream-json-demo.git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;cd react-llm-stream-json-demo&lt;/p&gt;
&lt;p&gt;pnpm install&lt;/p&gt;
&lt;p&gt;pnpm run dev&lt;br&gt;
Open &lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:3000&quot;&gt;http://localhost:3000&lt;/a&gt; → click Run Stream → open DevTools on the left panel.&lt;/p&gt;
&lt;p&gt;Architecture notes: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/gauravthorath/react-llm-stream-json-demo/blob/main/ARCHITECTURE.md&quot;&gt;https://github.com/gauravthorath/react-llm-stream-json-demo/blob/main/ARCHITECTURE.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Production takeaway&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Parse partial: do not JSON.parse the live buffer&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate partial: Zod .partial().safeParse&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Render partial: skeletons for missing fields&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Retain last good snapshot: do not blank UI on trailing garbage&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Parse partial. Validate partial. Render partial.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is next&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Follow-up: tool-calling streams and schema drift - when the model changes field shapes mid-session and your UI needs a migration strategy, not just a parser.&lt;/p&gt;
&lt;p&gt;Comment Part 2 on the video if you want that teardown next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Connect&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;YouTube: &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/n51RAGJZGdQ&quot;&gt;https://youtu.be/n51RAGJZGdQ&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/gauravthorath/react-llm-stream-json-demo&quot;&gt;https://github.com/gauravthorath/react-llm-stream-json-demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Portfolio: &lt;a rel=&quot;nofollow&quot; href=&quot;https://gauravthorat-portfolio.vercel.app/blog/react-llm-stream-json-parser&quot;&gt;https://gauravthorat-portfolio.vercel.app/blog/react-llm-stream-json-parser&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;react-nextjs-typescript-ai-frontend-webdevelopment-javascript-softwareengineering-llm-sse&quot;&gt;react #nextjs #typescript #ai #frontend #webdevelopment #javascript #softwareengineering #llm #sse&lt;/h2&gt;
</description>
<category>Videos</category>
<guid isPermaLink="true">https://coderlegion.com/20041/why-your-react-frontend-crashes-when-an-llm-streams-malformed-json</guid>
<pubDate>Tue, 09 Jun 2026 09:54:30 +0000</pubDate>
</item>
<item>
<title>fastjson 0.3.0: A Faster Drop-In ext/json for PHP, Backed by yyjson</title>
<link>https://coderlegion.com/18453/fastjson-0-3-0-a-faster-drop-in-ext-json-for-php-backed-by-yyjson</link>
<description>&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// Before
$payload = json_encode($response);
$data    = json_decode($input, true);
$ok      = json_validate($input);

// After
$payload = fastjson_encode($response);
$data    = fastjson_decode($input, true);
$ok      = fastjson_validate($input);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's the migration. Search-and-replace &lt;code&gt;json_*&lt;/code&gt; for &lt;code&gt;fastjson_*&lt;/code&gt;. JSON flags, error constants, and last-error semantics carry across byte-for-byte. The two extensions sit next to each other in the same process; adoption is per call site, not per repo.&lt;/p&gt;
&lt;p&gt;On the simdjson_php canonical 14.8 MB corpus, that swap buys 6.06× encode throughput, 2.66× decode, and 5.10× validate against &lt;code&gt;ext/json&lt;/code&gt; on the same PHP 8.6.0-dev build. The repo is at &lt;a href=&quot;https://github.com/iliaal/fastjson&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot;&gt;github.com/iliaal/fastjson&lt;/a&gt;. 0.3.0 shipped yesterday.&lt;/p&gt;
&lt;h3 id=&quot;why-drop-in-faster-json-for-php&quot;&gt;Why drop in faster JSON for PHP&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ext/json&lt;/code&gt; is fine. It's correct, well-maintained, and tracks the spec. On low-traffic endpoints it isn't on anyone's profiler. The cost shows up at scale: any application that calls &lt;code&gt;json_encode&lt;/code&gt; and &lt;code&gt;json_decode&lt;/code&gt; on every request path eventually finds JSON serialization sitting at the top of a flame graph. API gateways feel it first, then log processors and microservice fan-out paths.&lt;/p&gt;
&lt;p&gt;Before fastjson the practical options were two:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stay on &lt;code&gt;ext/json&lt;/code&gt;. Eat the CPU cost.&lt;/li&gt;
&lt;li&gt;Reach for &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/crazyxman/simdjson_php&quot;&gt;simdjson_php&lt;/a&gt;. It's fast but decode-only and not API-compatible; every call site has to be rewritten around its result shape.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;fastjson is option three. It's a native PHP extension that wraps &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ibireme/yyjson&quot;&gt;yyjson&lt;/a&gt; 0.12.0 (MIT, ~6K LOC of focused C) behind a namespaced API that mirrors &lt;code&gt;ext/json&lt;/code&gt;'s contract. PHP 8.3 minimum; 8.4 and 8.5 supported; coexists with &lt;code&gt;ext/json&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;what-drop-in-actually-means-here&quot;&gt;What &quot;drop-in&quot; actually means here&lt;/h3&gt;
&lt;p&gt;The risk with any &quot;drop-in&quot; claim is that it covers 90% of cases and silently changes behavior on the 10% that matter. So this section is what fastjson does and what it doesn't:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Function signatures track &lt;code&gt;ext/json&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;fastjson_encode($value, int $flags = 0, int $depth = 512)&lt;/code&gt;. Same positional shape. Same defaults. Same return values on success, &lt;code&gt;false&lt;/code&gt; on failure.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;`JSON_&lt;/em&gt;&lt;code&gt; flags match byte-for-byte.** &lt;/code&gt;JSON_UNESCAPED_SLASHES&lt;code&gt;, &lt;/code&gt;JSON_UNESCAPED_UNICODE&lt;code&gt;, &lt;/code&gt;JSON_PRETTY_PRINT&lt;code&gt;, the &lt;/code&gt;JSON&lt;em&gt;HEX&lt;/em&gt;*&lt;code&gt; family, &lt;/code&gt;JSON_THROW_ON_ERROR&lt;code&gt;, &lt;/code&gt;JSON_INVALID_UTF8_IGNORE&lt;code&gt;, &lt;/code&gt;JSON_INVALID_UTF8_SUBSTITUTE`. The integer constants are intentionally identical so user code can pass the same flag value into either function.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;`JSON&lt;em&gt;ERROR&lt;/em&gt;&lt;/em&gt;&lt;code&gt; codes match byte-for-byte, messages don't.** &lt;/code&gt;fastjson_last_error()&lt;code&gt; returns the same &lt;/code&gt;JSON&lt;em&gt;ERROR&lt;/em&gt;*&lt;code&gt; int as &lt;/code&gt;json_last_error()&lt;code&gt; for the same failure class, so code branching on error codes works without modification. &lt;/code&gt;fastjson_last_error_msg()&lt;code&gt; returns yyjson's parser message (e.g., &lt;/code&gt;&quot;unexpected character&quot;`), not ext/json's. Application code that pattern-matches on the message string needs updating; code that branches on the code does not.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coexistence, not replacement.&lt;/strong&gt; Both extensions load. Migrate the call sites where JSON is on the hot path; leave the rest on &lt;code&gt;ext/json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;53 phpt tests rewritten from `php-src/ext/json/tests/&lt;/em&gt;.phpt&lt;code&gt;** run alongside fastjson's own suite. The rest of the upstream suite is categorized in &lt;/code&gt;tests/upstream-json/.skiplist&lt;code&gt; with the reason each test was deferred (most are tests of &lt;/code&gt;ext/json` internals that don't translate, a few hit known divergences).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documented divergences.&lt;/strong&gt; Large/scientific doubles emit &lt;code&gt;100000000000000000.0&lt;/code&gt; where &lt;code&gt;ext/json&lt;/code&gt; emits &lt;code&gt;1.0e+17&lt;/code&gt; in some ranges. U+2028 / U+2029 line separators emit as ordinary code points; &lt;code&gt;ext/json&lt;/code&gt; always escapes them for JSONP safety. Both divergences are in the skiplist with rationale.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-numbers&quot;&gt;The numbers&lt;/h3&gt;
&lt;p&gt;Full simdjson_php canonical corpus: 14.8 MB across 15 files, the same set the simdjson PHP binding has been benchmarked against for years. Hardware: i9-13950HX. PHP 8.6.0-dev, release build (&lt;code&gt;-O2&lt;/code&gt;). fastjson built &lt;code&gt;-O2&lt;/code&gt; against the same PHP. yyjson 0.12.0 with three local patches. Numbers in throughput, MB/sec:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Operation              &lt;/th&gt;&lt;th&gt;fastjson    &lt;/th&gt;&lt;th&gt;ext/json &lt;/th&gt;&lt;th&gt;Speedup&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Decode (stdClass)      &lt;/td&gt;&lt;td&gt;602 MB/s    &lt;/td&gt;&lt;td&gt;227 MB/s &lt;/td&gt;&lt;td&gt;2.66×&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Decode (assoc array)   &lt;/td&gt;&lt;td&gt;628 MB/s    &lt;/td&gt;&lt;td&gt;237 MB/s &lt;/td&gt;&lt;td&gt;2.65×&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Encode                 &lt;/td&gt;&lt;td&gt;1,092 MB/s  &lt;/td&gt;&lt;td&gt;180 MB/s &lt;/td&gt;&lt;td&gt;6.06×&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Validate               &lt;/td&gt;&lt;td&gt;1,352 MB/s  &lt;/td&gt;&lt;td&gt;265 MB/s &lt;/td&gt;&lt;td&gt;5.10×&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Visual side-by-side, including &lt;code&gt;ext/json&lt;/code&gt; with Nora Dossche's open SIMD encode work (&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/php/php-src/pull/17734&quot;&gt;php-src#17734&lt;/a&gt;) and simdjson_php on the same PHP 8.6.0-dev build, lives at &lt;a rel=&quot;nofollow&quot; href=&quot;https://iliaal.github.io/fastjson/baseline.html&quot;&gt;https://iliaal.github.io/fastjson/baseline.html&lt;/a&gt;. Reproduce locally with &lt;code&gt;bench/run.php&lt;/code&gt; against any PHP install.&lt;/p&gt;
&lt;p&gt;The encode speedup is the largest gap because the PHP-native encoder has the most room to give back. ndossche's php-src#17734 patch closes a meaningful chunk of that gap inside &lt;code&gt;ext/json&lt;/code&gt; itself using SIMD on string encoding. fastjson and that PR attack the same problem from different angles, and an application can benefit from both once #17734 lands upstream (fastjson re-baselines automatically; the visual page already shows both).&lt;/p&gt;
&lt;h3 id=&quot;how-the-encoder-gets-to-6-&quot;&gt;How the encoder gets to 6×&lt;/h3&gt;
&lt;p&gt;The encoder is one-stage. A zval walks straight into a &lt;code&gt;smart_str&lt;/code&gt; buffer via yyjson's writer primitives. There's no intermediate DOM, no two-pass build-then-serialize, no temporary string allocations for the common-case scalars. Each PHP value type maps to one or two yyjson calls; arrays and objects walk recursively into the same path.&lt;/p&gt;
&lt;p&gt;A few less-obvious pieces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Custom allocator wired through Zend.&lt;/strong&gt; yyjson's allocator hooks route every alloc/realloc/free through PHP's &lt;code&gt;emalloc&lt;/code&gt; family. JSON workloads count against &lt;code&gt;memory_limit&lt;/code&gt; and against per-request memory accounting; oversized inputs bail out the same way any other PHP allocation does.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Direct &lt;code&gt;smart_str&lt;/code&gt; integration.&lt;/strong&gt; No &lt;code&gt;RETURN_STRING(estrdup(buf))&lt;/code&gt; after a separate allocation. The yyjson writer writes into the &lt;code&gt;smart_str.s&lt;/code&gt; backing store, which becomes the return zend_string directly. One allocation per encode call in the common case.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;`HEX_&lt;/em&gt;&lt;code&gt; flag scan-first.** The flags &lt;/code&gt;JSON_HEX_TAG&lt;code&gt;/&lt;/code&gt;HEX_AMP&lt;code&gt;/&lt;/code&gt;HEX_APOS&lt;code&gt;/&lt;/code&gt;HEX&lt;em&gt;QUOT&lt;code&gt; rewrite specific characters into hex escapes. fastjson scans the string once for any candidate character; if none are present, the rewrite path is skipped entirely and the string is encoded directly. Defensive callers that pass &lt;/code&gt;HEX&lt;/em&gt;*` flags as a precaution on payloads that don't actually contain the substituted characters don't pay the rewrite cost.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integer-valued-double shortcut.&lt;/strong&gt; When a &lt;code&gt;double&lt;/code&gt; round-trips losslessly through &lt;code&gt;int64&lt;/code&gt;, fastjson emits it as an integer without going through &lt;code&gt;php_gcvt&lt;/code&gt; or yyjson's REAL writer. A cheap range check fires before &lt;code&gt;floor()&lt;/code&gt;, so number-heavy arrays of non-integer doubles don't pay libm per element.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The decode path's gain has different sources: yyjson itself, which parses with less branching and tighter memory locality than &lt;code&gt;ext/json&lt;/code&gt;'s parser, and a local yyjson patch (&lt;code&gt;YYJSON_READ_VALIDATE_ONLY&lt;/code&gt;) that turns the read path into a fast validate-only mode without materializing values.&lt;/p&gt;
&lt;h3 id=&quot;the-memory-tradeoff&quot;&gt;The memory tradeoff&lt;/h3&gt;
&lt;p&gt;Worth surfacing before anyone hits it in production. Decode and validate hold the yyjson document object in memory alongside the PHP-side result, because yyjson's value graph is built first, then traversed to produce zvals. Peak heap on decode is roughly 1.7× what &lt;code&gt;ext/json&lt;/code&gt; peaks at on the same input. Encode is one-stage and peaks at ~1.06× of &lt;code&gt;ext/json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Validate is the loudest: peak heap is ~101× &lt;code&gt;ext/json&lt;/code&gt;'s streaming validator (which sits at a constant ~80 bytes since it doesn't materialize anything). The headline number sounds extreme, but the absolute footprint is bounded by yyjson's read path, and it's already 2.7× lower than yyjson's stock read path thanks to a vendored validate-only patch (&lt;code&gt;YYJSON_READ_VALIDATE_ONLY&lt;/code&gt;) that skips the value-graph build.&lt;/p&gt;
&lt;p&gt;For most callers, the speedup wins. If the application is validate-heavy on giant inputs under tight &lt;code&gt;memory_limit&lt;/code&gt;, the memory profile is a real consideration. The right move there is to leave validate-on-huge-inputs on &lt;code&gt;ext/json&lt;/code&gt; and migrate the encode and decode paths. That's exactly what coexistence buys.&lt;/p&gt;
&lt;h3 id=&quot;compat-harness&quot;&gt;Compat harness&lt;/h3&gt;
&lt;p&gt;53 rewritten phpt tests from &lt;code&gt;php-src/ext/json/tests/*.phpt&lt;/code&gt; run alongside fastjson's native suite. They cover the common decode/encode/validate paths, the flag combinations, and the documented error conditions.&lt;/p&gt;
&lt;p&gt;The two remaining intentional divergences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Large/scientific doubles.&lt;/strong&gt; Outside the integer-valued-double shortcut range, fastjson emits yyjson's real-number format. &lt;code&gt;ext/json&lt;/code&gt; uses &lt;code&gt;php_gcvt&lt;/code&gt; and switches to scientific notation earlier. The disagreement window narrowed in 0.3.0; what's left is the genuinely-fractional case where yyjson and &lt;code&gt;php_gcvt&lt;/code&gt; produce different decimal representations of the same IEEE 754 double.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;U+2028 / U+2029 line separators.&lt;/strong&gt; &lt;code&gt;ext/json&lt;/code&gt; always escapes these for JSONP safety. yyjson treats them as ordinary code points. fastjson follows yyjson's behavior. If JSONP is in the deployment path, set &lt;code&gt;JSON_UNESCAPED_UNICODE&lt;/code&gt; off in &lt;code&gt;ext/json&lt;/code&gt; and stay on &lt;code&gt;ext/json&lt;/code&gt; for that endpoint, or wrap fastjson output through a JSONP-safe post-step.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;upstream-collaboration-with-yyjson&quot;&gt;Upstream collaboration with yyjson&lt;/h3&gt;
&lt;p&gt;fastjson vendors yyjson 0.12.0 with three local patches. Full details are in &lt;code&gt;vendor/yyjson/PATCHES.md&lt;/code&gt;; the short version of each, and what happened when each was proposed upstream:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Lowercase hex digits in &lt;code&gt;\uXXXX&lt;/code&gt; escape table.&lt;/strong&gt; yyjson emits uppercase; &lt;code&gt;ext/json&lt;/code&gt; emits lowercase. RFC 8259 §7 allows either, but byte-parity with &lt;code&gt;ext/json&lt;/code&gt; is the project's compat goal. Proposed as &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ibireme/yyjson/pull/264&quot;&gt;yyjson#264&lt;/a&gt; (&lt;code&gt;YYJSON_WRITE_LOWERCASE_HEX&lt;/code&gt; flag) and &lt;strong&gt;accepted&lt;/strong&gt; upstream on 2026-05-11. fastjson will drop this patch once the vendored sources advance past yyjson 0.12.0.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;YYJSON_READ_VALIDATE_ONLY&lt;/code&gt;, no-tree validate mode.&lt;/strong&gt; Forks yyjson's parser entry point to skip the value-graph build entirely; peak memory drops 2.7× on the validate corpus. Not yet proposed upstream; the API surface needs a round of review before it's ready to submit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Public &lt;code&gt;yyjson_write_string_to_buf()&lt;/code&gt; wrapper.&lt;/strong&gt; Exposes yyjson's internal direct-write primitive so fastjson's one-stage encoder can compose at the buffer level. Proposed as &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ibireme/yyjson/pull/266&quot;&gt;yyjson#266&lt;/a&gt; and &lt;strong&gt;closed&lt;/strong&gt; upstream; the maintainer preferred to keep that surface private. The wrapper stays vendored locally; fastjson lives with it indefinitely.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;install&quot;&gt;Install&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;pie install iliaal/fastjson
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or build from source:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;phpize
./configure
make -j
make test
sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHP 8.3 minimum. No external library dependencies; yyjson is vendored in &lt;code&gt;src/yyjson/&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;the-four-character-migration&quot;&gt;The four-character migration&lt;/h3&gt;
&lt;p&gt;fastjson stays useful as long as yyjson's design choices (one-stage encoder, validate-only fast path, allocator hooks) beat what fits into &lt;code&gt;ext/json&lt;/code&gt;'s compatibility envelope. For the call sites where JSON serialization shows up on a flame graph, the migration is four characters; the rest of the codebase doesn't have to care.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/iliaal/fastjson&quot;&gt;https://github.com/iliaal/fastjson&lt;/a&gt;. Benchmark methodology and reproduction: &lt;code&gt;bench/run.php&lt;/code&gt;. Visual baseline: &lt;a rel=&quot;nofollow&quot; href=&quot;https://iliaal.github.io/fastjson/baseline.html&quot;&gt;https://iliaal.github.io/fastjson/baseline.html&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18453/fastjson-0-3-0-a-faster-drop-in-ext-json-for-php-backed-by-yyjson</guid>
<pubDate>Wed, 20 May 2026 11:49:28 +0000</pubDate>
</item>
<item>
<title>Parsing hundreds of megabytes of JSON in milliseconds in React Native</title>
<link>https://coderlegion.com/18298/parsing-hundreds-of-megabytes-of-json-in-milliseconds-in-react-native</link>
<description>&lt;p&gt;&lt;em&gt;How &lt;code&gt;JSON.parse&lt;/code&gt; materializes entire documents in JavaScript, and how &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ifeoluwak/react-native-fast-json&quot;&gt;react-native-fast-json&lt;/a&gt; uses native simdjson + lazy &lt;code&gt;JsonView&lt;/code&gt; access to change the cost model in React Native.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ifeoluwak/react-native-fast-json&quot;&gt;react-native-fast-json&lt;/a&gt;&lt;/strong&gt; is an open-source React Native library that wraps &lt;strong&gt;simdjson&lt;/strong&gt; in C++ and exposes a lazy &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt; through &lt;a rel=&quot;nofollow&quot; href=&quot;https://nitro.margelo.com/&quot;&gt;Nitro Modules&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most teams treat JSON parsing as “cheap” because API responses are small. The mental model is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;bytes on wire → JSON.parse → plain objects in JS → app logic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That model breaks when the payload is &lt;strong&gt;hundreds of megabytes&lt;/strong&gt;. The dominant cost is not “JSON syntax is slow” in the abstract, it is &lt;strong&gt;allocating and wiring up a full value tree in the JavaScript heap&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-json-parse-actually-does-in-react-native&quot;&gt;What &lt;code&gt;JSON.parse&lt;/code&gt; actually does in React Native&lt;/h3&gt;
&lt;p&gt;When you call &lt;code&gt;JSON.parse&lt;/code&gt; (or &lt;code&gt;await response.json()&lt;/code&gt;), the engine:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Holds the &lt;strong&gt;UTF-16/UTF-8 string&lt;/strong&gt; (or an internal representation of the body)&lt;/li&gt;
&lt;li&gt;Walks the entire document&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;every&lt;/strong&gt; object, array, number, boolean, and string, creates &lt;strong&gt;JavaScript values&lt;/strong&gt; with engine overhead (hidden classes, property storage, array backing stores, interned strings, etc.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For a &lt;strong&gt;~250 MB&lt;/strong&gt; file, outcomes depend heavily on &lt;strong&gt;platform and available RAM&lt;/strong&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Symptom &lt;/th&gt;&lt;th&gt;Typical cause&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Multi-second freezes&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Single-threaded parse + massive allocation on the JS thread&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Memory far above file size&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;JS object graph overhead (often &lt;strong&gt;~2–4×&lt;/strong&gt; the raw JSON size in bad cases)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;OOM / process kill&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Peak JS heap + retained tree + rest of the app&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;On the &lt;strong&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/strong&gt; fixture in our tests: &lt;strong&gt;iOS&lt;/strong&gt; could complete &lt;code&gt;JSON.parse&lt;/code&gt; but only with &lt;strong&gt;extreme CPU and memory spikes&lt;/strong&gt;; &lt;strong&gt;Android&lt;/strong&gt; &lt;strong&gt;always crashed&lt;/strong&gt; before parse finished, making &lt;code&gt;JSON.parse&lt;/code&gt; &lt;strong&gt;impossible&lt;/strong&gt; for that payload on Android, while native &lt;code&gt;parseFile&lt;/code&gt; worked on both platforms.&lt;/p&gt;
&lt;h4 id=&quot;benchmark-fixture-source-&quot;&gt;Benchmark fixture (source)&lt;/h4&gt;
&lt;p&gt;Measurements in this repo use the public &lt;strong&gt;~250 MB&lt;/strong&gt; JSON from &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples&quot;&gt;antonmedv/json-examples&lt;/a&gt;:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Repository&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples&quot;&gt;https://github.com/antonmedv/json-examples&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;File&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples/blob/master/data_250mb.json&quot;&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Raw URL&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ifeoluwak/react-native-fast-json/tree/main/example&quot;&gt;example app&lt;/a&gt; downloads that URL, caches it on disk, then calls &lt;code&gt;parseFile&lt;/code&gt; on the local path.&lt;/p&gt;
&lt;h4 id=&quot;measured-results-parsefile-release-builds-physical-devices-&quot;&gt;Measured results (&lt;code&gt;parseFile&lt;/code&gt;, release builds, physical devices)&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Platform &lt;/th&gt;&lt;th&gt;Time to root &lt;code&gt;JsonView&lt;/code&gt; &lt;/th&gt;&lt;th&gt;CPU / memory (observed)&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~100 ms&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Stable&lt;/strong&gt;, no long CPU peg, no runaway JS heap growth during parse&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~500 ms&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Stable&lt;/strong&gt;, same qualitative behavior as iOS, slower wall time&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;JSON.parse&lt;/code&gt; / &lt;code&gt;response.json()&lt;/code&gt;&lt;/strong&gt; on the same fixture:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Platform &lt;/th&gt;&lt;th&gt;&lt;code&gt;JSON.parse&lt;/code&gt; &lt;/th&gt;&lt;th&gt;&lt;code&gt;parseFile&lt;/code&gt; + lazy &lt;code&gt;JsonView&lt;/code&gt;&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Many seconds&lt;/strong&gt;; &lt;strong&gt;extreme&lt;/strong&gt; CPU and memory spikes (~&lt;strong&gt;1.2 GB&lt;/strong&gt; JS heap ballpark) &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~100 ms&lt;/strong&gt;; CPU and memory &lt;strong&gt;stable&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Crash&lt;/strong&gt;, could &lt;strong&gt;not&lt;/strong&gt; complete parse &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~500 ms&lt;/strong&gt;; CPU and memory &lt;strong&gt;stable&lt;/strong&gt; (~&lt;strong&gt;400 MB&lt;/strong&gt; mostly &lt;strong&gt;native&lt;/strong&gt; buffer)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The second row is &lt;strong&gt;not&lt;/strong&gt; “free memory.” The file still occupies roughly &lt;strong&gt;file size + simdjson padding&lt;/strong&gt; in native memory. The win is &lt;strong&gt;avoiding a second full copy as a giant JS object graph&lt;/strong&gt; until you explicitly materialize pieces.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-read-file-as-string-then-json-parse-can-be-worse-at-peak&quot;&gt;Why “read file as string, then &lt;code&gt;JSON.parse&lt;/code&gt;” can be worse at peak&lt;/h3&gt;
&lt;p&gt;A common variant:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const text = await readFile(path, 'utf8');
const data = JSON.parse(text);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At peak you may briefly hold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;entire file as one JS string&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;entire parsed tree&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Parser scratch allocations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;response.json()&lt;/code&gt; can sometimes avoid exposing one giant application-level string, but the &lt;strong&gt;end state&lt;/strong&gt; is still the same: a full tree in JS. For large files, &lt;strong&gt;peak heap&lt;/strong&gt; is the killer.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-technique-how-react-native-fast-json-does-it&quot;&gt;The technique: how react-native-fast-json does it&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ifeoluwak/react-native-fast-json&quot;&gt;react-native-fast-json&lt;/a&gt; is what makes the native lazy model practical in React Native. Instead of returning a plain object from &lt;code&gt;JSON.parse&lt;/code&gt;, it shifts work across a different boundary:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;file bytes → native buffer (simdjson) → JsonView handle → read paths on demand
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;1-native-buffer-simdjson-&quot;&gt;1. Native buffer (simdjson)&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;parseFile&lt;/code&gt; loads the file into a &lt;strong&gt;padded&lt;/strong&gt; native buffer (&lt;code&gt;simdjson::padded_string::load&lt;/code&gt;). Parsing runs in &lt;strong&gt;C++&lt;/strong&gt; with &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/simdjson/simdjson&quot;&gt;simdjson&lt;/a&gt; (SIMD-accelerated, widely used for large JSON).&lt;/p&gt;
&lt;p&gt;The document’s canonical bytes live in &lt;strong&gt;native memory&lt;/strong&gt;, not as nested JS objects.&lt;/p&gt;
&lt;h4 id=&quot;2-lazy-jsonview-nitro-hybrid-object-&quot;&gt;2. Lazy &lt;code&gt;JsonView&lt;/code&gt; (Nitro hybrid object)&lt;/h4&gt;
&lt;p&gt;The root returned to JavaScript is a &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt;, a &lt;a rel=&quot;nofollow&quot; href=&quot;https://nitro.margelo.com/&quot;&gt;Nitro&lt;/a&gt; hybrid object backed by C++. Calling:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getValue('metadata')&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;atPath('$.a.b.c')&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;asString()&lt;/code&gt; on a scalar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;…does &lt;strong&gt;targeted&lt;/strong&gt; native work and only crosses the bridge with &lt;strong&gt;small&lt;/strong&gt; results (another &lt;code&gt;JsonView&lt;/code&gt; handle or a primitive), not the whole document.&lt;/p&gt;
&lt;h4 id=&quot;3-materialization-is-explicit-and-expensive&quot;&gt;3. Materialization is explicit and expensive&lt;/h4&gt;
&lt;p&gt;When you call:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;asObject()&lt;/code&gt;&lt;/strong&gt;, subtree becomes a JS-friendly map/array structure&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;rawJson()&lt;/code&gt;&lt;/strong&gt;, subtree becomes a JS string&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;…you have chosen to &lt;strong&gt;pay the JS heap cost&lt;/strong&gt; for that slice. On a 250 MB document, calling these on the &lt;strong&gt;root&lt;/strong&gt; is equivalent to opting back into the problem you avoided.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;architecture&quot;&gt;Architecture&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;HybridFastJson&lt;/code&gt;&lt;/strong&gt; (&lt;code&gt;cpp/HybridFastJson.cpp&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;parseFile(path)&lt;/code&gt;, load file, construct &lt;code&gt;HybridJsonView&lt;/code&gt;, &lt;strong&gt;cache&lt;/strong&gt; by path string&lt;/li&gt;
&lt;li&gt;&lt;code&gt;parseString(str)&lt;/code&gt;, copy string into native view (&lt;strong&gt;not&lt;/strong&gt; path-cached)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;release(path)&lt;/code&gt;, erase cache entry for that path&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;HybridJsonView&lt;/code&gt;&lt;/strong&gt;, navigation, path helpers, scalar coercion, optional materialization.&lt;/p&gt;
&lt;p&gt;Until &lt;code&gt;release(path)&lt;/code&gt;, a cached &lt;code&gt;parseFile&lt;/code&gt; keeps the &lt;strong&gt;full native buffer&lt;/strong&gt; alive even if JS drops its &lt;code&gt;JsonView&lt;/code&gt; reference, plan releases when the flow ends.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-you-still-pay-for-honest-accounting-&quot;&gt;What you still pay for (honest accounting)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Cost &lt;/th&gt;&lt;th&gt;Still there?&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;File-sized native memory&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Yes, roughly &lt;strong&gt;JSON size + padding&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Parse CPU&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Yes, but native simdjson is much faster than building a JS tree&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;JS heap for the whole tree&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;, unless you &lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt; large parts&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Bridge traffic&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Per access; keep reads coarse-grained for huge docs&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Path cache&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;parseFile&lt;/code&gt; retains buffer until &lt;strong&gt;&lt;code&gt;release(path)&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;There is &lt;strong&gt;no zero memory overhead&lt;/strong&gt;. The claim that holds up is: &lt;strong&gt;near-zero &lt;em&gt;additional&lt;/em&gt; JS heap for the full document&lt;/strong&gt; while you navigate lazily.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-milliseconds-or-low-hundreds-of-ms-are-plausible-for-hundreds-of-mb&quot;&gt;Why milliseconds (or low hundreds of ms) are plausible for hundreds of MB&lt;/h3&gt;
&lt;p&gt;simdjson is designed for throughput on large valid JSON. On the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples/blob/master/data_250mb.json&quot;&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt; fixture, &lt;strong&gt;&lt;code&gt;parseFile&lt;/code&gt; after the file is on disk&lt;/strong&gt; landed at &lt;strong&gt;~100 ms on iOS&lt;/strong&gt; and &lt;strong&gt;~500 ms on Android&lt;/strong&gt; in our release builds, with &lt;strong&gt;stable CPU and memory&lt;/strong&gt;. By contrast, &lt;strong&gt;&lt;code&gt;JSON.parse&lt;/code&gt; on iOS&lt;/strong&gt; took &lt;strong&gt;many seconds&lt;/strong&gt; with &lt;strong&gt;extreme spikes&lt;/strong&gt;; on &lt;strong&gt;Android&lt;/strong&gt; it &lt;strong&gt;always crashed&lt;/strong&gt;, so native parse was the only viable option there.&lt;/p&gt;
&lt;p&gt;Caveats when you reproduce benchmarks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fixture&lt;/strong&gt;, use the same public file or disclose yours&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cold vs warm&lt;/strong&gt; storage (first read after download vs re-parse)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Platform&lt;/strong&gt;, Android was ~5× slower than iOS in our tests; do not assume one number for all devices&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device tier&lt;/strong&gt; and storage speed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON shape&lt;/strong&gt; (depth, string density) affects constant factors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debug vs release&lt;/strong&gt; native builds, ship measurements on &lt;strong&gt;release&lt;/strong&gt; binaries&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;comparison-table-same-fixture-measured-observed-&quot;&gt;Comparison table (same fixture, measured + observed)&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Dimension &lt;/th&gt;&lt;th&gt;&lt;code&gt;JSON.parse&lt;/code&gt; (our tests) &lt;/th&gt;&lt;th&gt;Native &lt;code&gt;JsonView&lt;/code&gt; (&lt;code&gt;parseFile&lt;/code&gt;)&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Completes after &lt;strong&gt;many seconds&lt;/strong&gt;; &lt;strong&gt;extreme&lt;/strong&gt; CPU/memory spikes &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~100 ms&lt;/strong&gt;; &lt;strong&gt;stable&lt;/strong&gt; CPU/memory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Crash&lt;/strong&gt;, parse &lt;strong&gt;not possible&lt;/strong&gt; on ~250 MB &lt;/td&gt;&lt;td&gt;&lt;strong&gt;~500 ms&lt;/strong&gt;; &lt;strong&gt;stable&lt;/strong&gt; CPU/memory&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Primary memory&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Full JS object graph (when it survives) &lt;/td&gt;&lt;td&gt;Native padded buffer (~file size)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;UI thread risk&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;High during parse &lt;/td&gt;&lt;td&gt;Lower; still avoid huge sync work in JS&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Best access pattern&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Whole-tree mutation &lt;/td&gt;&lt;td&gt;Few paths / scalars / wildcards&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Foot-guns&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Retaining whole &lt;code&gt;data&lt;/code&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt; on huge nodes; never calling &lt;code&gt;release&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id=&quot;wildcards-and-paths&quot;&gt;Wildcards and paths&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;atPath('$.a.b.c')&lt;/code&gt;&lt;/strong&gt;, simple dotted segments, no &lt;code&gt;[index]&lt;/code&gt; in the path string.&lt;/li&gt;
&lt;li&gt;*&lt;em&gt;`atPathWithWildcard('$.items[&lt;/em&gt;].id')&lt;code&gt;**, dynamic segments; returns &lt;/code&gt;string[] | null` for matched scalar strings.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For very large documents, prefer &lt;strong&gt;narrow&lt;/strong&gt; paths over scanning wildcards across the whole tree unless you have measured the cost.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;when-native-lazy-parsing-is-the-wrong-tool&quot;&gt;When native lazy parsing is the wrong tool&lt;/h3&gt;
&lt;h4 id=&quot;not-a-common-use-case-prefer-better-alternatives&quot;&gt;Not a common use case, prefer better alternatives&lt;/h4&gt;
&lt;p&gt;Shipping &lt;strong&gt;~250 MB JSON&lt;/strong&gt; to a phone is a &lt;strong&gt;smell&lt;/strong&gt;, not a pattern. We benchmark it because it stress-tests the parser and matches real legacy pain, not because every app should do it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Try these first&lt;/strong&gt; (usually cheaper than optimizing parse):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Don’t send the file&lt;/strong&gt;, paginate, stream, or return only fields the UI needs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t use JSON on the wire&lt;/strong&gt;, schema-driven binary formats decode faster and smaller.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t keep one blob&lt;/strong&gt;, SQLite (or similar) with indexes for the queries you actually run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t parse on the critical path&lt;/strong&gt;, generate summaries or shards on the server; sync deltas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Native lazy parsing is a &lt;strong&gt;mitigation&lt;/strong&gt; when you are locked into large JSON. It is not a substitute for a sane data contract.&lt;/p&gt;
&lt;h4 id=&quot;when-this-library-still-does-not-help-enough&quot;&gt;When this library still does not help enough&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Small payloads, &lt;code&gt;JSON.parse&lt;/code&gt; is simpler and fast enough.&lt;/li&gt;
&lt;li&gt;You need the entire document in JS anyway, you will materialize everything eventually; measure whether native parse + bulk &lt;code&gt;asObject()&lt;/code&gt; is still a win.&lt;/li&gt;
&lt;li&gt;Heavy in-place mutation of arbitrary subtrees in JS, work on plain objects.&lt;/li&gt;
&lt;li&gt;You cannot hold &lt;strong&gt;file-sized native RAM&lt;/strong&gt; (low-RAM devices + multiple huge files), budget and serialize access; even native buffers are ~file size.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;benchmark-methodology&quot;&gt;Benchmark methodology&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { fastJson } from 'react-native-fast-json';

const root = await fastJson.parseFile('/path/to/large.json');
const version = root?.getValue('metadata')?.getValue('version')?.asString();
fastJson.release('/path/to/large.json');
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fixture&lt;/strong&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples/blob/master/data_250mb.json&quot;&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;&lt;/a&gt; from &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/antonmedv/json-examples&quot;&gt;antonmedv/json-examples&lt;/a&gt;, via&lt;br&gt;
&lt;code&gt;https://github.com/antonmedv/json-examples/raw/refs/heads/master/data_250mb.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RN Version&lt;/strong&gt; 0.85.0, New Architecture.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device&lt;/strong&gt;, physical iOS and Android (document model, OS, RN version, Hermes on/off).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt;, release native binary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scenarios&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;A: &lt;code&gt;response.json()&lt;/code&gt; or &lt;code&gt;JSON.parse&lt;/code&gt; after full string in memory&lt;/li&gt;
&lt;li&gt;B: download/cache to disk → &lt;code&gt;parseFile(localPath)&lt;/code&gt; → read N fields → &lt;code&gt;release(path)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Metrics&lt;/strong&gt;, wall time to root &lt;code&gt;JsonView&lt;/code&gt;, JS heap snapshot, CPU/memory stability in Instruments / Android Studio.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Our results&lt;/strong&gt;, &lt;code&gt;parseFile&lt;/code&gt;: iOS &lt;strong&gt;~100 ms&lt;/strong&gt;, Android &lt;strong&gt;~500 ms&lt;/strong&gt;, CPU/memory &lt;strong&gt;stable&lt;/strong&gt;. &lt;code&gt;JSON.parse&lt;/code&gt;: iOS &lt;strong&gt;many seconds&lt;/strong&gt; with &lt;strong&gt;extreme spikes&lt;/strong&gt;; Android &lt;strong&gt;always crashed&lt;/strong&gt; on this fixture.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ifeoluwak/react-native-fast-json/tree/main/example&quot;&gt;example app&lt;/a&gt; implements download + &lt;code&gt;parseFile&lt;/code&gt; + timing UI, use it as a starting point, not as universal truth.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Idea &lt;/th&gt;&lt;th&gt;Detail&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Problem&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;JSON.parse&lt;/code&gt; &lt;strong&gt;materializes&lt;/strong&gt; the whole document in the JS heap.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Technique&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Parse in &lt;strong&gt;native&lt;/strong&gt; with simdjson; expose &lt;strong&gt;&lt;code&gt;JsonView&lt;/code&gt;&lt;/strong&gt;; read &lt;strong&gt;lazily&lt;/strong&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;&lt;code&gt;data_250mb.json&lt;/code&gt;:&lt;/strong&gt; ~&lt;strong&gt;100 ms&lt;/strong&gt; (iOS) / ~&lt;strong&gt;500 ms&lt;/strong&gt; (Android) for &lt;code&gt;parseFile&lt;/code&gt; in our tests.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;CPU / memory&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;strong&gt;Stable&lt;/strong&gt; on native parse; &lt;code&gt;JSON.parse&lt;/code&gt; had &lt;strong&gt;extreme spikes&lt;/strong&gt; on iOS and &lt;strong&gt;crashed&lt;/strong&gt; on Android for this fixture.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Memory model&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Avoid blowing up the &lt;strong&gt;JS heap&lt;/strong&gt;; native still holds &lt;strong&gt;~file size&lt;/strong&gt;.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Discipline&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;&lt;code&gt;release(path)&lt;/code&gt;, avoid huge &lt;code&gt;asObject()&lt;/code&gt; / &lt;code&gt;rawJson()&lt;/code&gt;, extract scalars to plain JS when done.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id=&quot;try-react-native-fast-json&quot;&gt;Try react-native-fast-json&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;yarn add react-native-fast-json react-native-nitro-modules
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install pods, rebuild, then use &lt;code&gt;fastJson.parseFile&lt;/code&gt; for large files on disk. Peer dependency: &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://nitro.margelo.com/&quot;&gt;react-native-nitro-modules&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18298/parsing-hundreds-of-megabytes-of-json-in-milliseconds-in-react-native</guid>
<pubDate>Tue, 19 May 2026 08:39:22 +0000</pubDate>
</item>
<item>
<title>Don’t Just Ask AI for JSON. Design the Output.</title>
<link>https://coderlegion.com/17702/dont-just-ask-ai-for-json-design-the-output</link>
<description>&lt;p&gt;When we use AI in a chat window, a little extra text usually does not matter.&lt;/p&gt;
&lt;p&gt;If the model says:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Sure, here is the result:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;before answering, we can still read it.&lt;/p&gt;
&lt;p&gt;If it adds:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Hope this helps!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;after the answer, we can simply ignore it.&lt;/p&gt;
&lt;p&gt;But code cannot ignore things the same way.&lt;/p&gt;
&lt;p&gt;When AI output needs to be passed into a parser, stored in a database, sent to another service, or used inside an automation pipeline, the shape of the answer matters as much as the answer itself.&lt;/p&gt;
&lt;p&gt;This is where many AI workflows break.&lt;/p&gt;
&lt;p&gt;We ask:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Please output the result in JSON.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And the AI replies:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Of course! Here is the JSON:

```json
{
  &quot;sentiment&quot;: &quot;negative&quot;,
  &quot;product&quot;: &quot;Notebook Battery&quot;,
  &quot;issue&quot;: &quot;Battery lasts less than 3 hours&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let me know if you need anything else!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
To a person, this looks fine.

To code, this may be a problem.

The JSON may be wrapped in a code block.  
There may be text before it.  
There may be text after it.  
The keys may be wrong.  
The structure may change next time.  
The output may look like JSON but fail when parsed.

That is the structured output problem.

## “Give me JSON” is not enough

A common mistake is thinking that structured output is just a matter of asking more clearly.

```txt
Output in JSON.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Output only JSON.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Do not include any explanation. JSON only.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These instructions help.&lt;/p&gt;
&lt;p&gt;But they do not fully solve the problem.&lt;/p&gt;
&lt;p&gt;LLMs generate text probabilistically. They are very good at continuing patterns. In normal conversations, models often include polite openings, explanations, summaries, and helpful closing sentences.&lt;/p&gt;
&lt;p&gt;So even when we ask for JSON, the model may still follow the conversational pattern it has learned.&lt;/p&gt;
&lt;p&gt;This does not mean the model is broken.&lt;/p&gt;
&lt;p&gt;It means we are asking a language model to produce something that is not really language in the usual sense. JSON is not a friendly paragraph. It is a strict structure.&lt;/p&gt;
&lt;p&gt;And strict structures need more than polite instructions.&lt;/p&gt;
&lt;h3 id=&quot;the-three-ways-structured-output-often-breaks&quot;&gt;The three ways structured output often breaks&lt;/h3&gt;
&lt;p&gt;In practice, AI-generated JSON usually fails in a few familiar ways.&lt;/p&gt;
&lt;h4 id=&quot;1-text-before-the-json&quot;&gt;1. Text before the JSON&lt;/h4&gt;
&lt;p&gt;The model adds something like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Sure, here is the result:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;before the object.&lt;/p&gt;
&lt;p&gt;A human can ignore it.&lt;br&gt;
&lt;code&gt;JSON.parse()&lt;/code&gt; cannot.&lt;/p&gt;
&lt;h4 id=&quot;2-text-after-the-json&quot;&gt;2. Text after the JSON&lt;/h4&gt;
&lt;p&gt;The model gives valid JSON, then adds an explanation:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;This analysis shows that the user is unhappy with the battery performance.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the output is no longer pure JSON.&lt;/p&gt;
&lt;h4 id=&quot;3-json-like-text-that-is-not-valid-json&quot;&gt;3. JSON-like text that is not valid JSON&lt;/h4&gt;
&lt;p&gt;This is the most subtle failure.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  sentiment: &quot;negative&quot;,
  'product': &quot;Notebook Battery&quot;,
  &quot;issue&quot;: &quot;Battery life&quot;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It looks close enough to a human.&lt;/p&gt;
&lt;p&gt;But it is not valid JSON.&lt;/p&gt;
&lt;p&gt;Missing quotes, single quotes, trailing commas, comments, extra fields, wrong types — these are all small mistakes that can break a pipeline.&lt;/p&gt;
&lt;h3 id=&quot;structure-is-part-of-the-design&quot;&gt;Structure is part of the design&lt;/h3&gt;
&lt;p&gt;The important shift is this:&lt;/p&gt;
&lt;p&gt;Structured output is not just about formatting.&lt;/p&gt;
&lt;p&gt;It is about designing the boundary between AI and the rest of the system.&lt;/p&gt;
&lt;p&gt;When the AI is only talking to a person, the output can be flexible.&lt;/p&gt;
&lt;p&gt;But when the AI is talking to code, the output must be predictable.&lt;/p&gt;
&lt;p&gt;A paragraph is useful for reading.&lt;br&gt;
A checklist is useful for review.&lt;br&gt;
A table is useful for comparison.&lt;br&gt;
JSON is useful when another system needs to process the result.&lt;/p&gt;
&lt;p&gt;The same answer becomes more valuable when it has the right shape.&lt;/p&gt;
&lt;h3 id=&quot;start-by-separating-thinking-from-output&quot;&gt;Start by separating thinking from output&lt;/h3&gt;
&lt;p&gt;One practical pattern is to separate the model’s reasoning space from the final output space.&lt;/p&gt;
&lt;p&gt;Instead of saying:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Analyze this review and output JSON.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can say:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;First, analyze the review.

Then output only the final JSON in this exact format:

{
  &quot;sentiment&quot;: &quot;positive | neutral | negative&quot;,
  &quot;product&quot;: &quot;string or null&quot;,
  &quot;main_issue&quot;: &quot;string or null&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The idea is simple.&lt;/p&gt;
&lt;p&gt;Let the model think freely where format does not matter.&lt;br&gt;
Then make the final output strict.&lt;/p&gt;
&lt;p&gt;This reduces the pressure on the model to reason and maintain a rigid format at the same time.&lt;/p&gt;
&lt;h3 id=&quot;examples-are-stronger-than-explanations&quot;&gt;Examples are stronger than explanations&lt;/h3&gt;
&lt;p&gt;Another useful pattern is showing the model exactly what we want.&lt;/p&gt;
&lt;p&gt;Instead of only explaining the format, provide examples.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Input:
&quot;Galaxy S24 battery drains too fast.&quot;

Output:
{&quot;sentiment&quot;:&quot;negative&quot;,&quot;product&quot;:&quot;Galaxy S24&quot;,&quot;issue&quot;:&quot;battery life&quot;}

Input:
&quot;iPhone camera is amazing.&quot;

Output:
{&quot;sentiment&quot;:&quot;positive&quot;,&quot;product&quot;:&quot;iPhone&quot;,&quot;issue&quot;:&quot;camera&quot;}

Now process this:

Input:
{{new_review}}

Output:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works because the model continues the pattern.&lt;/p&gt;
&lt;p&gt;If every example starts directly with JSON, the model is more likely to continue with JSON instead of adding a friendly sentence first.&lt;/p&gt;
&lt;p&gt;In prompt engineering, examples often beat instructions.&lt;/p&gt;
&lt;h3 id=&quot;for-serious-systems-prompts-are-not-the-final-layer&quot;&gt;For serious systems, prompts are not the final layer&lt;/h3&gt;
&lt;p&gt;Prompting can improve reliability.&lt;/p&gt;
&lt;p&gt;But if the output is important enough, prompts alone may not be enough.&lt;/p&gt;
&lt;p&gt;A production system may need stronger layers:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;1. Clear output instructions
2. Separate reasoning from final output
3. Explicit schema
4. API-level structured output or tool calling
5. Validation and retry logic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the difference between asking for structure and designing for structure.&lt;/p&gt;
&lt;p&gt;If the output fails, the system should not simply crash.&lt;/p&gt;
&lt;p&gt;It should parse, validate, detect the error, and recover if possible.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;The previous response could not be parsed as JSON.
The error was: trailing comma after final field.
Please return the same result as pure valid JSON only.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This kind of recovery loop treats AI output as something that can fail.&lt;/p&gt;
&lt;p&gt;And that is a healthier assumption.&lt;/p&gt;
&lt;h3 id=&quot;structured-output-is-about-trust&quot;&gt;Structured output is about trust&lt;/h3&gt;
&lt;p&gt;The more AI becomes part of workflows, agents, and automation systems, the more important structured output becomes.&lt;/p&gt;
&lt;p&gt;If AI is only helping us think, flexible text is fine.&lt;/p&gt;
&lt;p&gt;But if AI output becomes input for another process, the format must be reliable.&lt;/p&gt;
&lt;p&gt;A workflow cannot depend on “probably valid JSON.”&lt;br&gt;
An automation cannot depend on “usually parseable output.”&lt;br&gt;
A database pipeline cannot depend on “the model will likely follow instructions.”&lt;/p&gt;
&lt;p&gt;At that point, structured output is not a nice-to-have.&lt;/p&gt;
&lt;p&gt;It is part of system design.&lt;/p&gt;
&lt;h3 id=&quot;the-real-lesson&quot;&gt;The real lesson&lt;/h3&gt;
&lt;p&gt;The lesson is not:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Ask AI for JSON.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The lesson is:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Design the output so another system can trust it.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That means being clear about format, separating reasoning from final output, giving examples, using schemas when needed, and validating the result before trusting it.&lt;/p&gt;
&lt;p&gt;AI can generate useful answers.&lt;/p&gt;
&lt;p&gt;But useful answers are not always usable outputs.&lt;/p&gt;
&lt;p&gt;When we work with AI as developers, we should not only ask:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Is the answer correct?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We should also ask:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Can this output be safely used by the next step?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the real reason structured output matters.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Originally published at Dechive:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://dechive.dev/en/archive/prompt-structured-output&quot;&gt;https://dechive.dev/en/archive/prompt-structured-output&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17702/dont-just-ask-ai-for-json-design-the-output</guid>
<pubDate>Wed, 13 May 2026 09:55:59 +0000</pubDate>
</item>
<item>
<title>Unicode escape' codec can't decode bytes in position 2-3: truncated \ uxxxxxxxx escape</title>
<link>https://coderlegion.com/17134/unicode-escape-codec-cant-decode-bytes-in-position-2-3-truncated-uxxxxxxxx-escape</link>
<description>&lt;p&gt;In this article, we will solve a syntax based problem of &lt;strong&gt;&quot;Unicodeescape' codec can't decode bytes in position 2-3: truncated \uxxxxxxxx escape&quot;&lt;/strong&gt;. This problem is encountered when we make a mistake in using the &lt;strong&gt;&quot;unicode esacpe characters.&quot;&lt;/strong&gt;Python's interpreter is designed to understand certain characters with certain symbols and in programming each character is given a unicode. This error occurs when the interpreter fails to distinguish between a normal character and a &lt;strong&gt;unicode character&lt;/strong&gt;. We can solve this problem by simply &lt;strong&gt;manipulating the string&lt;/strong&gt; according to the interpreter's logic. We will also discuss how these unicode character works and the reason behind this syntax problem. Let's quickly go through the contents of this article. &lt;/p&gt;
&lt;div id=&quot;toc-div&quot;&gt;
&lt;h4&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Table of contents: - &lt;/strong&gt;&lt;a id=&quot;toc-toogle&quot; class=&quot;open&quot;&gt;&lt;/a&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div id=&quot;toc-list&quot;&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#what&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Understanding the error and discussing how the interpreter functions.&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#why&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Solving the error with a relevant example&lt;/span&gt;&lt;/a&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sol1&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Solution 1.&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sol2&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Solution 2.&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sol3&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Solution 3.&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#sol&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Why unicode characters were assigned and steps to avoid this error.&lt;/span&gt;&lt;/a&gt;

&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#con&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;The Conclusion&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;section&gt;&lt;a id=&quot;what&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Understanding the error and discussing how the interpreter functions.&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; &lt;a id=&quot;TypeError-str-object&quot; style=&quot;color: blue;&quot; rel=&quot;nofollow&quot; href=&quot;#what&quot;&gt;#&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial, helvetica, sans-serif;&quot;&gt;Let's break this error statment down: &lt;strong&gt;&quot;Unicodeescape' codec can't decode bytes in position 2-3: truncated \uxxxxxxxx escape&quot;.&lt;/strong&gt; This means that there is a syntax error and the interpreter is not able understand the meaning of this code. The &lt;strong&gt;&quot;Unicodeescape&quot;&lt;/strong&gt; term means that the syntax error is caused because the unicode escape characters are not used properly. Now we have a lot to dissect, let's start with the interpreter's logic. if we pass a command like: -  &lt;/span&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;print('This is her mother's dress')

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

The output of this code will be: -
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;print('This is her mother's dress.')
          ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax. Perhaps you forgot a comma?

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the interpreter is unable to understand the range of the string. We use &quot; &lt;strong&gt;'&lt;/strong&gt; &quot; character to set the range of characters to be printed. The interpreter is confused because it is not able to distinguish between a normal character and a single quote range setter. We can solve this problem with the help of escape sequences. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;print('This is her mother\'s dress')

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;This is her mother's dress
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here , the backslash character instructs the interpreter that it is an escape sequence for the single quote character ('). As we observed that the interpreter was confused and this confusion led to a syntax error. This is the exact problem we are facing. Let's understand this with the help of an example. &lt;/p&gt;
&lt;section&gt;&lt;a id=&quot;why&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Solving the error with a relevant example&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;a id=&quot;reasons-that-will-cause&quot; style=&quot;color: blue;&quot; rel=&quot;nofollow&quot; href=&quot;#why&quot;&gt;#&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;We know that the interpreter follow certain rules while printing and traversing the data. Suppose we have to load a file and traverse the data stored in it. We use the file handling concepts and perform the operation but on running the program we encounter the same error: - &lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;path = &quot;C:\Users\Dell\Downloads\lamdaphagevirus\lamda.txt&quot;
file = open(path, &quot;r&quot;)
data=file.read()
print(data)

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;path = &quot;C:\Users\Dell\Downloads\lamdaphagevirus\lamda.txt&quot;
                                                              ^
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What went wrong here? The error is in the path variable. we passed the location of the file and it consists of multiple backslashes. Now the interpreter is confused which character is a normal character and which one is a &lt;strong&gt;unicode escape character.&lt;/strong&gt; We know that the entire file location is a normal string without any unicode characters but the use of &quot;\&quot; characters is causing the problem. How are we going to solve this problem? Let's look at some solutions: - &lt;/p&gt;
&lt;div class=&quot;div-green&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Tip&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;Each character is assigned with a unicode and an escape sequence which is universal for all the languages.&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;a id=&quot;sol1&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Solution 1&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;For the 1st solution, we will convert out string into a &lt;strong&gt;raw string&lt;/strong&gt; like this: -&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;path = r&quot;C:\Users\Dell\Downloads\lamdaphagevirus\lamda.txt&quot;
file = open(path, &quot;r&quot;)
data=file.read()
print(data)

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;GGGCGGCGACCTCGCGGGTTTTCGCTATTTATGAAAATTTTCCGGTTTAAGGCGTTTCCGTTCTTCTTCG
TCATAACTTAATGTTTTTATTTAAAATACCCTCTGAAAAGAAAGGAAACGACAGGTGCTGAAAGCGAGGC

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A raw string is used whenever we want to avoid the technique of escaping characters with the help of backslashes. In order to convert a string into a raw string we have to simply add a &lt;strong&gt;&quot;r&quot;&lt;/strong&gt; before the starting of the string. If this solution does not work for you then try the next method.&lt;/p&gt;
&lt;p&gt;After this manually install &quot;dlib&quot; from &lt;a rel=&quot;nofollow&quot; href=&quot;https://pypi.org/simple/dlib/&quot;&gt;this link.&lt;/a&gt; This can help the programmer to solve this issue. &lt;/p&gt;

&lt;a id=&quot;sol2&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Solution 2&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;If the the raw string method fails then try to escape the characters with the help of a backslash.&lt;/span&gt;
&lt;/p&gt;&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;path = &quot;C:\\Users\\Dell\\Downloads\\lamdaphagevirus\\lamda.txt&quot;
file = open(path, &quot;r&quot;)
data=file.read()
print(data)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;GGGCGGCGACCTCGCGGGTTTTCGCTATTTATGAAAATTTTCCGGTTTAAGGCGTTTCCGTTCTTCTTCG
TCATAACTTAATGTTTTTATTTAAAATACCCTCTGAAAAGAAAGGAAACGACAGGTGCTGAAAGCGAGGC

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the interpreter a single backslash character means this &quot;\\&quot;. All the escape characters begin with a backslash and by using this character before every backslash in the string, we can instruct the interpreter to treat this character as a escape sequence.&lt;/p&gt;
&lt;a id=&quot;sol3&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Solution 3&lt;/strong&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;For the third solution we have to manipulate the string and replace every backslash with a &lt;strong&gt;&quot;/&quot;&lt;/strong&gt; character.&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;path = &quot;C:/Users/Dell/Downloads/lamdaphagevirus/lamda.txt&quot;
file = open(path, &quot;r&quot;)
data=file.read()
print(data)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&lt;span style=&quot;font-family:arial,helvetica,sans-serif;&quot;&gt;GGGCGGCGACCTCGCGGGTTTTCGCTATTTATGAAAATTTTCCGGTTTAAGGCGTTTCCGTTCTTCTTCG
TCATAACTTAATGTTTTTATTTAAAATACCCTCTGAAAAGAAAGGAAACGACAGGTGCTGAAAGCGAGGC
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-purple&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Note&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;In case of file handling, majority of the errors are caused due to an invalid location entry.&lt;/span&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;p&gt;To know more about unicode errors &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/howto/unicode.html&quot;&gt;vist this link.&lt;/a&gt;&lt;/p&gt;
&lt;section&gt;
&lt;a id=&quot;sol&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;&lt;h2&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;Why unicode characters were assigned and how to avoid this error.&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt;&lt;a id=&quot;the-solution&quot; style=&quot;color: blue;&quot; rel=&quot;nofollow&quot; href=&quot;#sol&quot;&gt;#&lt;/a&gt;&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Now that we have discussed the different solutions for the unicode error, we will try to understand the logic behind the designation of such codes. The main reason for assigning a universal code to every character was to establish uniformity in programming. During the early phases when technology was developing, majority of the codes were built around English language but as the technology progressed many nations started to get involved in this field. So, in order to avoid confusion and establish uniformity among the programming world, codes were assigned which were universal for all the languages around the globe.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We have to learn more about escape sequences and unicode if we want to avoid this kind of syntax error.&lt;/p&gt;


&lt;/section&gt;

&lt;section&gt;&lt;a id=&quot;con&quot; class=&quot;custom_anchor&quot;&gt;&lt;/a&gt;
&lt;h2&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt;The conclusion&lt;/strong&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;This article offers the most effective solution for the error: - &lt;strong&gt;&quot;Unicodeescape' codec can't decode bytes in position 2-3: truncated \uxxxxxxxx escape&quot;.&lt;/strong&gt; We discussed about the logic of interpreter and the different ways to solve this error. We strolled through the concepts of &lt;strong&gt;unicode&lt;/strong&gt; and &lt;strong&gt;escape sequences&lt;/strong&gt;. We also discussed the idea and purpose behind the creation of unicode.&lt;/span&gt;&lt;/p&gt;
&lt;/section&gt;&lt;/section&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17134/unicode-escape-codec-cant-decode-bytes-in-position-2-3-truncated-uxxxxxxxx-escape</guid>
<pubDate>Sat, 09 May 2026 07:21:58 +0000</pubDate>
</item>
<item>
<title>How This Tool Improves Developer Productivity with JSON and API Workflows</title>
<link>https://coderlegion.com/8480/how-this-tool-improves-developer-productivity-with-json-and-api-workflows</link>
<description>&lt;p&gt;JSON is the de facto data interchange format for modern web and mobile applications. However, generating, validating, and maintaining JSON structures manually can introduce friction in development workflows, particularly during rapid prototyping and API development.&lt;/p&gt;
&lt;p&gt;Automated JSON Structure Generation&lt;/p&gt;
&lt;p&gt;The tool converts natural-language descriptions into syntactically valid, well-structured JSON. It automatically handles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proper nesting of objects and arrays&lt;/li&gt;
&lt;li&gt;List item Consistent key naming&lt;/li&gt;
&lt;li&gt;Appropriate primitive and composite data types&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This reduces human error and eliminates repetitive boilerplate.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API-Ready Response Generation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Generated output can be used directly as mock API responses. This enables frontend teams to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Develop UI components independently of backend availability Simulate&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API contracts early in the development cycle Validate response&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;schemas before backend implementation&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This approach aligns well with contract-first and API-driven development methodologies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By automating JSON generation and validation while supporting downstream API workflows, this tool reduces development overhead and accelerates iteration cycles, allowing engineers to focus on system design and business logic rather than data scaffolding.&lt;/p&gt;
&lt;p&gt;Reference tool:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://formatjsononline.com/ai-json-generator&quot;&gt;https://formatjsononline.com/ai-json-generator&lt;/a&gt;&lt;/p&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/8480/how-this-tool-improves-developer-productivity-with-json-and-api-workflows</guid>
<pubDate>Mon, 15 Dec 2025 10:12:51 +0000</pubDate>
</item>
<item>
<title>JsonX: Lightweight JSON to C struct mapping for Embedded Systems</title>
<link>https://coderlegion.com/6601/jsonx-lightweight-json-to-c-struct-mapping-for-embedded-systems</link>
<description>&lt;h3 id=&quot;jsonx-lightweight-json-c-struct-mapping-for-embedded-systems&quot;&gt;JsonX: Lightweight JSON → C struct mapping for Embedded Systems&lt;/h3&gt;
&lt;p&gt;JsonX is a lightweight C library for embedded developers who need to map JSON directly into structs — without dynamic memory or code generators.&lt;/p&gt;
&lt;p&gt;JSON is everywhere - from web APIs to IoT devices.&lt;/p&gt;
&lt;p&gt;But on microcontrollers, most JSON libraries feel like elephants in a china shop: they assume megabytes of RAM, malloc on every step, and a friendly OS.&lt;/p&gt;
&lt;p&gt;Typical JSON libraries for embedded systems fall into two extremes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full-featured giants (e.g. &lt;strong&gt;ArduinoJson, jansson&lt;/strong&gt;): powerful but memory-hungry.&lt;/li&gt;
&lt;li&gt;Bare parsers (e.g. &lt;strong&gt;JSMN, cJSON, jfes&lt;/strong&gt;): no mapping, just tokenization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-the-problem-with-json-on-embedded-devices&quot;&gt; The Problem with JSON on Embedded Devices&lt;/h3&gt;
&lt;p&gt;When you work with RTOS or bare-metal firmware where every byte and cycle counts.&lt;br&gt;
That’s where &lt;strong&gt;JsonX&lt;/strong&gt; comes in - a lightweight layer over &lt;strong&gt;cJSON&lt;/strong&gt; designed specifically for MCU + RTOS environments, where predictable memory and simplicity matter most.&lt;/p&gt;
&lt;p&gt;So you either waste RAM or write tons of manual traversal code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// classical pain
value = cJSON_GetObjectItem(root, &quot;config&quot;);
param = cJSON_GetObjectItem(value, &quot;baudrate&quot;);
baudrate = param-&amp;gt;valueint;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-jsonx-in-one-sentence&quot;&gt; JsonX in One Sentence&lt;/h3&gt;
&lt;p&gt;A thin mapping layer that turns JSON into C structs using a declarative table, not hand-written traversal.&lt;/p&gt;
&lt;p&gt;Example structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;typedef struct
{
    char      device_name[32];
    double    baudrate;
    bool      debug;
} config_t;

config_t config;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mapping:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JX_ELEMENT config_desc[] =
{
    JX_PROPERTY_STRING(&quot;device_name&quot;, config.device_name),
    JX_PROPERTY_NUMBER(&quot;baudrate&quot;, config.baudrate),
    JX_PROPERTY_BOOLEAN(&quot;debug&quot;, config.debug),
};

const size_t config_desc_size = sizeof(config_desc)/sizeof(config_desc[0]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that’s it - one call:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const char *config_json_str = &quot;{\&quot;device_name\&quot;:\&quot;sensor1\&quot;,\&quot;baudrate\&quot;:9600,\&quot;debug\&quot;:true}&quot;;

if(jx_json_to_struct(char *buffer, config_desc, config_desc_size, JX_MODE_STRICT) == JX_SUCCESS)
{
    jx_log(&quot;Configuration loaded: %s @ %lu\n&quot;, config.device_name, (uint32_t)config.baudrate);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No malloc() surprises, no deep tree traversal.&lt;/p&gt;
&lt;h3 id=&quot;-core-benefits&quot;&gt; Core Benefits&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Predictable Memory&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;All allocations go through RTOS pools or a static buffer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No hidden malloc/free. Works under &lt;strong&gt;ThreadX, FreeRTOS, or bare-metal&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Automatic Struct Mapping&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Define once → parse many.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shared parsing engine for all schemas.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Optional / Ignored Fields&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Unknown keys ignored automatically.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optional fields can have defaults.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Makes firmware tolerant to JSON changes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Readable and Debuggable&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You still get readable JSON in logs - easier to verify on target or&lt;br&gt;
via serial output.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-jsonx-vs-binary-formats&quot;&gt;⚖️ JsonX vs Binary Formats&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;When NOT to use JsonX:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You control both ends and need max bandwidth (LoRa, NB-IoT)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You rely on schema versioning (protobuf/flatbuffers)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When JsonX shines:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You want human-readable logs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You interface with web APIs&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want deterministic memory use&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You prefer C-only solution&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;-example-parsing-an-array-of-coordinates&quot;&gt; Example: Parsing an Array of Coordinates&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;    #define JX_USER_BUFFER_SIZE    1024    
    // Initialize JsonX (using standard malloc/free)
    jx_init();
    
    // Define point structure
    typedef struct {
        double x;
        double y;
    } Point_t;
        
    // Define square structure with array of 4 points
    typedef struct {
        Point_t points[4];
    } Square_t;
        
        
    // Create square data structure
    Square_t square = {
        .points = {
            {0, 0},
            {1, 0},
            {1, 1},
            {0, 1}
        }
    };
        
    // Define JSON mapping for a single point object
    JX_ELEMENT point_0[] = {
        JX_PROPERTY_NUMBER(&quot;x&quot;, square.points[0].x),
        JX_PROPERTY_NUMBER(&quot;y&quot;, square.points[0].y)
    };
    
    JX_ELEMENT point_1[] = {
        JX_PROPERTY_NUMBER(&quot;x&quot;, square.points[1].x),
        JX_PROPERTY_NUMBER(&quot;y&quot;, square.points[1].y)
    };
    
    JX_ELEMENT point_2[] = {
        JX_PROPERTY_NUMBER(&quot;x&quot;, square.points[2].x),
        JX_PROPERTY_NUMBER(&quot;y&quot;, square.points[2].y)
    };
    
    JX_ELEMENT point_3[] = {
        JX_PROPERTY_NUMBER(&quot;x&quot;, square.points[3].x),
        JX_PROPERTY_NUMBER(&quot;y&quot;, square.points[3].y)
    };
    
    // Define array of point objects
    JX_ELEMENT square_array[] = {
        JX_OBJECT_VAL(point_0),
        JX_OBJECT_VAL(point_1),
        JX_OBJECT_VAL(point_2),
        JX_OBJECT_VAL(point_3)
    };
    
    // Define root object with &quot;square&quot; property
    JX_ELEMENT root[] = {
        JX_PROPERTY_ARRAY(&quot;square&quot;, square_array)
    };
    
    // ===== SERIALIZATION: C struct -&amp;gt; JSON =====
    char *json_output = jx_alloc_memory(JX_USER_BUFFER_SIZE);
    if (json_output != NULL) {
        jx_struct_to_json(root, 1, json_output, JX_USER_BUFFER_SIZE, JX_FORMATTED);
        jx_log(&quot;Serialized JSON:\n%s\n\n&quot;, json_output);
        jx_free_memory(json_output);
    }
        
    // ===== DESERIALIZATION: JSON -&amp;gt; C struct =====
    const char *json_input =
    &quot;{&quot;
        &quot;  \&quot;square\&quot;: [&quot;
            &quot;    {\&quot;x\&quot;: 5, \&quot;y\&quot;: 6},&quot;
            &quot;    {\&quot;x\&quot;: 7, \&quot;y\&quot;: 8},&quot;
            &quot;    {\&quot;x\&quot;: 9, \&quot;y\&quot;: 10},&quot;
            &quot;    {\&quot;x\&quot;: 11, \&quot;y\&quot;: 12}&quot;
        &quot;  ]&quot;
    &quot;}&quot;;
    
    
    // Parse JSON
    jx_json_to_struct((char*)json_input, root, 1, JX_MODE_STRICT);
    
    // Print parsed data
    jx_log(&quot;Parsed square points:\n&quot;);
    for (int i = 0; i &amp;lt; 4; i++) {
        jx_log(&quot;  Point %d: x=%d, y=%d\n&quot;,
                    i,
                    (int)square.points[i].x,
                    (int)square.points[i].y);
        }
    // Cleanup
    jx_parser_deinit();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-tested-configuration-stm32h7-threadx--os-gcc-12-&quot;&gt; Tested Configuration: STM32H7 + ThreadX (-Os, GCC 12)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;⚙️ Memory &amp;amp; Code Footprint&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verified on STM32H7 (GCC 12, -Os, ThreadX)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;jx_parser.o&lt;/strong&gt; — 2228 B code, 4 B static RAM&lt;br&gt;
Core parser and mapping logic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;jx_static_allocator.o&lt;/strong&gt; — 248 B code, 4 B static RAM&lt;br&gt;
Implements static allocator for bare-metal mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;jx_version.o&lt;/strong&gt; — 68 B code, 0 B RAM&lt;br&gt;
Simple version string helper.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;example.o (demo)&lt;/strong&gt; — 765 B code, 1076 B RAM&lt;br&gt;
Demo test including a 1 KB byte pool for ThreadX.&lt;/p&gt;
&lt;p&gt;➡ &lt;strong&gt;Core only&lt;/strong&gt;: ≈ 2.5 KB code + 8 B static RAM&lt;/p&gt;
&lt;p&gt;➡ &lt;strong&gt;With example&lt;/strong&gt;: ≈ 3.2 KB code + 1.06 KB RAM&lt;/p&gt;
&lt;p&gt;The demo includes a 1 KB jx_byte_pool_buffer for ThreadX, but the actual pool size is user-defined.&lt;br&gt;
JsonX itself has &lt;strong&gt;no hidden heap allocations&lt;/strong&gt; - all memory management is deterministic.&lt;/p&gt;
&lt;p&gt;The static allocator consumes only ≈ &lt;strong&gt;12–16 bytes&lt;/strong&gt; of header overhead inside the provided buffer.&lt;/p&gt;
&lt;h3 id=&quot;-open-source-and-final-thoughts&quot;&gt; Open Source and Final Thoughts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/embedmind/JsonX&quot;&gt;https://github.com/embedmind/JsonX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JsonX&lt;/strong&gt; is lightweight, open-source (&lt;strong&gt;MIT&lt;/strong&gt;), and built purely in C for portability across RTOSes and MCU families.&lt;/p&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;This library isn’t about inventing a new protocol - it’s about making life easier for embedded developers who already have to deal with JSON.&lt;/p&gt;
&lt;p&gt;Working with JSON on MCUs? I'd love to hear your use case - especially if you've battled with JSMN, Jansson, or ArduinoJson before.&lt;/p&gt;
&lt;h3 id=&quot;-join-the-discussion&quot;&gt; Join the Discussion&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;⭐ Star on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/embedmind/JsonX&quot;&gt;GitHub&lt;/a&gt; if this solves your problem&lt;/li&gt;
&lt;li&gt;Found a bug? Open an &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/embedmind/JsonX/issues&quot;&gt;issue&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/6601/jsonx-lightweight-json-to-c-struct-mapping-for-embedded-systems</guid>
<pubDate>Fri, 17 Oct 2025 20:51:57 +0000</pubDate>
</item>
<item>
<title>The Complete JSON &amp; Data Toolkit</title>
<link>https://coderlegion.com/5799/the-complete-json-data-toolkit</link>
<description>&lt;p&gt;**&lt;/p&gt;
&lt;h3 id=&quot;formatj-son-online-a-powerful-json-toolkit-that-now-supports-files-up-to-100-mb&quot;&gt;FormatJ SON Online: A Powerful JSON Toolkit That now Supports Files Up to 100 MB&lt;/h3&gt;
&lt;p&gt;**&lt;br&gt;
Dealing with large JSON files can be a headache — many online tools crash or refuse files past a small size limit. That’s why I built FormatJSONOnline.com, a toolbox that not only formats, validates, and converts JSON, but now supports files up to 100 MB. Here’s what makes it stand out, and how you can get full value from it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Features &amp;amp; Highlights&lt;/strong&gt;&lt;br&gt;
✅ Format &amp;amp; Beautify JSON&lt;/p&gt;
&lt;p&gt;Clean up minified or messy JSON into a readable structure.&lt;/p&gt;
&lt;p&gt; Live Validation&lt;/p&gt;
&lt;p&gt;Catch syntax errors instantly — missing commas, mismatched braces, and more.&lt;/p&gt;
&lt;p&gt; Minify JSON&lt;/p&gt;
&lt;p&gt;Remove unnecessary whitespace to compress JSON for performance.&lt;/p&gt;
&lt;p&gt; Conversion Tools&lt;/p&gt;
&lt;p&gt;JSON → Excel / JSON → CSV / JSON → XML&lt;/p&gt;
&lt;p&gt;Excel → JSON &amp;amp; CSV → JSON&lt;/p&gt;
&lt;p&gt; AI JSON Generator + Mock API&lt;/p&gt;
&lt;p&gt;Generate JSON from plain English prompts, edit it, and publish it as a live mock REST endpoint.&lt;/p&gt;
&lt;p&gt; Support Up to 100 MB&lt;/p&gt;
&lt;p&gt;Unlike many tools with strict size limits, FormatJSONOnline handles files up to 100 MB, making it robust for real-world API responses and large datasets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt; Additional Utilities&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;SQL Formatter&lt;/p&gt;
&lt;p&gt;JSON Compare / Schema Validator / Path Finder / Dummy JSON Generator&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How to Use It (Step-by-Step)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Upload or Paste JSON / Prompt Description – Either bring in your own JSON or describe what you want in plain English.&lt;/p&gt;
&lt;p&gt;Edit &amp;amp; Validate – Fix any errors, beautify, or minify as needed.&lt;/p&gt;
&lt;p&gt;Convert or Publish – Convert JSON to other formats or publish it as a mock API endpoint.&lt;/p&gt;
&lt;p&gt;Why Support for 100 MB Matters&lt;/p&gt;
&lt;p&gt;Many online JSON tools cap at a few MB, which means you have to split, reduce, or only format parts of large responses. Supporting 100 MB means:&lt;/p&gt;
&lt;p&gt;You can format full API responses in one go.&lt;/p&gt;
&lt;p&gt;No need to chunk your JSON manually.&lt;/p&gt;
&lt;p&gt;Better for real production debugging and logging tasks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Try It Out&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Give it a spin here: &lt;a rel=&quot;nofollow&quot; href=&quot;https://formatjsononline.com&quot;&gt;https://formatjsononline.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Use the conversion pages:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://formatjsononline.com/json-to-excel&quot;&gt;JSON to Excel&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://formatjsononline.com/excel-to-json&quot;&gt;Excel to JSON&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://formatjsononline.com/json-to-csharp&quot;&gt;JSON to C#&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://formatjsononline.com/json-to-pdf&quot;&gt;JSON to PDF&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://formatjsononline.com/&quot;&gt;Format JSON Online&lt;/a&gt; aims to be the one–stop JSON toolkit for developers. With support up to 100 MB, AI JSON generation, mock API creation, and robust conversions, it eliminates the need to bounce between multiple small utilities.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/5799/the-complete-json-data-toolkit</guid>
<pubDate>Tue, 30 Sep 2025 06:59:51 +0000</pubDate>
</item>
<item>
<title>JavaScript Objects: Your First Step to Data Magic</title>
<link>https://coderlegion.com/4041/javascript-objects-your-first-step-to-data-magic</link>
<description>&lt;p&gt;Ever wondered how websites store and organize information like user profiles, product details, or your favorite playlist? The secret lies in JavaScript objects – powerful containers that make coding feel like organizing a well-structured toolbox. If you're new to programming, don't worry! By the end of this guide, you'll understand objects so well that you'll wonder how you ever coded without them.&lt;/p&gt;
&lt;h3 id=&quot;follow-me-for-more-content&quot;&gt;Follow Me for More Content&lt;/h3&gt;
&lt;p&gt;Before we dive in, let's connect! I regularly share beginner-friendly coding tips and tutorials:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Portfolio&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://abdelhakim-baalla.vercel.app/&quot;&gt;abdelhakim-baalla.vercel.app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instagram&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.instagram.com/abdelhakim.baalla/&quot;&gt;@abdelhakim.baalla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/Abdelhakim99891&quot;&gt;@Abdelhakim99891&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/abdelhakimbaalla/&quot;&gt;abdelhakimbaalla&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, let's unlock the magic of JavaScript objects!&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-are-javascript-objects-&quot;&gt;What Are JavaScript Objects?&lt;/h3&gt;
&lt;p&gt;Think of a JavaScript object as a digital filing cabinet. Just like a real filing cabinet has labeled folders containing different documents, a JavaScript object has labeled properties containing different values.&lt;/p&gt;
&lt;p&gt;In the real world, you might describe a person like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name: Abdelhakim Baalla&lt;/li&gt;
&lt;li&gt;Age: 19&lt;/li&gt;
&lt;li&gt;City: Agadir, Morocco&lt;/li&gt;
&lt;li&gt;Profession: Full Stack Developer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In JavaScript, we can represent this same information using an object:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const person = {
  name: &quot;Abdelhakim Baalla&quot;,
  age: 19,
  city: &quot;Agadir, Morocco&quot;,
  profession: &quot;Full Stack Developer&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Objects are everywhere in JavaScript! They're the building blocks that help us organize and manage data efficiently.&lt;/p&gt;
&lt;h3 id=&quot;why-are-objects-so-important-&quot;&gt;Why Are Objects So Important?&lt;/h3&gt;
&lt;p&gt;Objects solve a fundamental problem in programming: &lt;strong&gt;organization&lt;/strong&gt;. Imagine trying to manage information about 100 users using separate variables:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// This is messy and hard to manage!
const user1Name = &quot;Alice&quot;;
const user1Age = 30;
const user1Email = &quot;*Emails are not allowed*&quot;;

const user2Name = &quot;Bob&quot;;
const user2Age = 25;
const user2Email = &quot;*Emails are not allowed*&quot;;
// ... and so on for 100 users!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With objects, we can organize this data much more elegantly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const users = [
  {
    name: &quot;Alice&quot;,
    age: 30,
    email: &quot;*Emails are not allowed*&quot;
  },
  {
    name: &quot;Bob&quot;,
    age: 25,
    email: &quot;*Emails are not allowed*&quot;
  }
  // Much cleaner and scalable!
];
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;creating-your-first-javascript-object&quot;&gt;Creating Your First JavaScript Object&lt;/h3&gt;
&lt;h4 id=&quot;method-1-object-literal-syntax-most-common-&quot;&gt;Method 1: Object Literal Syntax (Most Common)&lt;/h4&gt;
&lt;p&gt;The easiest way to create an object is using curly braces &lt;code&gt;{}&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const car = {
  brand: &quot;Toyota&quot;,
  model: &quot;Camry&quot;,
  year: 2023,
  color: &quot;blue&quot;,
  isRunning: false
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;method-2-using-the-object-constructor&quot;&gt;Method 2: Using the Object Constructor&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const car = new Object();
car.brand = &quot;Toyota&quot;;
car.model = &quot;Camry&quot;;
car.year = 2023;
car.color = &quot;blue&quot;;
car.isRunning = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;method-3-using-object-create-&quot;&gt;Method 3: Using Object.create()&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const car = Object.create(null);
car.brand = &quot;Toyota&quot;;
car.model = &quot;Camry&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: Method 1 (object literal) is the most popular and readable approach among developers!&lt;/p&gt;
&lt;h3 id=&quot;understanding-object-properties&quot;&gt;Understanding Object Properties&lt;/h3&gt;
&lt;p&gt;Properties are the building blocks of objects. They consist of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;/strong&gt; (property name): The label for the data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Value&lt;/strong&gt;: The actual data stored&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const smartphone = {
  brand: &quot;Apple&quot;,        // Key: &quot;brand&quot;, Value: &quot;Apple&quot;
  model: &quot;iPhone 15&quot;,    // Key: &quot;model&quot;, Value: &quot;iPhone 15&quot;
  storage: 256,          // Key: &quot;storage&quot;, Value: 256
  hasCamera: true        // Key: &quot;hasCamera&quot;, Value: true
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;property-naming-rules&quot;&gt;Property Naming Rules&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Use camelCase for multi-word properties: &lt;code&gt;firstName&lt;/code&gt;, &lt;code&gt;phoneNumber&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Avoid spaces and special characters&lt;/li&gt;
&lt;li&gt;If you must use spaces, wrap in quotes: &lt;code&gt;&quot;phone number&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const user = {
  firstName: &quot;Sarah&quot;,           // ✅ Good
  lastName: &quot;Johnson&quot;,          // ✅ Good
  &quot;phone number&quot;: &quot;123-456-7890&quot;, // ✅ Works but not recommended
  age: 28                       // ✅ Good
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;accessing-object-properties&quot;&gt;Accessing Object Properties&lt;/h3&gt;
&lt;h4 id=&quot;dot-notation-most-common-&quot;&gt;Dot Notation (Most Common)&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const book = {
  title: &quot;The Great Gatsby&quot;,
  author: &quot;F. Scott Fitzgerald&quot;,
  pages: 180,
  genre: &quot;Classic Literature&quot;
};

console.log(book.title);    // &quot;The Great Gatsby&quot;
console.log(book.author);   // &quot;F. Scott Fitzgerald&quot;
console.log(book.pages);    // 180
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;bracket-notation&quot;&gt;Bracket Notation&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(book[&quot;title&quot;]);    // &quot;The Great Gatsby&quot;
console.log(book[&quot;author&quot;]);   // &quot;F. Scott Fitzgerald&quot;

// Useful when property names have spaces or special characters
const product = {
  &quot;product name&quot;: &quot;Laptop&quot;,
  &quot;price-usd&quot;: 999
};

console.log(product[&quot;product name&quot;]);  // &quot;Laptop&quot;
console.log(product[&quot;price-usd&quot;]);     // 999
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;dynamic-property-access&quot;&gt;Dynamic Property Access&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const student = {
  name: &quot;Emma&quot;,
  grade: &quot;A&quot;,
  subject: &quot;Mathematics&quot;
};

const propertyName = &quot;grade&quot;;
console.log(student[propertyName]); // &quot;A&quot;

// This won't work with dot notation
// console.log(student.propertyName); // undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;modifying-object-properties&quot;&gt;Modifying Object Properties&lt;/h3&gt;
&lt;h4 id=&quot;adding-new-properties&quot;&gt;Adding New Properties&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const pet = {
  name: &quot;Buddy&quot;,
  type: &quot;dog&quot;
};

// Add new properties
pet.age = 3;
pet.breed = &quot;Golden Retriever&quot;;
pet[&quot;favorite toy&quot;] = &quot;Tennis ball&quot;;

console.log(pet);
// {
//   name: &quot;Buddy&quot;,
//   type: &quot;dog&quot;,
//   age: 3,
//   breed: &quot;Golden Retriever&quot;,
//   &quot;favorite toy&quot;: &quot;Tennis ball&quot;
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;updating-existing-properties&quot;&gt;Updating Existing Properties&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const movie = {
  title: &quot;Inception&quot;,
  year: 2010,
  rating: 8.8
};

// Update properties
movie.rating = 9.0;
movie.director = &quot;Christopher Nolan&quot;;

console.log(movie.rating);   // 9.0
console.log(movie.director); // &quot;Christopher Nolan&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;deleting-properties&quot;&gt;Deleting Properties&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const account = {
  username: &quot;john_doe&quot;,
  password: &quot;secret123&quot;,
  email: &quot;*Emails are not allowed*&quot;,
  temporaryToken: &quot;abc123&quot;
};

// Delete the temporary token
delete account.temporaryToken;

console.log(account);
// {
//   username: &quot;john_doe&quot;,
//   password: &quot;secret123&quot;,
//   email: &quot;*Emails are not allowed*&quot;
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;methods-in-objects&quot;&gt;Methods in Objects&lt;/h3&gt;
&lt;p&gt;Objects can also contain functions, which are called &lt;strong&gt;methods&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const calculator = {
  result: 0,
  
  add: function(number) {
    this.result += number;
    return this;
  },
  
  subtract: function(number) {
    this.result -= number;
    return this;
  },
  
  multiply: function(number) {
    this.result *= number;
    return this;
  },
  
  getResult: function() {
    return this.result;
  }
};

// Using the calculator
calculator.add(10).multiply(2).subtract(5);
console.log(calculator.getResult()); // 15
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;modern-method-syntax&quot;&gt;Modern Method Syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const person = {
  name: &quot;Alice&quot;,
  age: 30,
  
  // Modern syntax (ES6+)
  greet() {
    return `Hello, I'm ${this.name}!`;
  },
  
  celebrateBirthday() {
    this.age++;
    return `Happy birthday! I'm now ${this.age} years old.`;
  }
};

console.log(person.greet()); // &quot;Hello, I'm Alice!&quot;
console.log(person.celebrateBirthday()); // &quot;Happy birthday! I'm now 31 years old.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;understanding-this-in-objects&quot;&gt;Understanding 'this' in Objects&lt;/h3&gt;
&lt;p&gt;The keyword &lt;code&gt;this&lt;/code&gt; refers to the object that owns the method:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const restaurant = {
  name: &quot;Pizza Palace&quot;,
  location: &quot;Downtown&quot;,
  isOpen: true,
  
  getInfo() {
    return `${this.name} is located ${this.location} and is ${this.isOpen ? 'open' : 'closed'}`;
  },
  
  toggleStatus() {
    this.isOpen = !this.isOpen;
    return `${this.name} is now ${this.isOpen ? 'open' : 'closed'}`;
  }
};

console.log(restaurant.getInfo()); // &quot;Pizza Palace is located Downtown and is open&quot;
console.log(restaurant.toggleStatus()); // &quot;Pizza Palace is now closed&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;practical-examples&quot;&gt;Practical Examples&lt;/h3&gt;
&lt;h4 id=&quot;example-1-creating-a-user-profile&quot;&gt;Example 1: Creating a User Profile&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const userProfile = {
  firstName: &quot;Sarah&quot;,
  lastName: &quot;Johnson&quot;,
  email: &quot;*Emails are not allowed*&quot;,
  age: 28,
  preferences: {
    theme: &quot;dark&quot;,
    notifications: true,
    language: &quot;English&quot;
  },
  
  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  },
  
  updateEmail(newEmail) {
    this.email = newEmail;
    return `Email updated to ${newEmail}`;
  },
  
  toggleNotifications() {
    this.preferences.notifications = !this.preferences.notifications;
    return `Notifications ${this.preferences.notifications ? 'enabled' : 'disabled'}`;
  }
};

console.log(userProfile.getFullName()); // &quot;Sarah Johnson&quot;
console.log(userProfile.updateEmail(&quot;*Emails are not allowed*&quot;)); // &quot;Email updated to *Emails are not allowed*&quot;
console.log(userProfile.toggleNotifications()); // &quot;Notifications disabled&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;example-2-building-a-shopping-cart&quot;&gt;Example 2: Building a Shopping Cart&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const shoppingCart = {
  items: [],
  total: 0,
  
  addItem(name, price, quantity = 1) {
    const item = {
      name: name,
      price: price,
      quantity: quantity,
      subtotal: price * quantity
    };
    
    this.items.push(item);
    this.calculateTotal();
    return `Added ${quantity} ${name}(s) to cart`;
  },
  
  removeItem(itemName) {
    this.items = this.items.filter(item =&amp;gt; item.name !== itemName);
    this.calculateTotal();
    return `Removed ${itemName} from cart`;
  },
  
  calculateTotal() {
    this.total = this.items.reduce((sum, item) =&amp;gt; sum + item.subtotal, 0);
  },
  
  getCartSummary() {
    return {
      itemCount: this.items.length,
      total: this.total,
      items: this.items
    };
  }
};

// Using the shopping cart
console.log(shoppingCart.addItem(&quot;Apple&quot;, 1.50, 3)); // &quot;Added 3 Apple(s) to cart&quot;
console.log(shoppingCart.addItem(&quot;Banana&quot;, 0.75, 2)); // &quot;Added 2 Banana(s) to cart&quot;
console.log(shoppingCart.getCartSummary());
// {
//   itemCount: 2,
//   total: 6,
//   items: [
//     { name: &quot;Apple&quot;, price: 1.50, quantity: 3, subtotal: 4.50 },
//     { name: &quot;Banana&quot;, price: 0.75, quantity: 2, subtotal: 1.50 }
//   ]
// }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;nested-objects&quot;&gt;Nested Objects&lt;/h3&gt;
&lt;p&gt;Objects can contain other objects, creating powerful data structures:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const company = {
  name: &quot;Tech Solutions Inc.&quot;,
  founded: 2020,
  address: {
    street: &quot;123 Main St&quot;,
    city: &quot;San Francisco&quot;,
    state: &quot;CA&quot;,
    zipCode: &quot;94105&quot;
  },
  employees: [
    {
      name: &quot;Alice Johnson&quot;,
      position: &quot;Developer&quot;,
      salary: 75000,
      skills: [&quot;JavaScript&quot;, &quot;React&quot;, &quot;Node.js&quot;]
    },
    {
      name: &quot;Bob Smith&quot;,
      position: &quot;Designer&quot;,
      salary: 65000,
      skills: [&quot;Photoshop&quot;, &quot;Figma&quot;, &quot;CSS&quot;]
    }
  ],
  
  getCompanyInfo() {
    return `${this.name} was founded in ${this.founded} and is located in ${this.address.city}, ${this.address.state}`;
  },
  
  addEmployee(employee) {
    this.employees.push(employee);
    return `Added ${employee.name} as ${employee.position}`;
  }
};

console.log(company.getCompanyInfo()); // &quot;Tech Solutions Inc. was founded in 2020 and is located in San Francisco, CA&quot;
console.log(company.employees[0].skills[0]); // &quot;JavaScript&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;common-object-methods&quot;&gt;Common Object Methods&lt;/h3&gt;
&lt;h4 id=&quot;object-keys-&quot;&gt;Object.keys()&lt;/h4&gt;
&lt;p&gt;Get all property names:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const fruit = {
  name: &quot;Apple&quot;,
  color: &quot;red&quot;,
  taste: &quot;sweet&quot;,
  size: &quot;medium&quot;
};

const keys = Object.keys(fruit);
console.log(keys); // [&quot;name&quot;, &quot;color&quot;, &quot;taste&quot;, &quot;size&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;object-values-&quot;&gt;Object.values()&lt;/h4&gt;
&lt;p&gt;Get all property values:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const values = Object.values(fruit);
console.log(values); // [&quot;Apple&quot;, &quot;red&quot;, &quot;sweet&quot;, &quot;medium&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;object-entries-&quot;&gt;Object.entries()&lt;/h4&gt;
&lt;p&gt;Get key-value pairs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const entries = Object.entries(fruit);
console.log(entries);
// [[&quot;name&quot;, &quot;Apple&quot;], [&quot;color&quot;, &quot;red&quot;], [&quot;taste&quot;, &quot;sweet&quot;], [&quot;size&quot;, &quot;medium&quot;]]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;practical-use-case---iterating-through-an-object-&quot;&gt;Practical use case - iterating through an object:&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const scores = {
  Alice: 95,
  Bob: 87,
  Charlie: 92,
  Diana: 98
};

// Using Object.entries() to iterate
Object.entries(scores).forEach(([name, score]) =&amp;gt; {
  console.log(`${name}: ${score}%`);
});
// Alice: 95%
// Bob: 87%
// Charlie: 92%
// Diana: 98%
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;best-practices-for-working-with-objects&quot;&gt;Best Practices for Working with Objects&lt;/h3&gt;
&lt;h4 id=&quot;1-use-descriptive-property-names&quot;&gt;1. Use Descriptive Property Names&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ❌ Not clear
const user = {
  n: &quot;John&quot;,
  a: 25,
  e: &quot;*Emails are not allowed*&quot;
};

// ✅ Clear and descriptive
const user = {
  name: &quot;John&quot;,
  age: 25,
  email: &quot;*Emails are not allowed*&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-group-related-properties&quot;&gt;2. Group Related Properties&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ✅ Well-organized
const product = {
  id: 1,
  name: &quot;Laptop&quot;,
  
  // Group pricing information
  pricing: {
    cost: 800,
    retail: 1200,
    discount: 0.1
  },
  
  // Group specifications
  specs: {
    brand: &quot;Dell&quot;,
    processor: &quot;Intel i7&quot;,
    ram: &quot;16GB&quot;,
    storage: &quot;512GB SSD&quot;
  },
  
  // Group availability information
  availability: {
    inStock: true,
    quantity: 25,
    warehouse: &quot;West Coast&quot;
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-use-methods-for-object-behavior&quot;&gt;3. Use Methods for Object Behavior&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const bankAccount = {
  balance: 1000,
  accountHolder: &quot;John Doe&quot;,
  
  // Methods for account operations
  deposit(amount) {
    if (amount &amp;gt; 0) {
      this.balance += amount;
      return `Deposited \({amount}. New balance: \){this.balance}`;
    }
    return &quot;Invalid deposit amount&quot;;
  },
  
  withdraw(amount) {
    if (amount &amp;gt; 0 &amp;amp;&amp;amp; amount &amp;lt;= this.balance) {
      this.balance -= amount;
      return `Withdrew \({amount}. New balance: \){this.balance}`;
    }
    return &quot;Invalid withdrawal amount or insufficient funds&quot;;
  },
  
  getBalance() {
    return `Current balance: $${this.balance}`;
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;common-mistakes-to-avoid-1&quot;&gt;Common Mistakes to Avoid&lt;/h3&gt;
&lt;h4 id=&quot;1-confusing-dot-vs-bracket-notation&quot;&gt;1. Confusing Dot vs Bracket Notation&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const settings = {
  theme: &quot;dark&quot;,
  &quot;font-size&quot;: 16
};

// ❌ This won't work
// console.log(settings.font-size); // SyntaxError

// ✅ Use brackets for properties with hyphens
console.log(settings[&quot;font-size&quot;]); // 16
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-forgetting-this-in-methods&quot;&gt;2. Forgetting 'this' in Methods&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;const counter = {
  count: 0,
  
  // ❌ Missing 'this'
  increment() {
    count++; // ReferenceError: count is not defined
  },
  
  // ✅ Using 'this' correctly
  increment() {
    this.count++;
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-accidentally-creating-global-variables&quot;&gt;3. Accidentally Creating Global Variables&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ❌ Missing 'const/let/var' creates global variable
person = {
  name: &quot;John&quot;
};

// ✅ Always declare objects properly
const person = {
  name: &quot;John&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;taking-your-skills-further&quot;&gt;Taking Your Skills Further&lt;/h3&gt;
&lt;p&gt;Now that you understand JavaScript objects, here are some next steps to continue your learning journey:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Practice Building Real Projects&lt;/strong&gt;: Create a todo list, address book, or simple game using objects&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Learn About Classes&lt;/strong&gt;: Objects and classes work together in modern JavaScript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Explore JSON&lt;/strong&gt;: Learn how objects relate to JSON (JavaScript Object Notation)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Study Object-Oriented Programming&lt;/strong&gt;: Understand inheritance, encapsulation, and other OOP concepts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dive into Advanced Topics&lt;/strong&gt;: Prototypes, destructuring, and spread operators&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Congratulations! You've just unlocked one of JavaScript's most powerful features. Objects are the foundation of modern web development, and mastering them opens doors to building amazing applications.&lt;/p&gt;
&lt;p&gt;Remember these key points:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Objects organize related data and functions together&lt;/li&gt;
&lt;li&gt;Use dot notation for simple property access&lt;/li&gt;
&lt;li&gt;Methods bring objects to life with behavior&lt;/li&gt;
&lt;li&gt;The 'this' keyword refers to the object itself&lt;/li&gt;
&lt;li&gt;Practice with real-world examples to solidify your understanding&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keep experimenting, keep coding, and most importantly, have fun with your newfound knowledge! JavaScript objects are your gateway to creating dynamic, interactive web applications.&lt;/p&gt;
&lt;h3 id=&quot;connect-amp-continue-learning&quot;&gt;Connect &amp;amp; Continue Learning&lt;/h3&gt;
&lt;p&gt;Ready to level up your JavaScript skills? I share more beginner-friendly tutorials and coding tips regularly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Portfolio&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://abdelhakim-baalla.vercel.app/&quot;&gt;Visit My Portfolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/abdelhakimbaalla/&quot;&gt;Connect with me&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/Abdelhakim99891&quot;&gt;Follow @Abdelhakim99891&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instagram&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.instagram.com/abdelhakim.baalla/&quot;&gt;Follow @abdelhakim.baalla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Abdelhakim-Baalla&quot;&gt;Check out my code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dev.to&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://dev.to/abdelhakim_baalla&quot;&gt;Read more articles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Medium&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@abdelhakimbaalla50&quot;&gt;Follow my blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;YouTube&lt;/strong&gt;: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/@Dinocrafting&quot;&gt;Watch tutorials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Found this helpful?&lt;/strong&gt; Give it a clap, share it with fellow developers, and let me know what you'd like to learn next in the comments!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Happy coding!&lt;/em&gt;&lt;/p&gt;
</description>
<category>JavaScript</category>
<guid isPermaLink="true">https://coderlegion.com/4041/javascript-objects-your-first-step-to-data-magic</guid>
<pubDate>Tue, 15 Jul 2025 17:39:08 +0000</pubDate>
</item>
<item>
<title>Top JSON Formatting &amp; Validation Tools (Fast + Developer-Friendly)</title>
<link>https://coderlegion.com/3958/top-json-formatting-validation-tools-fast-developer-friendly</link>
<description>&lt;p&gt;Here are some &lt;strong&gt;fast, reliable tools&lt;/strong&gt; for &lt;strong&gt;JSON formatting and validation&lt;/strong&gt; — perfect for developers working with APIs, logs, or large JSON payloads.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-jsonformatter-org&quot;&gt;1. &lt;a rel=&quot;nofollow&quot; href=&quot;https://jsonformatter.org&quot;&gt;&lt;strong&gt;jsonformatter.org&lt;/strong&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ Format, validate, minify, and view JSON&lt;/li&gt;
&lt;li&gt;Has tree view and raw text view&lt;/li&gt;
&lt;li&gt;Supports upload + clipboard copy&lt;/li&gt;
&lt;li&gt;Also supports XML, YAML, JWT, CSV&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Fastest and most comprehensive online tool.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h4 id=&quot;-2-jsoneditoronline-org&quot;&gt;⚡ 2. &lt;a rel=&quot;nofollow&quot; href=&quot;https://jsoneditoronline.org&quot;&gt;&lt;strong&gt;jsoneditoronline.org&lt;/strong&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Visual + code editor side-by-side&lt;/li&gt;
&lt;li&gt;Detects and highlights syntax issues live&lt;/li&gt;
&lt;li&gt;Offers &quot;Transform&quot;, &quot;Sort&quot;, and &quot;Filter&quot; tools&lt;/li&gt;
&lt;li&gt;Supports collaboration with shareable links&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Great for working with deeply nested JSON visually.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-vs-code-built-in-or-plugin-&quot;&gt;3. &lt;strong&gt;VS Code (Built-in or Plugin)&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✨ Use built-in formatting: Right click → Format Document&lt;/li&gt;
&lt;li&gt;Extensions:&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prettier&lt;/strong&gt; (formatting)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSON Tools&lt;/strong&gt; (validation, sorting, filtering)&lt;/li&gt;
&lt;li&gt;Works offline and with huge files&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;Ideal if you're already coding in VS Code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h4 id=&quot;4-quicktype-io&quot;&gt;4. &lt;a rel=&quot;nofollow&quot; href=&quot;https://quicktype.io&quot;&gt;&lt;strong&gt;quicktype.io&lt;/strong&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;⚙️ Convert JSON → TypeScript, Python, Java, etc.&lt;/li&gt;
&lt;li&gt;Also formats + validates input&lt;/li&gt;
&lt;li&gt;Instant TypeScript interfaces for Angular/NestJS devs&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Best for generating types/interfaces from real API responses.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h4 id=&quot;5-cli-tools-for-local-work-&quot;&gt;5. &lt;strong&gt;CLI Tools (For local work)&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;If you want a &lt;strong&gt;fast terminal-based&lt;/strong&gt; option:&lt;/p&gt;
&lt;h5 id=&quot;-jq-lightweight-and-powerful-&quot;&gt;✅ &lt;code&gt;jq&lt;/code&gt; (lightweight and powerful)&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;jq '.' data.json  # Format
jq type data.json # Validate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install jq   # macOS
sudo apt install jq   # Ubuntu/Debian
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;Fastest tool for shell scripting and JSON pipelines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;summary-table&quot;&gt;Summary Table&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Tool                                                 &lt;/th&gt;&lt;th&gt;Format &lt;/th&gt;&lt;th&gt;Validate &lt;/th&gt;&lt;th&gt;Extras&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://jsonformatter.org&quot;&gt;jsonformatter.org&lt;/a&gt;       &lt;/td&gt;&lt;td&gt;✅      &lt;/td&gt;&lt;td&gt;✅        &lt;/td&gt;&lt;td&gt;Tree view, minify, export&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://jsoneditoronline.org&quot;&gt;jsoneditoronline.org&lt;/a&gt; &lt;/td&gt;&lt;td&gt;✅      &lt;/td&gt;&lt;td&gt;✅        &lt;/td&gt;&lt;td&gt;Visual editing, sharing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;VS Code                                              &lt;/td&gt;&lt;td&gt;✅      &lt;/td&gt;&lt;td&gt;✅        &lt;/td&gt;&lt;td&gt;Extensions, huge JSON&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://quicktype.io&quot;&gt;quicktype.io&lt;/a&gt;                 &lt;/td&gt;&lt;td&gt;✅      &lt;/td&gt;&lt;td&gt;✅        &lt;/td&gt;&lt;td&gt;Generate TS/Java classes&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;jq&lt;/code&gt; (CLI)                                           &lt;/td&gt;&lt;td&gt;✅      &lt;/td&gt;&lt;td&gt;✅        &lt;/td&gt;&lt;td&gt;Scriptable, blazing fast&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
</description>
<category>Full-stack Dev</category>
<guid isPermaLink="true">https://coderlegion.com/3958/top-json-formatting-validation-tools-fast-developer-friendly</guid>
<pubDate>Mon, 14 Jul 2025 07:43:29 +0000</pubDate>
</item>
<item>
<title>How to serialize JSON API requests using Java Records?</title>
<link>https://coderlegion.com/477/how-to-serialize-json-api-requests-using-java-records</link>
<description>&lt;p&gt;JSON is a popularly used file format in the APIs as it is lightweight and self-describing.&lt;br&gt;
JSON stands for JavaScript Object Notation and. It was derived from JavaScript and originally specified by &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.crockford.com/&quot;&gt;Douglas Crockford&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;JSON is easy to read, write, and language-independent, supporting data structures like arrays and objects for flexible organization. It is widely used by software teams and is a common choice for storing and transferring data. The RESTful APIs generally rely on JSON files to exchange data over HTTP.&lt;/p&gt;
&lt;p&gt;In this tutorial blog we will learn to serialize the JSON API requests using Java Records.&lt;/p&gt;
&lt;h3 id=&quot;what-are-java-records-&quot;&gt;What are Java Records?&lt;/h3&gt;
&lt;p&gt;A Java record is a special type of class designed specifically for working with immutable data. Java Records were introduced in Java 14 version as a preview feature and became a standard feature in Java 16. &lt;/p&gt;
&lt;p&gt;Records offer a concise syntax for defining classes primarily intended to store immutable data.&lt;/p&gt;
&lt;p&gt;The following is a simple example of Java Records:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public record Country(String name, long population) {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;what-is-json-serialization-&quot;&gt;What is JSON Serialization?&lt;/h3&gt;
&lt;p&gt;JSON serialization is the process of transforming an object, data structure, or complex data type into a JSON (JavaScript Object Notation) format. For example, converting Java POJO into a JSON format. &lt;/p&gt;
&lt;p&gt;During JSON serialization, each attribute of an object is converted into a JSON property, while nested structures (such as lists or other objects) are represented as JSON arrays or nested JSON objects. This helps in making the data more portable and accessible to other systems, programming languages, or APIs.&lt;/p&gt;
&lt;p&gt;For example consider the following “Country” object using Java Records:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public record Country(String name, long population) {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With JSON serialization, an instance of the “Country” Record could be converted to JSON as shown below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&quot;name&quot; : &quot;India&quot;,
     &quot;population&quot;:  &quot;1.43 billion&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;how-to-serialize-json-api-requests-using-java-records-&quot;&gt;How to serialize JSON API Requests using Java Records?&lt;/h3&gt;
&lt;p&gt;API requests using request body in the JSON format can be serialized using Java Records easily through the Jackson Databind or Google Gson library. Java Records are convenient, lightweight and efficient as they automatically generate getters, as well as &lt;em&gt;equals()&lt;/em&gt;, &lt;em&gt;hashCode()&lt;/em&gt;, and &lt;em&gt;toString()&lt;/em&gt; methods.&lt;/p&gt;
&lt;p&gt;In this tutorial, we will be using the Rest-Assured library for executing the API requests and Jackson Databind library with Java Records for serializing the request body used in the API requests.&lt;/p&gt;
&lt;h3 id=&quot;api-under-test&quot;&gt;API under Test&lt;/h3&gt;
&lt;p&gt;We will be using the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mfaisalkhatri/restful-ecommerce&quot;&gt;restful-ecommerce&lt;/a&gt; APIs in this blog for demonstration. It is free to use E-Commerce Web APIs for practicing API testing and is available over GitHub.&lt;/p&gt;
&lt;p&gt;We will be using the docker-compose file to start the restful-ecommerce application and accordingly execute the API requests on our local machine. &lt;/p&gt;
&lt;h3 id=&quot;test-scenario&quot;&gt;Test Scenario&lt;/h3&gt;
&lt;p&gt;We will use the &lt;em&gt;“/addOrder”&lt;/em&gt; API that will allow adding new orders in the system. The following is the request payload for the  &lt;em&gt;“/addOrder”&lt;/em&gt; API: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ { 
    &quot;user_id&quot;: &quot;1&quot;,
    &quot;product_id&quot;: &quot;1&quot;,
    &quot;product_name&quot;: &quot;iPhone&quot;,
    &quot;product_amount&quot;: 500.00,
    &quot;qty&quot;: 1,
    &quot;tax_amt&quot;: 5.99,
    &quot;total_amt&quot;: 505.99
}]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The request accepts a JSON array with multiple JSON objects that holds the different order details.&lt;/p&gt;
&lt;p&gt;We will serialize the JSON given in the payload using Java Records and execute the POST request to add order in the system verifying that the order is added successfully.&lt;/p&gt;
&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;/h3&gt;
&lt;p&gt;We would be using the Maven project and adding the following dependencies in the pom.xml file. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;org.testng&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;testng&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;7.10.2&amp;lt;/version&amp;gt;
 &amp;lt;/dependency&amp;gt;

 &amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;io.rest-assured&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;rest-assured&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;5.5.0&amp;lt;/version&amp;gt;
   &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
 &amp;lt;/dependency&amp;gt;

 &amp;lt;dependency&amp;gt;
   &amp;lt;groupId&amp;gt;com.fasterxml.jackson.core&amp;lt;/groupId&amp;gt;
   &amp;lt;artifactId&amp;gt;jackson-databind&amp;lt;/artifactId&amp;gt;
   &amp;lt;version&amp;gt;2.18.1&amp;lt;/version&amp;gt;
 &amp;lt;/dependency&amp;gt;
 &amp;lt;dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dependencies are for TestNG that acts as a test runner, rest-assured for executing the API requests and Jackson Databind that will help in serialization.&lt;/p&gt;
&lt;p&gt;Let’s create a new package - restful-ecommerce under the &lt;em&gt;src/test&lt;/em&gt; folder in the project. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=8693737744531670164&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Let’s add two more packages under the &lt;em&gt;restful-ecommerce&lt;/em&gt; page, the first one with name - &lt;em&gt;pojo&lt;/em&gt; and the second one with name &lt;em&gt;tests&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id=&quot;test-implementation&quot;&gt;Test Implementation&lt;/h3&gt;
&lt;p&gt;The first step in implementation is to create Java Records with the fields needed for adding the &lt;em&gt;Order&lt;/em&gt; as per the request payload.&lt;/p&gt;
&lt;p&gt;The request payload requires the following fields, hence we will accordingly add those fields to the Record&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;user_id&lt;/li&gt;
&lt;li&gt;product_id&lt;/li&gt;
&lt;li&gt;product_name&lt;/li&gt;
&lt;li&gt;product_amt&lt;/li&gt;
&lt;li&gt;qty&lt;/li&gt;
&lt;li&gt;tax_amt&lt;/li&gt;
&lt;li&gt;total_amt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The data_type details for these fields can be found on the Swagger using which the fields in the Java Record can be created.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=10651747805031785369&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;So, let’s add a new Java Record - “Order”, under the &lt;em&gt;pojo&lt;/em&gt; package. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public record Order(String user_id, String product_id, String product_name, int product_amount, int qty, int tax_amt,
                   int total_amt) {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After adding the Java Record, we can straightaway move to write the API tests and create a new Java class - “AddOrderTests” under the &lt;em&gt;tests&lt;/em&gt; package.&lt;/p&gt;
&lt;p&gt;public class AddOrderTests {&lt;/p&gt;
&lt;p&gt;   @Test&lt;br&gt;
   public void testAddOrder () {&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   List&amp;lt;Order&amp;gt; orders = new ArrayList&amp;lt;&amp;gt; ();
   orders.add (new Order (&quot;1&quot;, &quot;34&quot;, &quot;Canon Camera CX12&quot;, 14500, 1, 915, 15415));

   given ().body (orders)
       .when ()
       .log ()
       .all ()
       .contentType (ContentType.JSON)
       .post (&quot;http://localhost:3004/addOrder&quot;)
       .then ()
       .log ()
       .all ()
       .statusCode (201);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;   }&lt;br&gt;
}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code Walkthrough&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The @Test annotation is from the TestNG library that will allow us to run the tests. The request payload actually accepts JSON Arrays in which multiple objects of Orders are added. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;List&amp;lt;Order&amp;gt; orders = new ArrayList&amp;lt;&amp;gt; ();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first statement in the method is creating a new list that can store Order objects. This will help us in adding multiple order objects to the list and accordingly pass them as the request body. This is done to ensure that we pass the JSON Object under JSON Arrays as the &quot;/addOrder&quot; endpoint needs the request body in JSON Array format.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;orders.add (new Order (&quot;1&quot;, &quot;34&quot;, &quot;Canon Camera CX12&quot;, 14500, 1, 915, 15415));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The second line in the method adds an object of Order with details. See how simple it is to pass the value to the Records object, Records automatically generates the required constructor for passing the values.&lt;/p&gt;
&lt;p&gt;Next, using rest-assured methods the test for the API is written.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;given ().body (orders)
   .when ()
   .log ()
   .all ()
   .contentType (ContentType.JSON)
   .post (&quot;http://localhost:3004/addOrder&quot;)
   .then ()
   .log ()
   .all ()
   .statusCode (201);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The interpretation of the above code is pretty simple: given a body of order objects, log the request details in the console, the content-type of the request body will be in JSON format. &lt;/p&gt;
&lt;p&gt;The &lt;em&gt;Post&lt;/em&gt; HTTP method should be hit for the API endpoint &lt;em&gt;“&lt;a rel=&quot;nofollow&quot; href=&quot;http://localhost:3004/addOrder”&quot;&gt;http://localhost:3004/addOrder”&lt;/a&gt;&lt;/em&gt;, when the API is executed, then the response details received should be logged in the console and its status code should be checked that should be equal to 201.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Test Execution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before we execute the test, we should make sure that the restful-ecommerce application is up and running. We can start the application using the following docker compose command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose -f docker-files/docker-compose-ecommerce.yml up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can then hit the following URL to make sure that the application is up and running. It should display the Swagger docs&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://localhost:3004/api-docs/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=9361457111427271547&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Next, we can run the test and check for the output. The following screenshots show that the JSON is serialized successfully in the API request body.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=9545470663108811260&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;addOrder&lt;/em&gt; API is successfully hit and one order is generated.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=15015810893858752380&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;summary-1&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;Java Records introduced in Java 16 are convenient, lightweight and efficient as they automatically generate getters, as well as equals(), hashCode(), and toString() methods. &lt;/p&gt;
&lt;p&gt;It can be a better fit for JSON serialization and deserialization with Jackson Databind library as it does not require writing a lot of boilerplate code.&lt;/p&gt;
&lt;p&gt;All the code examples shown in this article can be found &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mfaisalkhatri/api-testing-rest-assured&quot;&gt;over on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy Testing!&lt;/p&gt;
</description>
<category>Java</category>
<guid isPermaLink="true">https://coderlegion.com/477/how-to-serialize-json-api-requests-using-java-records</guid>
<pubDate>Sun, 10 Nov 2024 05:01:58 +0000</pubDate>
</item>
<item>
<title>Working With JSON File in Python</title>
<link>https://coderlegion.com/196/working-with-json-file-in-python</link>
<description>&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; To attain the solution for &lt;strong&gt;data storage or integrity&lt;/strong&gt;, &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/186/python-opening-%26-reading-files&quot; target=&quot;_blank&quot;&gt;handling files&lt;/a&gt;&lt;a&gt; is significant in all programming languages, whether dealing with simple textual files or with some &lt;strong&gt;structured file formats&lt;/strong&gt; like &lt;/a&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/207/mastering-reading-and-writing-csv-files-in-python&quot; target=&quot;_blank&quot;&gt;CSV&lt;/a&gt; and &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/json.html#module-json&quot; title=&quot;json&quot;&gt;JSON &lt;/a&gt; or bin. These formats are used in various domains for small applications to &lt;strong&gt;enterprise-level programs&lt;/strong&gt;. So, in this article, I will cover the basics of the JSON format and how Python will handle the JSON format by providing the reading and writing modules and some techniques for optimizing the performance of analyzing the JSON file.&lt;/p&gt;
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Overview of JSON file format&lt;/h2&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Before understanding the technicality, let's first understand the format of JSON. The JSON acronym &lt;strong&gt;JavaScript Object Notation&lt;/strong&gt; is a file format used for &lt;em&gt;storing and transferring textual data between client and server&lt;/em&gt;. This format represents data in the form of &lt;strong&gt;key-pair value&lt;/strong&gt; with comma separated. It also supports the nested data structures by using python objects.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{ 
  &quot;name&quot;: &quot;Chris&quot;, 
  &quot;age&quot;: 23, 
  &quot;address&quot;: { 
    &quot;city&quot;: &quot;New York&quot;, 
    &quot;country&quot;: &quot;America&quot; 
  }, 
  &quot;friends&quot;: { 
    &quot;name&quot;: &quot;Emily&quot;, 
    &quot;hobbies&quot;: [ &quot;biking&quot;,  &quot;music&quot;,   &quot;gaming&quot; ] 
  } 
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; In this example, we have a root JSON object representing a person. It has several properties like name and age. The address property is a nested object having two properties, city and country. Then, the person object has another object representing friends having property of name and an array of hobbies including biking, music, and gaming as value. Overall, this JSON data represents the simple key-pair value structure of JSON format.&lt;/p&gt; 
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Importance and Common Use Cases&lt;/h2&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; JSON is a &lt;strong&gt;lightweight data format&lt;/strong&gt; used to interchange the data between client and server. It is a simple &lt;strong&gt;human-readable&lt;/strong&gt; format that can be easily understood and &lt;strong&gt;parsed by the machine&lt;/strong&gt;. The best use case of JSON is a web application when you are storing and transmitting data between different web-based applications, such that the client has to fill out the Contact Us form and information is sent for further processing.&lt;/p&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; The few other use cases of JSON files are:&lt;/p&gt;
&lt;ul&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Configuration file&lt;/strong&gt;: Most of the developers used the JSON format to write and store the application data in the configuration file. These configuration files are easy to use because you can write all the &lt;strong&gt;settings and parameters&lt;/strong&gt; of the application in them. Its major use is you don't have to change the code for a distinct environment.&lt;/li&gt; 

&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Web Development&lt;/strong&gt;: JSON data format is the best fit for storing and retrieving the data between client and server. In &lt;a rel=&quot;nofollow&quot; href=&quot;https://coderlegion.com/254/python-on-the-web-high-cost-of-synchronous-uwsgi&quot; target=&quot;_blank&quot;&gt;web&lt;/a&gt; development, JavaScript makes &lt;strong&gt;dynamic applications&lt;/strong&gt;, whereas JSON is &lt;strong&gt;derived from JavaScript&lt;/strong&gt;. So, JavaScript can easily convert the JSON object into a JavaScript object for processing.&lt;/li&gt; 

&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Web API and Cross Platform&lt;/strong&gt;: JSON format is also used for &lt;strong&gt;creating the web API&lt;/strong&gt; because of its simplicity. These APIs will help to exchange the data between the web server and the client. Also, JSON is a platform-independent format and can ensure interaction with different programming languages.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=435823660352769998&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Introduction to the 'JSON' modules in Python&lt;/h2&gt;    
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Python provides us with a built-in module that specifically deals with JSON files. To use this module, we first have to &lt;strong&gt;import the JSON library&lt;/strong&gt; and use it to manipulate the JSON file. Also, it has the specialty that we don't have to install the packages for JSON separately in the machine, but simply import the library.&lt;/p&gt; 
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Working with JSON File&lt;/h2&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; While working on a program, we encountered a situation dealing with JSON data format. You must know about the ways of reading and writing operations in a JSON file. Here, the prior knowledge of file handling in Python comes in handy. So, let's start by &lt;strong&gt;importing the JSON module&lt;/strong&gt; into the program.&lt;/p&gt; 
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 1. Reading JSON File: using 'json.load()' function&lt;/h3&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Using the &lt;strong&gt;json.load()&lt;/strong&gt; function, you &lt;strong&gt;read the data&lt;/strong&gt; which is already available in the file.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import json  
file_path = &quot;sample3.json&quot; #provide location of file in the same directory    
with open(file_path, 'r') as file: #here, the file open operation is performed with write mode  
   content = json.load(file) #this will load the stored data from file and saved it into content variable 
   print(content)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=7366966339372812131&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 2. Parsing JSON data with error handling&lt;/h3&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Using &lt;strong&gt;json.loads()&lt;/strong&gt; function, you can &lt;strong&gt;parse the JSON string&lt;/strong&gt; data into a Python object. It is used when you already have the string data obtained from the API and user responses. Also, while using this function, use error handling because if the data is not in the string format, it will &lt;strong&gt;raise the exception&lt;/strong&gt; to &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/json.html#json.JSONDecodeError&quot; title=&quot;json&quot;&gt; JSONDecodeError&lt;/a&gt; .&lt;/p&gt;   
&lt;pre&gt;&lt;code&gt;import json  
file_path = &quot;sample3.json&quot; #provide location of file in the same directory    
try: 
   with open(file_path, 'r') as file: #here, the file open operation is performed with write mode  
      json_data = '{&quot;fruit&quot;: &quot;Orange&quot;, &quot;size&quot;: &quot;Medium&quot;, &quot;color&quot;: &quot;Orange&quot;}' 
      content = json.loads(json_data) 
   print(content)  
except json.JSONDecodeError as e: #it catches the exception if error occur in decoding 
   print(&quot;Decoding Error&quot;) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=11601217133943038929&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 3. Writing JSON files:  Using 'json.dump()' function&lt;/h3&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Apart from reading operations, you can also perform writing operations in JSON files. By using &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/json.html#json.dump&quot; title=&quot;json&quot;&gt; json.dump() &lt;/a&gt;    function, you can &lt;strong&gt;write all the JSON data&lt;/strong&gt; into the file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import json  
file_path = &quot;sample3.json&quot; #provide location of file in the same directory    
with open(file_path, 'w') as file: #here, the file open operation is performed with write mode  
    data = {  
       &quot;fruit&quot;: &quot;Apple&quot;,  
       &quot;size&quot;: &quot;Large&quot;,  
       &quot;color&quot;: &quot;Red&quot;  
    }  
    json.dump(data, file) #it dumps the JSON data into the file using JSON dump function  
#this is used for reading operation  
with open(file_path, 'r') as file: #here, the file open operation is performed with read mode   
    print(file.read()) #print what we write in the file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=13168742299485047233&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 4. Serializing Python data structures to JSON&lt;/h3&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Using &lt;strong&gt;json.dumps()&lt;/strong&gt; function, you can &lt;strong&gt;serialize&lt;/strong&gt; the Python data structure i.e. list, tuples, dictionary, object, and other datatype, &lt;strong&gt;to JSON string&lt;/strong&gt; that you can use for transmission and storage between client and server. It takes one argument, a Python object, and then serializes it into a JSON string. It is not used for writing to the file, but for encoding the Python objects into a JSON string.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import json  
data = {  
       &quot;fruit&quot;: &quot;Mango&quot;,  
       &quot;size&quot;: &quot;Large&quot;,  
       &quot;color&quot;: &quot;Yellow&quot;  
    }  
encode_Data = json.dumps(data) #this will encode the data into string and stores in the variable  
print(encode_Data) #it prints the converted JSON string 
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-blue&quot;&gt;   
&lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;   
&lt;span class=&quot;alert-body&quot;&gt; The JSON data is encoded using UTF-8 which is the default encoding in python JSON module. 
&lt;/span&gt;  
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=10384878108127030845&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Handling Nested JSON Files&lt;/h2&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; JSON files store the data in the string format that has the same syntax as a dictionary object in Python. However, remember that it does not work the same as a dictionary in Python. Sometimes, we get the nested JSON data during transmission and storage, where an &lt;strong&gt;object is contained in another object&lt;/strong&gt;, and we have to deal with it differently. In Python, for dealing with nested JSON files, we have to navigate or iterate through the structure of dictionaries.&lt;/p&gt; 
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 1. Understanding nested JSON data&lt;/h3&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; To understand the nested JSON data, let's take an example where a JSON object is stored in another object having the following structure:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;{ 
  &quot;name&quot;: &quot;Chris&quot;, 
  &quot;age&quot;: 23, 
  &quot;address&quot;: { 
    &quot;city&quot;: &quot;New York&quot;, 
    &quot;country&quot;: &quot;America&quot; 
  }, 
  &quot;friends&quot;: [ 
    { 
      &quot;name&quot;: &quot;Emily&quot;, 
      &quot;hobbies&quot;: [ &quot;biking&quot;, &quot;music&quot;, &quot;gaming&quot; ] 
    }, 
    { 
      &quot;name&quot;: &quot;John&quot;, 
      &quot;hobbies&quot;: [ &quot;soccer&quot;, &quot;gaming&quot; ] 
    } 
  ] 
} 
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; In the above data, you can see JSON object has a list with the name friend, where each friend is acting as a nested object with an array of hobbies.&lt;/p&gt; 
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 2. Navigating and Accessing Nested Json Objects&lt;/h3&gt;   
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; For navigating and accessing the nested object, first, parse the Json string into the Python object, then load the data into the file. After that, you can &lt;strong&gt;access and navigate by using the keys and indices&lt;/strong&gt; for each dictionary and list objects in the data.&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;import json  
data = '''{ 
     &quot;name&quot;: &quot;Chris&quot;, 
     &quot;age&quot;: 23, 
     &quot;address&quot;: { 
         &quot;city&quot;: &quot;New York&quot;, 
         &quot;country&quot;: &quot;America&quot; 
         }, 
    &quot;friends&quot;:  
    [ 
        { 
            &quot;name&quot;: &quot;Emily&quot;, 
            &quot;hobbies&quot;: [ &quot;biking&quot;, &quot;music&quot;, &quot;gaming&quot; ] 
        }, 
        { 
            &quot;name&quot;: &quot;John&quot;, 
            &quot;hobbies&quot;: [ &quot;soccer&quot;, &quot;gaming&quot; ] 
        } 
    ] 
}''' 
encode_Data = json.loads(data) #this will parse the data and stores in the variable  
#accessing the root key 
name = encode_Data[&quot;name&quot;] 
age = encode_Data[&quot;age&quot;] 
#accessing the nested keys 
city = encode_Data[&quot;address&quot;][&quot;city&quot;] 
country = encode_Data[&quot;address&quot;][&quot;country&quot;] 
#accessing the nested data within the array 
friend1 = encode_Data[&quot;friends&quot;][0][&quot;name&quot;] 
friend1_hobby = encode_Data[&quot;friends&quot;][0][&quot;hobbies&quot;] 
print(&quot;Name is:&quot;,name) 
print(&quot;Age is:&quot;, age) 
print(&quot;Country:&quot;, country) 
print(&quot;City:&quot;, city) 
print(&quot;Friend name:&quot;,friend1) 
print(&quot;Friend hobby: &quot;, friend1_hobby) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=4130096564750075693&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; 3. Techniques for flattening JSON data&lt;/h3&gt; 
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; Flattening is the technique that is used to make the nested structure of &lt;strong&gt;Json data into tabular format&lt;/strong&gt;. This format makes it easy to analyze and manipulate the data. Pythons provided us with a library named &lt;strong&gt;“pandas”&lt;/strong&gt; that gave us a simple function &lt;strong&gt;json_normalize()&lt;/strong&gt; for flattening the nested structure of JSON data into a data frame.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import json 
import pandas as pd #import pandas library 
data = '''[ 
  { 
    &quot;name&quot;: &quot;Chris&quot;, 
    &quot;age&quot;: 23, 
    &quot;address&quot;: { 
      &quot;city&quot;: &quot;New York&quot;, 
      &quot;country&quot;: &quot;America&quot; 
    } 
  }, 
  { 
    &quot;name&quot;: &quot;Emily&quot;, 
    &quot;age&quot;: 25, 
    &quot;address&quot;: { 
      &quot;city&quot;: &quot;New York&quot;, 
      &quot;country&quot;: &quot;America&quot; 
    } 
  }, 
  { 
    &quot;name&quot;: &quot;John&quot;, 
    &quot;age&quot;: 27, 
    &quot;address&quot;: { 
      &quot;city&quot;: &quot;New York&quot;, 
      &quot;country&quot;: &quot;America&quot; 
    } 
  } 
]''' #nested data 
encodedata = json.loads(data) #first parse the json string into python object  
flaten_data = pd.json_normalize(encodedata) #then, flaten the data into tabular format 
print(flaten_data) #print the table 
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-red&quot;&gt;   
&lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt;   
&lt;span class=&quot;alert-body&quot;&gt; Remember, not all python datatypes converted into JSON i.e. tuples are converted into list.  
&lt;/span&gt;  
&lt;/div&gt; 
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=14896148613240830936&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Performance Optimization and Best Practices&lt;/h2&gt;  
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt; While dealing with Json files, several performance considerations need to be followed to ensure the &lt;strong&gt;robustness and maintainability&lt;/strong&gt; of the program. Here, I am going to discuss some performance and optimizing techniques and the best practices for writing clean and efficient code.&lt;/p&gt;  
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=10933335903417327024&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; Performance Considerations for working with large JSON&lt;/h3&gt;   
&lt;ul&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Memory constraints:&lt;/strong&gt; Large Json files take a lot of memory while loading into the RAM. So, it's better to check the size of the file and available resources before processing it. &lt;/li&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Streaming Technique:&lt;/strong&gt; if you are dealing with large Json files, it is preferred to use chunks for processing the file. Large Json files will consume a lot of memory when we load the file in the RAM. So, using the Json streaming technique will load the file in the form of chunks rather than loading the entire file.&lt;/li&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Incremental approach:&lt;/strong&gt; Python provides us with a library with the name ijson, this library allows you to parse the large Json file iteratively. It's better to use libraries instead of creating chunks in the program.&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h3 style=&quot;margin: 0.5;&quot;&gt; Techniques for optimizing JSON file operation&lt;/h3&gt;  
&lt;ul&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Efficient serialization&lt;/strong&gt;: while working with Json file parsing use the efficient libraries cjson or ujson. These libraries provide a much more efficient way of serialization and deserialization of Json data instead of standard libraries.&lt;/li&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt;&lt;strong&gt; Usage of Api and generator function&lt;/strong&gt;: when working on a large Json file, try to use the streaming API or some generator function that reads the Json objects line by line instead of loading them into the memory at once. &lt;/li&gt; 
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Caching&lt;/strong&gt;: if you are accessing the same Json file frequently then increase the usage of the cache by reducing the data loading request again and again.&lt;/li&gt;  
&lt;li style=&quot;text-align: justify; margin: 1;&quot;&gt; &lt;strong&gt;Processing&lt;/strong&gt;: if you are working with many files, try to use batch processing instead of working line by line. This helps you to improve the performance of input-output operations.&lt;/li&gt;  
&lt;/ul&gt; 
&lt;div class=&quot;div-faq&quot; style=&quot;margin-bottom: 5px; margin-top: 2px;&quot;&gt;  
&lt;span class=&quot;faq-header&quot; style=&quot;font-weight: bold; color: dark-gray;&quot;&gt;FAQs&lt;/span&gt;  
&lt;span class=&quot;faq-body&quot; style=&quot;margin-top: 1px; margin-bottom: 5px;&quot;&gt; Q: Is dump() and dumps() work same? &lt;br&gt;A: No, the dump() function is used to serialize the python object to json string and store it into the file, whereas the dumps() works the same but is not stored in the file &lt;/span&gt;  
&lt;span class=&quot;faq-body&quot; style=&quot;margin-top: 1px; margin-bottom: 5px;&quot;&gt;Q: What is the ijson library?&lt;br&gt; A: The ijson library is used for iteratively parsing the json file. It deals with larger json files.&lt;/span&gt;  
&lt;/div&gt;  
&lt;h2 style=&quot;margin: 0.5;&quot;&gt;Wrapping Up&lt;/h2&gt;
&lt;p style=&quot;text-align: justify; margin: 1;&quot;&gt;In conclusion, you saw that JSON is a &lt;strong&gt;platform-independent format&lt;/strong&gt; used for &lt;strong&gt;interchanging&lt;/strong&gt; the data between client and server. Python provides us with various &lt;strong&gt;powerful built-in tools and libraries&lt;/strong&gt; to deal with Json files. Whether you are developing a web application or working on web API, understanding the fundamentals of json is significant. It is a versatile format that can &lt;strong&gt;work with any programming language&lt;/strong&gt;. So, mastering the methods mentioned in the article will help you to deal with json files efficiently. I hope this guide is helpful for you. Happy Coding!&lt;/p&gt;
&lt;h2 style=&quot;margin: 0.5;&quot;&gt; Reference&lt;/h2&gt;    
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/json.html#module-json&quot; title=&quot;json&quot;&gt;Working with Json&lt;/a&gt;   &lt;/p&gt;
</description>
<category>File Handling</category>
<guid isPermaLink="true">https://coderlegion.com/196/working-with-json-file-in-python</guid>
<pubDate>Mon, 18 Mar 2024 14:03:14 +0000</pubDate>
</item>
<item>
<title>Json.decoder.jsondecodeerror: expecting value: line 1 column 1 (char 0)</title>
<link>https://coderlegion.com/25/json-decoder-jsondecodeerror-expecting-value-line-1-column-1-char-0</link>
<description>&lt;p&gt;This article concerns &lt;em&gt;what&lt;/em&gt; &lt;strong&gt;&quot;JSON decoder error&quot;&lt;/strong&gt; is and &lt;em&gt;how to fix&lt;/em&gt; it. In the world of JSON data handling, you come across many errors but JSON decoder error is one of the common ones. This error often arises when the input JSON data is either &lt;strong&gt;improperly formatted&lt;/strong&gt; or &lt;strong&gt;missing entirely&lt;/strong&gt;, leaving developers scratching their heads. Carefully reviewing your JSON data format can help you &lt;em&gt;successfully parse&lt;/em&gt; it, improving your data handling skills. We'll explore &lt;strong&gt;why&lt;/strong&gt; this error occurs and &lt;strong&gt;strategies to rectify&lt;/strong&gt; it. So, let's embark on this journey to conquer the JSON decoding challenge.&lt;/p&gt;
&lt;h2&gt;What is a JSON decoder function?&lt;/h2&gt;
&lt;p&gt;A JSON decoding function &lt;strong&gt;converts&lt;/strong&gt; a &lt;strong&gt;JSON-formatted string&lt;/strong&gt; into a &lt;strong&gt;programming language-manipulable data structure&lt;/strong&gt;. These functions are frequently encountered in programming libraries. In order to make working with the data within your code easier, it takes a JSON string as input and converts it into a data structure, such as a dictionary (in Python), an object (in JavaScript), or a similar data structure in other languages. &lt;em&gt;JSON decoding functions are used in many programming languages to convert JSON data to native data structures&lt;/em&gt;.&lt;br&gt;
When you need to work with data from &lt;strong&gt;outside sources&lt;/strong&gt;, such as APIs, or when you need to parse configuration files in JSON format, JSON decoding routines come in handy. They ensure the JSON data is &lt;strong&gt;appropriately parsed&lt;/strong&gt; and can be used as native data types in your programs.&lt;/p&gt;
&lt;h2&gt;What does the 'json-decode-error' mean?&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;div-red&quot;&gt;&lt;br&gt;
&lt;span class=&quot;alert-header&quot;&gt;Error:&lt;/span&gt;&lt;br&gt;
&lt;span class=&quot;alert-body&quot;&gt;Json decode error&lt;/span&gt;&lt;br&gt;
&lt;/div&gt;
&lt;p&gt;When trying to &lt;strong&gt;decode (parse)&lt;/strong&gt; a JSON-formatted string into a data structure but the input JSON data is &lt;strong&gt;not well-formed&lt;/strong&gt; or &lt;strong&gt;contains syntax mistakes&lt;/strong&gt; that preclude proper parsing, the &quot;&lt;strong&gt;&lt;em&gt;JSONDecodeError&lt;/em&gt;&lt;/strong&gt;&quot; error occurs. The JSON data provided is not in a proper format, according to this issue, which commonly occurs when working with JSON data in a programming context.&lt;br&gt;
In order to resolve this error, you need to review and fix the issues in the JSON data to ensure it conforms to the JSON syntax rules, which we will be discussing further in this blog.&lt;/p&gt;
&lt;h2&gt;A few common scenarios that can lead to this error:&lt;/h2&gt;
&lt;p&gt;There can be multiple reasons for this error to occur, but here are a few most common ones:&lt;/p&gt;
&lt;h2&gt;Scenario1: Parsing an Empty string&lt;/h2&gt;
&lt;p&gt;When you attempt to parse an &lt;strong&gt;empty string&lt;/strong&gt; using a JSON decode, such as the &lt;strong&gt;&lt;code&gt;json.load()&lt;/code&gt;&lt;/strong&gt; function in Python,  you encounter the &lt;strong&gt;&lt;code&gt;JSONDecodeError: Expecting value: line 1 column 1 (char 0)&lt;/code&gt;&lt;/strong&gt; error. This error arises because an empty string essentially lacks any JSON data to work with. An empty string provides no such structure or data content to interpret, making it &lt;strong&gt;impossible&lt;/strong&gt; for the JSON decoder to identify and convert it into a meaningful data structure. Therefore, the error message serves as a signal that the JSON decoder expects to find a valid JSON value at the start of the string but instead encounters a lack of content.&lt;/p&gt;
&lt;h3&gt;Example:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import json

empty_string = &quot;&quot;
try:
    data = json.loads(empty_string)
except json.JSONDecodeError as e:
    print(f&quot;JSONDecodeError: {e}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Output:&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;JSONDecodeError: Expecting value: line 1 column 1 (char 0)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Scenario2: Incorrectly formatted JSON&lt;/h2&gt;
&lt;p&gt;JSON is a highly structured data format that adheres to predefined guidelines for information representation. The warning &lt;strong&gt;&lt;code&gt;JSONDecodeError: Expecting value&lt;/code&gt;&lt;/strong&gt; frequently denotes problems with JSON data formatting. It's vital to make sure that your input string complies with these guidelines to prevent this issue. One of the following valid JSON values should always start JSON data:&lt;br&gt;
**- Object&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;li&gt;String&lt;/li&gt;
&lt;li&gt;Number&lt;/li&gt;
&lt;li&gt;Boolean&lt;/li&gt;
&lt;li&gt;Null**&lt;br&gt;
A JSON data structure should initiate with one of these valid JSON values to be correctly formatted.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import json

invalid_json = '{&quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 30,}'  
try:
    data = json.loads(invalid_json)
except json.JSONDecodeError as e:
    print(f&quot;JSONDecodeError: {e}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-blue&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;Incorrect format due to an extra comma in 'invalid_json' variable.&lt;/span&gt;
&lt;/div&gt;
&lt;h2&gt;Scenario3: Network or File reading issues&lt;/h2&gt;
&lt;p&gt;Sometimes accessing data from external sources you end up getting this error. If you are trying to parse JSON data from an external source, such as an &lt;strong&gt;API&lt;/strong&gt; or a &lt;strong&gt;file&lt;/strong&gt;, and the source is returning an &lt;strong&gt;empty response&lt;/strong&gt; or an invalid response, it can trigger this error.&lt;br&gt;
&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import json

# Assuming 'empty.json' is an empty file
with open('empty.json', 'r') as file:
    json_data = file.read()
    try:
        data = json.loads(json_data)
    except json.JSONDecodeError as e:
        print(f&quot;JSONDecodeError: {e}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;h3&gt;Scenario 1: Solution: Parsing an Empty string&lt;/h3&gt;
&lt;p&gt;Before attempting to parse an empty string, you must first determine whether it is empty. An easy &lt;strong&gt;conditional statement&lt;/strong&gt; can accomplish this. For instance, Python:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import json

input_string = &quot;&quot;  # Your input string
if input_string:
    data = json.loads(input_string)
else:
    # Handle the case when the string is empty
    print(&quot;The input string is empty.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By this, you can easily identify the error or mistake and take action to debug it.&lt;/p&gt;
&lt;h3&gt;Scenario 2: Solution: Incorrectly formatted JSON &lt;/h3&gt;
&lt;p&gt;You must make sure that the input string is &lt;strong&gt;genuine JSON&lt;/strong&gt; if you want to fix problems with improperly formatted JSON. This can entail fixing any syntax issues or missing JSON data pieces. To help find and correct formatting mistakes, you can also use online linting or JSON validation tools.&lt;/p&gt;
&lt;h3&gt;Scenario 3: Solution: Network or File reading issues&lt;/h3&gt;
&lt;p&gt;Consider the following when working with JSON data from external sources, such as files or APIs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verify that the source is providing data. &lt;/li&gt;
&lt;li&gt;Make sure that the file or API is not empty.&lt;br&gt;
Use error handling methods to handle potential network problems or file reading errors compassionately. Use try-except blocks, for instance, in Python to catch exceptions and deal with them properly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's an example of handling network or file reading issues:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import json
import requests

try:
    response = requests.get('https://example.com/api/data')
    response.raise_for_status()  # Check for HTTP errors
    json_data = response.text

    if json_data:
        data = json.loads(json_data)
    else:
        # Handle the case when the response is empty
        print(&quot;No data received from the API.&quot;)
except requests.exceptions.RequestException as e:
    # Handle network errors
    print(f&quot;Network error: {e}&quot;)
except json.JSONDecodeError as e:
    # Handle JSON decoding errors
    print(f&quot;JSON decoding error: {e}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By using these fixes, you can handle situations where the &lt;strong&gt;&lt;code&gt;JSONDecodeError&lt;/code&gt;&lt;/strong&gt; might occur efficiently and make sure your code gracefully handles empty strings, improperly structured JSON, or problems with external data sources.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In conclusion, it's critical to address the fundamental causes methodically when dealing with &lt;strong&gt;&lt;code&gt;JSONDecodeError: Expecting value: line 1 column 1 (char 0)&lt;/code&gt;&lt;/strong&gt; or similar problems. Take the following essential actions to fix these mistakes and guarantee flawless JSON data handling: &lt;br&gt;
**- Validate Source &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;String Integrity&lt;strong&gt;&lt;br&gt;
By following these guidelines, you may confidently &lt;/strong&gt;manage the complexities&lt;strong&gt; of JSON decoding, efficiently handle errors, and take advantage of the capabilities of structured data interchange for your applications. With these techniques, you'll be well-equipped to &lt;/strong&gt;tackle** typical challenges in your coding travels. JSON decoding, like coding itself, is a voyage of accuracy and problem-solving.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;References&lt;/h2&gt; 
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://sebhastian.com/python-jsondecodeerror-expecting-value/&quot;&gt;JSON Decode Error&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Json</category>
<guid isPermaLink="true">https://coderlegion.com/25/json-decoder-jsondecodeerror-expecting-value-line-1-column-1-char-0</guid>
<pubDate>Thu, 19 Oct 2023 11:37:31 +0000</pubDate>
</item>
</channel>
</rss>