Очень много раз наблюдал и продолжаю наблюдать, как код начинает превращаться в помойку при решении рутинной задачи по конкатенации параметров URL.
Сразу приведу пример
const productParam = (product?.id) ? product.id : -1;
const categoryParam = (category?.id) ? category.id : -1;
const url = `${process.env.BASE_URL}?$product_id={productParam}&category_id=${categoryParam}`;
Это совсем простой пример всего из двух параметров, но уже выглядит не очень френдли для обслуживания, особенно, если появляются зависимые параметры и все это обрастает условными операторами и кастомными билдерами url.
Как ни странно, но даже опытные разработчики пытаются решить так эту задачу, объясняя это тем, что "зачем городить огород ради одного параметра", а потом их уже два, а потом они должны как-то обрабатываться во время выполнения, а потом логика расползается между вью и экшеном и начинается рефакторинг…
Вот пример, с чего это все начинается, казалось бы, очень безобидного и лаконичного кода
const url = `${process.env.BASE_URL}?product=${id}`;
Я пытался разобраться в чем причина популярности решения этой задачи "в лоб" и предполагаю, что причина в названии нативного класса - URLSearchParams, который, кажется не очень нам поможет в решении задачи, но это не так . Не знаю, как у вас, но меня смущает в названии "Search", потому что я вполне могу использовать параметры не для поиска или фильтра, а для ретранслирования utm, к примеру, или как-то иначе.
Давайте посмотрим на минималистичный пример решения той же задачи с использованием URLSearchParams:
let params = { product: 3, count: 5 };
const payload = new URLSearchParams(params);
const url = `${process.env.BASE_URL}?${payload}`;
Казалось бы, стало сложнее. На самом деле, можно даже сделать на одну строку меньше, но я специально этого не делал, чтобы отделить параметры. Теперь вы можете с ними легко работать и вам не придется править 2 последние строчки.
Не очень понятно в чем плюсы? Попробуйте решить задачу, по предварительной подготовке данных, к примеру, пробежаться по всем параметрам и ограничить их максимальным значением, равным 3.
Больно? Нет, если вы выбрали путь реализации через URLSearchParams. Вот пример реализации в одну строку и без модификаций уже написанного кода.
let params = { product: 3, count: 5 };
//добавляем любые преобразования работая как с обычным объектом
Object.keys(params).forEach((key) => params[key] = (params[key] > 3 ? 3 : params[key]))
//тут ничего не меняем
const payload = new URLSearchParams(params);
const url = `${process.env.BASE_URL}?${payload}`;
Надеюсь вы почувствовали разницу.
Если вы ревьювер, пожалуйста, поделитесь, часто такое встречается в коде вашей команды? Если нет, то вероятно, у меня просто паранойя и мне везет на подобный код и модификации параметров.
Надеюсь кому-то будет полезен этот пост. Всем удачи и чистого кода!