前提
GET用のURLパラメータを構築する時、URLSearchParams.toString()が便利です。次のように使います。
const params = {
search: "abc",
searchtype: 2,
userid: 1234,
}
const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?search=abc&searchtype=2&userid=1234
問題点
paramsのプロパティ値にnullやundefinedを含むものがあった場合、それらは"null"、"undefined"という文字列としてエンコードされます。
const params = {
search: null,
searchtype: undefined,
userid: 1234,
}
const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?search=null&searchtype=undefined&userid=1234
これは URLSearchParamsの仕様ではありますが、この仕様がサーバ側で役に立つケースはほぼないでしょう。
nullという入力値を本当にnullとして扱ってしまうと、今度は"null"という文字列を送信できないことになってしまう為です。
解決策(コード付き)
例えば ASP.NET Core等は、サーバ側でGET/POSTパラメータをモデルクラスにマッピングする際には、そのパラメータが存在しなければ自動的にデフォルト値(文字列やNull許容値の場合はnull、数値の場合は0)で初期化されます。
よって、paramsの中にnullやundefinedなプロパティがあれば、プロパティ自体を除外してしまえば良いでしょう。
function filterNullProperties(obj) {
return Object.keys(obj).reduce(
(retObj, key) =>
(obj[key] === null || obj[key] === undefined)
? retObj // null プロパティは無視
: Object.assign(retObj, { [key]: obj[key] }) // null でないプロパティのみretObjに追加
, {});
}
上記を用いると、次のような結果が得られます。
const params = filterNullProperties({
search: null,
searchtype: undefined,
userid: 1234,
});
const url = "https://host/api/getXXX" + (new URLSearchParams(params)).toString()
console.log(url);
https://host/api/getXXX?userid=1234
一見落着です。
気がかりな点
どうして URLSearchParamsがこのような仕様になっているのかが分からないのでその点は気がかりです。
null値を"null"という文字列にして送信することでうれしいケースがある、ということでしょうか?
また、もっとシンプルに書ける方法などありましたらコメントでご教授頂ければと思います。