こんにちは。櫻井です。
APIでJSONを受け取ったときにファイルが大きすぎると処理が重たくなってしまうのでどうにかクライアントサイドには軽いJSONデータを渡せないかなということでサーバー側で処理してからクライアントに渡す方法を思いついたのでとりあえずやってみようと思います。
まずはフロント側
HTML
<div class="js-append_dom"></div>
<button class="js-get_json">json GET</button>
htmlは単純にJSONを取得するボタンを設置するのと取得したJSONを表示させるためのDOMを用意するだけです。
JavaScript
const getBtn = document.querySelector('.js-get_json');
const appendDOM = document.querySelector('.js-append_dom');
let params = {
offset: 0,
limit: 10
};
async function getJson() {
try {
const query = new URLSearchParams(params);
const response = await fetch(`./get_json.php?${query}`);
const data = await response.json();
data.forEach(element => {
const item = `<div>${element.id} ${element.title}</div>`;
appendDOM.insertAdjacentHTML('beforeend',item);
});
params.offset += params.limit;
} catch(error) {
console.log(error)
}
}
getBtn.addEventListener('click', () => {
getJson();
})
getBtnはボタンのDOM、appendDOMはJSONを表示させるためのDOMをそれぞれ変数に格納しています。
paramsはPHPに渡すパラメーターです。
offsetが取得する開始位置
limitが一度に送るJSONの件数です。
非同期で取得してもらうのでasyncでgetJsonを定義しています。
getJsonはgetBtnがおさr他時に発火するようにしています。
try catchを使って、もしfetchが失敗したりしたらcatchに処理を流すようにしています。
queryにURLSearchParamsを使ってオブジェクトをパラメータとして付与できる形にします。
responseでphpからJSONを取得しています。
この時、phpにパラメータを渡しています。
awaitを使用することでJSONが帰ってくるまで処理をストップしています。
JSONが帰ってきたらforEachを回してDOMを構築します。
DOMの構築が終わったらparamsのoffsetの値を更新します。
PHPの処理
header('Content-Type: application/json; charset=UTF-8');
$offset = isset($_GET['offset']) ? (int)$_GET['offset'] : 0;
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
$apiURL = 'https://jsonplaceholder.typicode.com/posts';
$response = json_decode(file_get_contents($apiURL), true);
if(count($response) < $offset + $limit) {
$limit = count($response) - $offset;
};
$response = array_slice($response, $offset, $limit);
echo json_encode($response);
headerでjsonであること、utf-8であることを宣言しておきます。
$offsetはパラメーターがある場合は整数の型宣言をして格納します。パラメーターがない場合は0が入るようにしています。
$limitはパラメーターがある場合は整数の型宣言をして格納します。パラメーターがない場合は10が入るようにしています。
$apiURLに取得するJSONのURLを格納します。
$responseでjsonを読み込んでデコードしています。
$responseの配列の数が$offsetと$limitを足した数より少ない時は$limitの値を$responseの数から$offsetを引いた数にします。
$responseの配列を$offsetから$limitの数だけ切り取ってjsonに再びエンコードして呼び出します。
まとめ
自分でもぶっちゃけ問題の解決にはなってないと思います。
だってクライアント側には軽いデータ渡ってるけどサーバー側には大きいままのJSONデータそのまま渡ってるんだもん。
サーバーの負荷が心配になる。。
サーバー側で送られてきたJSONをいい感じに分割できればそれが一番いいかもしれません。
