TL;DR: Is there better way how to deal with nested records with optional fields than huge Pattern Matching matrix? Some pattern everyone else knows about and I’m just unaware of?
I’m in early beginner phase with rescript, I went through documentation couple times and tried to search for something relevant to my question here and probably everywhere else I suspect it is hiding somewhere in plain sight and I’m just not realizing it is the thing I’m looking for.
I think it isn’t really relevant, but to provide context: I’m querying some GraphQL endpoint in GatsbyJS site (with help of graphql-ppx
).
After many hours spent over stupid mistakes, I have working code which allows me to retrieve record with title
and siteUrl
always present.
%%raw("import { graphql } from 'gatsby'")
type rec metadata = {
title: string,
siteUrl: string,
}
let empty = {
title: "no title",
siteUrl: "",
}
%graphql(`
query SiteMetaData {
site {
siteMetadata {
title
siteUrl
}
}
}
`)
@module("gatsby") external useStaticQueryUnsafe: string => SiteMetaData.Raw.t = "useStaticQuery"
let useSiteMetadata = () => {
let {site} = SiteMetaData.query->useStaticQueryUnsafe->SiteMetaData.parse
switch site {
| None => empty
| Some({siteMetadata: None}) => empty
| Some({siteMetadata: Some(smd)}) =>
switch smd {
| {title: None, siteUrl: None} => empty
| {title: Some(someTitle), siteUrl: None} => {title: someTitle, siteUrl: ""}
| {title: None, siteUrl: Some(someUrl)} => {title: "no title", siteUrl: someUrl}
| {title: Some(someTitle), siteUrl: Some(someUrl)} => {title: someTitle, siteUrl: someUrl}
}
}
}
As you can see from pattern matching, almost everything in the query can be nullable and graphql-ppx’s parse
is converting this to Options (which is great).
But, whole time it seems to me that I have something fundamentally wrong and there has to be more sensible way to deal with options and defaults in similar responses. Just imagine how it would even work if I add 10 more attributes to siteMetadata
and all of them optional? What if there would be another level with more options?
Btw. don’t focus on Gatsby part at all. I know that I can make fields non-optional, I just hit this problem and want to know how to deal with it. No matter if it comes from Gatsby, totally different GraphQL server or simply from nested rescript record with a lot of options.