๐ฉ Record<string, never> ํ์ฉ๋ฒ
import { isNil, isArray, isEmpty } from 'lodash'; import qs from 'query-string'; const buildQueryString = <T = Record<string, never>>(params?: T): string => { // ์ ํจํ์ง ์์ ๊ฐ(null, undefined, ๋น ๋ฌธ์์ด/๋ฐฐ์ด) ์ ๊ฑฐ const cleanedParams = omitBy(params || {}, (val) => { if (isNil(val)) return true; return isArray(val) && (val as string[]).every((v) => !v); }); // ๊ฐ์ฒด๊ฐ ๋น์ด ์์ผ๋ฉด ๋น ๋ฌธ์์ด ๋ฐํ, ์๋๋ฉด ์ฟผ๋ฆฌ ๋ฌธ์์ด ์์ฑ return isEmpty(cleanedParams) ? '' : `?${qs.stringify(cleanedParams, { arrayFormat: 'comma', encode: false })}`; }; // ์ฌ์ฉ ์์ console.log(buildQueryString()); // '' console.log(buildQueryString({ name: 'John', age: '25', empty: '' })); // '?name=John,age=25' console.log(buildQueryString({ items: [], invalid: null })); // '' console.log(buildQueryString({ tags: ['red', 'blue'], empty: null })); // '?tags=red,blue'
buildQueryString ํจ์๋ ํ๋ก ํธ์๋์์ API ์์ฒญ์ ์ํ ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ์์ฑํ๋ ์ ํธ๋ฆฌํฐ ํจ์์
๋๋ค. ์
๋ ฅ ๊ฐ์ฒด์์ ์ ํจํ์ง ์์ ๊ฐ(null, undefined, ๋น ๋ฌธ์์ด, ๋น ๋ฐฐ์ด ๋๋ ๋ชจ๋ ์์๊ฐ ๋น ๊ฐ์ธ ๋ฐฐ์ด)์ ์ ๊ฑฐํ๊ณ , ์ ํจํ ๋ฐ์ดํฐ๋ง ํฌํจํ ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ๋ฐํํฉ๋๋ค. ์ด๋ API ์์ฒญ์ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค๊ณ , ์๋ฒ์ ์ฒ๋ฆฌ ๋ถ๋ด์ ์ค์ด๋ฉฐ, ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค.
ํจ์ ๊ตฌ์กฐ
์ ๋ค๋ฆญ ํ์
<T = Record<stringุ never>>
T๋ ์
๋ ฅ ํ๋ผ๋ฏธํฐ params์ ํ์
์ ๋ํ๋
๋๋ค.
๊ธฐ๋ณธ ํ์
Record๋ ์์ฑ์ด ์๋ ๋น ๊ฐ์ฒด {}๋ฅผ ์๋ฏธํฉ๋๋ค.
params๊ฐ undefined์ด๊ฑฐ๋ ์ ๋ฌ๋์ง ์์ ๊ฒฝ์ฐ, ๋น ๊ฐ์ฒด {}๋ก ์ฒ๋ฆฌ๋์ด ํจ์๊ฐ ์์ ํ๊ฒ ๋์ํฉ๋๋ค.
ํ๋ผ๋ฏธํฐ
params?: T
- params๋ ์ ํ์ ์ด๋ฉฐ, ๊ฐ์ฒด ํํ๋ก ์ ๋ฌ๋ฉ๋๋ค.
- params || {}๋ฅผ ํตํด undefined์ผ ๊ฒฝ์ฐ ๋น ๊ฐ์ฒด๋ก ๋์ฒด๋ฉ๋๋ค.
๋ก์ง
Lodash์ omitBy
Lodash์ omitBy๋ฅผ ์ฌ์ฉํด null, undefined, ๋น ๋ฌธ์์ด ๋๋ ๋ชจ๋ ์์๊ฐ ๋น ๊ฐ์ธ ๋ฐฐ์ด์ ์ ๊ฑฐ.
{ name: "John", empty: null, items: [""] } โ { name: "John" }.
- Lodash์ isEmpty๋ก ์ ๋ฆฌ๋ ๊ฐ์ฒด๊ฐ ๋น์ด ์๋์ง ํ์ธ.
- ๋น์ด ์์ผ๋ฉด ' '๋ฅผ ๋ฐํ.
- ๊ทธ๋ ์ง ์์ผ๋ฉด qs.stringify๋ฅผ ์ฌ์ฉํด ์ฟผ๋ฆฌ ๋ฌธ์์ด๋ก ๋ณํํ๊ณ , ?๋ฅผ ์ ๋์ฌ๋ก ์ถ๊ฐ.
- arrayFormat: 'comma'๋ ๋ฐฐ์ด์ ์ผํ๋ก ๊ตฌ๋ถ (์: tags=red,blue).
- encode: false๋ URL ์ธ์ฝ๋ฉ์ ๋นํ์ฑํํด ๊ฐ๋ ์ฑ์ ๋์.
๐ ์ ๋ ฅ ์์
buildQueryString(); // ์ถ๋ ฅ: ''
- params๊ฐ undefined์ด๋ฏ๋ก ๋น ๊ฐ์ฒด {}๋ก ์ฒ๋ฆฌ.
- omitBy({}, ...)๋ ๋น ๊ฐ์ฒด๋ฅผ ๋ฐํ, isEmpty๊ฐ true์ด๋ฏ๋ก '' ๋ฐํ.
๐ ์ ํจํ ๊ฐ ํฌํจ
buildQueryString({ name: 'John', age: '25', empty: '' }); // ์ถ๋ ฅ: '?name=John,age=25'
- empty: ''๋ ์ ๊ฑฐ๋จ.
- cleanedParams = { name: 'John', age: '25' }.
- qs.stringify๋ก name=John,age=25๋ฅผ ์์ฑํ๊ณ , ?๋ฅผ ์ถ๊ฐ.
๐ ์ ํจํ์ง ์์ ๊ฐ๋ง ํฌํจ
buildQueryString({ items: [], invalid: null }); // ์ถ๋ ฅ: ''
- items: []์ invalid: null์ ์ ๊ฑฐ๋จ.
- cleanedParams = {}, isEmpty๊ฐ true์ด๋ฏ๋ก '' ๋ฐํ.
๐ ๋ฐฐ์ด ํฌํจ
buildQueryString({ tags: ['red', 'blue'], empty: null }); // ์ถ๋ ฅ: '?tags=red,blue'
- empty: null์ ์ ๊ฑฐ๋จ.
- cleanedParams = { tags: ['red', 'blue'] }.
- qs.stringify๋ก tags=red,blue๋ฅผ ์์ฑํ๊ณ , ?๋ฅผ ์ถ๊ฐ.
๋ฐฐ์ด ํฌํจ
- ํจ์จ์ ์ธ ์์ฒญ: ๋ถํ์ํ ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๊ฑฐํด ๋คํธ์ํฌ ์์ฒญ ํฌ๊ธฐ๋ฅผ ์ค์ด๊ณ , ์๋ฒ์ ์ฒ๋ฆฌ ๋ถ๋ด์ ์ํ.
- ํ์
์์ ์ฑ: Record
๋ฅผ ๊ธฐ๋ณธ ํ์ ์ผ๋ก ์ฌ์ฉํด ์ ๋ ฅ์ด ์๊ฑฐ๋ ๋น ๊ฐ์ฒด์ผ ๋๋ ์์ ํ๊ฒ ์ฒ๋ฆฌ. - ์ฌ์ฉ์ ๊ฒฝํ: ๊ฐ๊ฒฐํ ์ฟผ๋ฆฌ ๋ฌธ์์ด์ URL์ ๊น๋ํ๊ฒ ์ ์งํ๋ฉฐ, ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ๋ ๊ณต์ ๋งํฌ์ ๊ฐ๋ ์ฑ์ ๋์.
- ์๋ฒ ๋ถํ ๊ฐ์: ์ ํจํ ๋ฐ์ดํฐ๋ง ์๋ฒ๋ก ์ ์ก๋๋ฏ๋ก ์๋ฒ์ ๊ฒ์ฆ ๋ก์ง์ด ๊ฐ์ํ๋จ.
ํธ๋ํฝ ๊ด๋ฆฌ์์ ์ฐ๊ด์ฑ
- ํ๋ก ํธ์๋์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฆฌํ๋ฉด ๋ถํ์ํ ๋ฐ์ดํฐ ์ ์ก์ด ์ค์ด๋ค์ด ๋คํธ์ํฌ ํธ๋ํฝ์ด ๊ฐ์.
- ์๋ฒ๋ ์ ํจํ ๋ฐ์ดํฐ๋ง ์ฒ๋ฆฌํ๋ฏ๋ก CPU/๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ค๊ณ , ์บ์ฑ ํจ์จ์ฑ์ด ํฅ์.
- ์ด๋ ํธ๋ํฝ ์คํ์ดํฌ๋ฅผ ๊ฐ์ ์ ์ผ๋ก ๋ฐฉ์งํ๋ฉฐ, ์ ์ฒด ์์คํ ์ฑ๋ฅ์ ์ต์ ํ.