DEV Community

loading...

What are best options for reliably parsed, yet powerful, querystrings?

Pacharapol Withayasakpunt
Currently interested in TypeScript, Vue, Kotlin and Python. Looking forward to learning DevOps, though.
・1 min read

I currently only care about integers and arrays to be reliably parsed.

  • JSON in querystring isn't very much seen, and I feel it is not compact. URL always have length limits.
  • I also have seen GraphQL in URL.
  • Single-lined YAML?
  • If I don't use querystring format, what about the keys? _=?

Discussion (3)

Collapse
louy2 profile image
Yufan Lou • Edited

The conventional option is of course application/x-www-form-urlencoded, but ...

Note: The application/x-www-form-urlencoded format is in many ways an aberrant monstrosity, the result of many years of implementation accidents and compromises leading to a set of requirements necessary for interoperability, but in no way representing good design practices. In particular, readers are cautioned to pay close attention to the twisted details involving repeated (and in some cases nested) conversions between character encodings and byte sequences. Unfortunately the format is in widespread use due to the prevalence of HTML forms. [HTML]

LOL.

That said if the API is public it is probably still best to use the most widely supported format, application/x-www-form-urlencoded.

If the API is private however, no one is gonna stop you from throwing your data in a MessagePack and Base65536 encode it.

EDIT: Base65536 is actually not denser than Base64 octet-wise. Just use Base64 is probably fine.

If you still want it to be readable, maybe jsurl?

Collapse
patarapolw profile image
Pacharapol Withayasakpunt Author • Edited

Both JSON and YAML are heavily url-encoded.

I ended up with Rison, which only encode strings (to single quotes 'string') if needed. Also, arrays are !(a,1), instead of ["a",1].

But indeed, I know that the original Rison project is dead. 😢

  $axios.defaults.paramsSerializer = (params) => {
    return Object.entries<any>(params)
      .map(([k, v]) => {
        if (
          [
            '_',
            ...someTroublesomeKeys,
          ].includes(k) ||
          /^is[A-Z]/.test(k)
        ) {
          v = rison.encode(v)
        }

        return `${encodeURIComponent(k)}=${encodeURIComponent(v)}`
      })
      .join('&')
  }
Collapse
louy2 profile image
Yufan Lou

FYI, there is a better maintained fork: github.com/w33ble/rison-node