es-tooling / ecosystem-cleanup

A place to keep track of ongoing efforts to clean up the JS ecosystem
393 stars 2 forks source link

Remove `qs` from list #35

Open OiYouYeahYou opened 7 months ago

OiYouYeahYou commented 7 months ago

On the basic KV-pair structure of a query: qs is indeed made redundant by URLSearchParams. But, qs supports a superset of the URL Query Syntax that supports deeply nested data, and acts differently is certain conditions.

The reason a more complicated format become useful in situations where you need to transmit non-path data in HTTP methods like GET. For instance, applications like Strapi strictly adhere to the HTTP method definition but needs additional information for functions like nested data population.

In this changeset, I've removed the whole recommendation, but I accept that another change would be to recommend only using qs if you need the superset support.

Examples

Stringifying

const data = {
  nested: {
    data: {
      is: ["supported", "and", "expressed"],
    },
  },
}

new URLSearchParams(data).toString()
// nested=[object+Object]
qs.stringify(data)
// nested[data][is][0]=supported&nested[data][is][1]=and&nested[data][is][2]=expressed

* I've URI decoded the strings for clarity

Parsing

const q1 =
  "nested[data][is][0]=supported&nested[data][is][1]=and&nested[data][is][2]=expressed";

Object.fromEntries(new URLSearchParams(q1))
/* {
  'nested[data][is][0]': 'supported',
  'nested[data][is][1]': 'and',
  'nested[data][is][2]': 'expressed'
} */
qs.parse(q1)
// { nested: { data: { is: ['supported', 'and', 'expressed] } } }
const q2 =
  "repeated=keys&repeated=are&repeated=supported&repeated=differently&repeated="

new URLSearchParams(q2)
/* URLSearchParams {
  'repeated' => 'keys',
  'repeated' => 'are',
  'repeated' => 'supported',
  'repeated' => 'differently',
  'repeated' => '' } */
qs.parse(q2)
// { repeated: [ 'keys', 'are', 'supported', 'differently', '' ] }

Aside about URL

Tangential FYI: URLSearchParams is fine for most applications, but URL is finicky. Depending on environment (Node vs Browser), it may or may-not parse the string as a URL or URL-like. For instance:

Most of the time people use HTTP(S) URLs and will never face this problem, but sometimes this can require avoiding the built-in.

43081j commented 7 months ago

You're right that qs isn't directly replaced by URLSearchParams.

However, i think this is more that the wording is wrong rather than us needing to remove it from the list

qs has a large footprint thanks to the deep layers of node compat it has under the hood (for very old versions of node). We should still be pushing people to lighter alternatives because of that, but making those clear rather than thinking URLSearchParams is enough

for example, i've already moved many packages to use fast-querystring, or node's own querystring module

though there's also a piece of work (unfinished) to create a lighter qs-like alternative which uses fast-querystring under the hood (or uses native functionality, either way).