How to Verify Keys in JSON Using jq

Bernice ChoyBernice Choy
3 min read

Context

A peer seek my inputs on parsing JSON. The requirements are:

  1. To determine whether a key exists or available without jq throwing error

  2. The queries are to be executed in a pipeline

Overview

I set out to explore the different ways of parsing JSON with jq using its built-in operators and functions.

  • You can try it along on your local machine or via the jq online playground.

  • The query and jq Command line (CLI) command will be provided along with the explanation below.

  • I will be mainly parsing the nested objects.

I will be using the following sample JSON file (generated by our friend ChatGPT) to test out the different approaches, saved into a file named sample.json.

{
    "id": 12345,
    "name": "RandomUser",
    "isActive": true,
    "age": 29,
    "address": {
      "street": "123 Random St",
      "city": "Randomville",
      "state": "RA",
      "zipcode": "12345"
    },
    "preferences": {
      "notifications": {
        "email": true,
        "sms": false
      },
      "theme": "dark"
    },
    "accountStatus": "Active",
    "createdAt": "2023-01-01T12:00:00Z",
    "updatedAt": "2024-08-31T14:30:00Z",
    "metadata": {
      "lastLogin": "2024-08-31T14:00:00Z",
      "subscription": {
        "plan": "Premium",
        "renewalDate": "2025-01-01"
      }
    }
  }

empty and alternative operator

A method I learned from one of my projects is using the alternative operator ('//') and emptykeyword.

  • It is useful when the subsequent operation(s) expects an input.

  • By standardizing to return no result instead of the "null" string, you can leverage on comparison operators such as -z for empty or -n for non-empty value in shell-script.

You can try the following queries to observe the differences between the usage of empty and alternative operator.

Without //empty

Note that without empty, the output returned when a invalid or non-existent path is provided is a string value of null.

jq Queryjq Command LineExpected output
.preferences.notifications.emailjq '.preferences.notifications.email' sample.jsontrue
.preferences.emailjq '.preferences.email' sample.jsonnull

With //empty

Upon using //empty , for invalid or non-existent path, no results will be returned.

jq Queryjq Command LineExpected output
.preferences.notifications.email//emptyjq '.preferences.notifications.email//empty' sample.jsontrue
.preferences.email//emptyjq '.preferences.email//empty' sample.json<No output>

has() function

Referencing to a Stack Overflow Post, the has() function may be what we are looking for to explicitly determine if a given key exists

  • This may be more intuitive, to check if the key exists

  • Will return true or false

  • Do note that it is not transitive, so you need to navigate to the target attribute before using the has() function

jq Queryjq Command LineExpected output
.preferenceshas("notifications")jq '.preferenceshas("notifications")' sample.jsontrue
.has("notifications")jq '.has("notifications")' sample.jsonfalse

Conclusion

Depending on the context of your workflow, there's probably more than 1 way to determine in verifying the keys in a JSON.

For now, just noting it down here to share with my peer and hope this may be useful to you too!

Cheers!

0
Subscribe to my newsletter

Read articles from Bernice Choy directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Bernice Choy
Bernice Choy

A fledgling engineer dabbling into areas of DevOps, AWS and automation. I enjoy tinkering with technology frameworks and tools to understand and gain visibility in the underlying mechanisms of the "magic" in them. In the progress of accumulating nuggets of wisdom in the different software engineering disciplines!