sanity-io / GROQ

Specification for GROQ - The Query Language for JSON
https://groq.dev
MIT License
398 stars 15 forks source link

Feature request: Don't return null values from groq query #100

Open eivindml opened 2 years ago

eivindml commented 2 years ago

For some applications, I like to use a runtime type system so I can decode the query responses from Sanity, and have a 100% runtime guarantee of correct types. One issue I'm often bumping into with regards to this, is that Sanity returns optional empty values as null.

If my decoder tries to decode the value:

type Link = {
  title: string;
  label?: string;
}

It can fail, since my label type is label?: string while Sanity basically returns label: string | null, but only for some queries.

Example:

If I do a query like this;

*[_type == "link"] {
  _id,
  title,
  label
}

the "optional" label will return a value if string | null. It would be better to not return it at all, or return it as undefined.

Skjermbilde 2022-05-24 kl  11 05 39

If I use the ... syntax like this;

*[_type == "link"] {
  ...
}

I get the result I prefer, but now I'm querying unnecessary data.

I learnt that I can use the defined(), and it works, but it's a bit verbose, I have to apply that to all optional fields.

*[_type == "resource"] {
  _id,
    "slug": slug.current,
    title,
    defined(subtitle) => {subtitle},
    defined(content) => {content},
    description,
    defined(keywords) => {keywords},
    defined(video.url) => {"video": video.url},
    "asset": {
      defined(external) => {"external": asset.external},
      defined(internal) => {"internal": asset.internal.asset->url}
    },
    categories[]->{_id, title},
   "poster": poster.asset-> {
     ...,
     "lqip": metadata.lqip
   }
}

Describe the solution you'd like

It would be nice to be able to specify this behaviour at the top level of the groq query (or something similar).

*[_type == "resource"] | defined(*) {
  _id,
    "slug": slug.current,
    title,
}

Describe alternatives you've considered

Additional context

Generic function that will run a query, optionally transform the data and then try to decode it:

Skjermbilde 2022-05-24 kl  13 01 58

And here is a usage example:

Skjermbilde 2022-05-24 kl  13 04 30
KittyGiraudel commented 2 years ago

Note: I believe this is planned for a future version of Groq. And I’ve heard this is the behavior from Groq v1.

eivindml commented 9 months ago

Is there now an option for this? Want to migrate away from api v1.

scyzemic commented 2 weeks ago

Is there any update on this? This would be great just for default function parameters alone 😅