スネークケースのレスポンスをキャメルケースで受け取りたかった


apiレスポンスのJSONのプロパティってスネークケースで扱われていますよね。
ただフロントはキャメルケースで統一してコーディングしていることが多いと思います。

キャメルケースで書いているにapi取り出し時だけスネークケースで書くのって気持ち悪い。。。。。
ということでobject内のプロパティをすべて置換するように関数を書いてみました。

作ってみた

const convertProperty = (src, converter) => Object
    .keys(src)
    .map(key => {
        const converted = converter(key)
        if (Array.isArray(src[key])) {
            return { [converted]: src[key].map(_ => convertProperty(_, converter)) };
        } else if (typeof src[key] === "object" && src[key] !== null) {
            return { [converted]: convertProperty(src[key], converter) };
        } else {
            return { [converted]: src[key] }
        }
    })
    .reduce((acc, cur) => ({ ...acc, ...cur }));

・第一引数に置換したいプロパティを持つobject
・第二引数にプロパティ名を受け取り加工して返すコールバック

を渡します。

実際使ってみます

const sample = {
        "sample_title": "test",
        "sample_array": [
            {
                "first_property": 1,
                "second_property": 2
            },
            {
                "first_property": 1,
                "second_property": 2
            }
        ],
        "sample_object": {
            "first_property": 1,
            "second_property": 2
        }
}

const toCamel = s => s.replace(/_./g, matched => matched[1].toUpperCase());

const convertedObj = convertProperty(sample, toCamel);
consloe.log(convertedObj);

出力結果

{ sampleTitle: 'test',
  sampleArray:
   [ { firstProperty: 1, secondProperty: 2 },
     { firstProperty: 1, secondProperty: 2 } ],
  sampleObject: { firstProperty: 1, secondProperty: 2 } }

ネストオブジェクトも対応できていていいかんじですね!

ここではconverterとしてスネークケース→キャメルケースにする関数を渡していますが、
コールバックかえればキャメルケース→スネークケースも対応できるので割と実用的にできた気がします。

実際のユースケース

axiosのinterceptorsと一緒に使ったりしています。

const Axios = require("axios");

const toCamel = s => s.replace(/_./g, matched => matched[1].toUpperCase());

const convertProperty = (src, converter) => Object
    .keys(src)
    .map(key => {
        const converted = converter(key)
        if (Array.isArray(src[key])) {
            return { [converted]: src[key].map(_ => convertProperty(_, converter)) };
        } else if (typeof src[key] === "object" && src[key] !== null) {
            return { [converted]: convertProperty(src[key], converter) };
        } else {
            return { [converted]: src[key] }
        }
    })
    .reduce((acc, cur) => ({ ...acc, ...cur }));

const httpClient = Axios.create({ timeout: 10000 });

httpClient.interceptors.response.use(
    (response) => Object.assign(response, { data: convertProperty(response.data, toCamel) })
);

上記のように共通のaxiosインスタンスにプロパティ変換処理を書いておけばresponseすべてがキャメルケースに変換されたうえで渡ってくるのでとてもいい感じです!

終わり

最後までお読みいただきありがとうございました。
気になる点、アドバイスございましたら是非コメントをお願いいたします!