JSON(ジェイソン)とは

JSONはJavaScript Object Notationを短縮した名前です。コンピューターだけではなく人間が読んでも理解することができるだけではなく作成も簡単にできるように考えられたデータフォーマットです。 JSONの作成方法にはルールがありますがJSON自体はただの文字列で、JavaScriptであればJSON.parseで文字列からJavaScriptで扱える形式に変換することができます。

X(旧Twitter), Slackを始め多数のAPIでJSONは利用されています。名前にJavaScriptが入っているので使用できる範囲がJavaScript言語のみという印象を受けるかもしれませんが、実はPHPやRuby, Pythonなど特定のプログラム言語に依存せず利用することすることができます。そのため、JSONの基本を理解し一度処理方法を身につけてしまえば、その知識をさまざまな場所で活用することができます。

本文書ではJSONの構造を理解した後JavaScriptの利用して外部リソースからJSONデータを取得しJSONデータの理解を深めます。Local StorageでもJSONデータを活用できるのでその説明も行っています。さらにPHPを利用して楽天ブックス系APIを利用して実際にJSONを取得します。JSONを知らなかった人もこの例を見ればどのようにJSONが実際の世界で利用されているのか理解することができます。

JSONが使われる理由

JSONが使われる理由は、主に以下の3つの特徴を持っているためです。

  • 読みやすい構造
  • 軽量(必要なデータ以外の不必要なデータを含まないため)
  • プログラミング言語に依存しない

JSONの理解を深めよう

JSONデータとは

JSONのデータはキーと値のペアを持っておりキーと値を使って記述していきます。

下記のシンプルなJSONデータを使って説明を行います。キーにあたるのがfirstName, キーに対する値が五郎となりキーと値のペアは’:’(コロン)を使って区切ります。複数のキーと値を持つ場合は、’,’(コンマ)によってペアを分け、それを{}カーリーブレースで囲めばJSONデータとなります。

JSONはキーも値もダブルクオテーションで囲む必要があります。


{
    "firstName" : "五郎",
    "lastName" : "山下",
    "age" : "22"
};

キーがついていることでその値が何の値なのかをキーの名前から理解することができます。わかりやすいデータ構造をしていることがこの例を見ただけでも理解して頂けるかと思います。何も説明を受けなくてもこのJSONデータを見ただけで名前が山下吾郎で年齢は22歳ということを理解することができます。

JSONデータの型

JSONデータには型というものがあり例えば先ほどの例ではキーも値もすべてダブルクオテーションで囲んでいましたが数値についてはダブルクオテーションを外すと数値の型として認識されます。


{
    "firstName" : "五郎",
    "lastName" : "山下",
    "age" : 22
};

その他ブール型、null型、配列型、オブジェクト型などがあります。ブールはtrue, falseの真偽値のみ設定することができます。nullは値が何も入っていないことを意味し小文字でnullと設定します。下記の例ではある国ではミドルネームがありますが別の国ではミドルネームは存在しないのでmiddleNameにnullを設定しています。


{
    "firstName" : "五郎",
    "lastName" : "山下", //string
    "age" : 22, //number
    "isAdmin" : true, //bool
    "middleName": null, //null
    "color":["red","blue","white"], //配列
  "address":{
       "zip_code": "168-0001",
       "prefecture": "東京"
    }
};

JSONデータへのアクセス方法

JSONデータの形がどのようなものか少しは理解が進んだと思うので実際に動作確認を行います。Node.jsがインストールされ、”node -v”コマンドを実行するとnodeのバージョンが表示される環境です。任意のディレクトリにmain.jsファイルを作成します。

JSONデータはオブジェクトと形は似てますが”文字列”なので下記のように変数に代入することができます。{}で囲んだ外側に`(シングルクオテーション)が入っていることに注意してください。変数に入った文字列のJSONデータはJSON.parseメソッドによってJSONデータからJavaScriptのオブジェクトに変換することができます。オブジェクトなのでプロパティについては.(ドット)を利用してアクセスすることができます。


const json = '{"firstName" : "五郎","lastName" : "山下","age" : "22"}';

const person = JSON.parse(json);

console.log(`その人の名字は:  ${person.firstName}`);
console.log(`年齢は: ${person.age}`);

作成したmain.jsファイルをnodeコマンドで実行します。


% node main.js
その人の名字は:  五郎
年齢は: 22

JSONデータが文字列だということがわからずJSON.parseを実行してJavaScriptのオブジェクトに変更さずに実行してみましょう。undefinedとなります。


const json = '{"firstName" : "五郎","lastName" : "山下","age" : "22"}';

console.log(`その人の名字は:  ${json.firstName}`);
console.log(`年齢は: ${json.age}`);

//結果
その人の名字は:  undefined
年齢は: undefined

型を調べると文字列のstringであることがわかります。


const json = '{"firstName" : "五郎","lastName" : "山下","age" : "22"}';

console.log('jsonの型:', typeof json);

//結果
jsonの型: string

JSON.parseの結果の型も確認しておきましょう。JSON.parseにより文字列からオブジェクトに変換されていることがわかります。


const json = '{"firstName" : "五郎","lastName" : "山下","age" : "22"}';

const person = JSON.parse(json);

console.log('personの型:', typeof person);
//結果
personの型: object

JSONデータ自体は文字列だということをしっかり理解してください。

配列にJSONデータ

JSONデータは配列の一つの要素として保存することもできます。先ほどの変数personを元に配列を作成します。


[{
   "firstName" : "一郎",
   "lastName" : "山下",
   "age" :  "29",
   "height" : "170",
   "weight" : "60"
}]

配列には複数の要素を保存することが可能です。配列を利用すれば、複数のJSONデータを一つの変数として保存することができます。これで3人の兄弟の情報を保存することができます。


[{
   "firstName" : "一郎",
   "lastName" : "山下",
   "age" :  "29",
   "height" : "170",
   "weight" : "60"
},
{
   "firstName" : "三郎",
   "lastName" : "山下",
   "age" :  "27",
   "height" : "176",
   "weight" : "68"
},
{
   "firstName" : "五郎",
   "lastName" : "山下",
   "age" :  "22",
   "height" : "165",
   "weight" : "54"
}];

配列のJSONデータへのアクセス

JSONデータをオブジェクトに変換した後、配列の要素番号を指定してデータにアクセスを行います。配列の各要素には先頭から順番に番号が振られているので、番号を元に配列の要素へのアクセスを行います。

動作確認のコードでは、それぞれの状態における型の確認を行っています。配列の最初の要素の情報を取得したいので、0を指定してアクセスを行います。


const json =
  '[{"firstName" : "一郎","lastName" : "山下","age" :  "29","height" : "170","weight" : "60"}]';

console.log('jsonの型:', typeof json);

const brothers = JSON.parse(json);

console.log('brothersの型:', typeof brothers);
console.log('brothersの型:', Array.isArray(brothers));

console.log('brothers[0]の型', typeof brothers[0]);
console.log('brothers[0]の型:', Array.isArray(brothers[0]));

console.log('長男の名前は:  ' + brothers[0].firstName);
console.log('年齢は: ' + brothers[0].age);
console.log('身長は: ' + brothers[0].height);
console.log('体重は: ' + brothers[0].weight);

実行すると変数jsonに入っているのはJSONデータので型は文字列です。JSON.parseで変換すると型はobjectと表示されていますがArray.isArrayの結果はtrueになっているので配列であることがわかります。brothersは配列なのでbrothers[0]でアクセスでき、その型はobjectであることがわかります。


 % node main.js
jsonの型: string
brothersの型: object
brothersの型: true
brothers[0]の型 object
brothers[0]の型: false
長男の名前は:  一郎
年齢は: 29
身長は: 170

配列にループ処理を行い、JSONデータにアクセス

配列に保存されたデータはJSON.parseによりオブジェクトに変換された後でforを使ってループ処理を行い配列の全要素のデータにアクセスを行うことができます。


let json =
  '[{"firstName" : "一郎","lastName" : "山下","age" :  "29","height" : "170","weight" : "60"},{"firstName" : "三郎","lastName" : "山下","age" :  "27","height" : "176","weight" : "68"},{"firstName" : "五郎","lastName" : "山下","age" :  "22","height" : "165","weight" : "34"}]';

let brothers = JSON.parse(json);

for (i in brothers) {
  console.log('名前は:  ' + brothers[i].firstName);
  console.log('年齢は: ' + brothers[i].age);
  console.log('身長は: ' + brothers[i].height);
  console.log('体重は: ' + brothers[i].weight);
}

配列は3つの要素から構成されていたので、ループ処理により3つの要素のJSONデータにアクセスできていることを確認することができます。


% node test.js
名前は:  一郎
年齢は: 29
身長は: 170
体重は: 60

名前は:  三郎
年齢は: 27
身長は: 176
体重は: 68

名前は:  五郎
年齢は: 22
身長は: 165
体重は: 34

ネストされたJSONデータ

これまで扱ったJSONデータは、1つのキーに対して1つの値を設定していましたが、今回は、1つのキーに対して1つの値ではなくさらにJSONデータを割り当てます。JSONデータの中にまたJSONデータが入っている構造です。その構造のことをネストされた構造と呼びます。

下記がネストされたJSONデータです。


{
  "ichiro" : {
   "age" :  "29",
   "height" : "170",
   "weight" : "60"
},
"saburo" : {
   "age" :  "27",
   "height" : "176",
   "weight" : "68"
},
"goro" : {
   "age" :  "22",
   "height" : "165",
   "weight" : "54"
}}

ネストされたJSONデータへのアクセス

配列の場合はオブジェクトに変換後に配列の要素にアクセスする場合は番号を指定していましたが、Jネスト化されている場合はキーを指定することができます。JSONのデータ構造がわかっていれば、配列よりもわかりやすくデータに対してアクセスを行うことができます。


const json =
  '{"ichiro" : {"age" :  "29","height" : "170","weight" : "60"},"saburo" : {"age" :  "27","height" : "176","weight" : "68"},"goro" : {"age" :  "22","height" : "165","weight" : "54"}}';

console.log('jsonの型は:', typeof json);
const brothers = JSON.parse(json);

console.log('年齢は: ' + brothers.saburo.age);
console.log('身長は: ' + brothers.saburo.height);
console.log('体重は: ' + brothers.saburo.weight);

実行するとネストされたデータにアクセスすることができます。ここまでくると当たり前ですがJSONデータの型は文字列(string)です。


% node test.js
jsonの型は: string
年齢は: 27
身長は: 176
体重は: 68
さらにageキーに対してもJSONデータを割り当てることができるためネストは何階層にも行うことができます。
fukidashi

ネストされたJSONデータを配列に保存する

ネストされたJSONデータを配列に保存することもできます。


[
  {
    "ichiro": {
      "name": "一郎",
      "age": "29",
      "height": "170",
      "weight": "60"
    }
  },
  {
    "saburo": {
      "name": "三郎",
      "age": "27",
      "height": "176",
      "weight": "68"
    }
  },
  {
    "goro": {
      "name": "五郎",
      "age": "22",
      "height": "165",
      "weight": "54"
    }
  }
]

アクセスは配列の番号を使用して行います。


let json =
  '[{"ichiro" : {"name": "一郎","age" :  "29","height" : "170","weight" : "60"}},{"saburo" : {"name": "三郎","age" :  "27","height" : "176","weight" : "68"}},{"goro" : {"name": "五郎","age" :  "22","height" : "165","weight" : "54"}}]';

let brothers = JSON.parse(json);

console.log('brothersの型:', typeof brothers);
console.log('brothersの型:', Array.isArray(brothers));

console.log('二男の名前は:  ' + brothers[1].saburo.name);
console.log('年齢は: ' + brothers[1].saburo.age);
console.log('身長は: ' + brothers[1].saburo.height);
console.log('体重は: ' + brothers[1].saburo.weight);

//結果
brothersの型: object
brothersの型: true
二男の名前は:  三郎
年齢は: 27
身長は: 176
体重は: 68

テンプレートリテラルの利用

JSONデータを文字列で設定するためデータが多くなると先ほどの例のようにデータの見栄えが悪くなります。その場合はテンプレートリテラルを利用します。'(シングルクオテーション)から`(バッククオテーション)に変更します。


const json = `[{
  "firstName" : "一郎",
  "lastName" : "山下",
  "age" :  "29",
  "height" : "170",
  "weight" : "60"
},
{
  "firstName" : "三郎",
  "lastName" : "山下",
  "age" :  "27",
  "height" : "176",
  "weight" : "68"
},
{
  "firstName" : "五郎",
  "lastName" : "山下",
  "age" :  "22",
  "height" : "165",
  "weight" : "54"
}]`;

const brothers = JSON.parse(json);

for (i in brothers) {
  console.log('名前は:  ' + brothers[i].firstName);
  console.log('年齢は: ' + brothers[i].age);
  console.log('身長は: ' + brothers[i].height);
  console.log('体重は: ' + brothers[i].weight);
}

console.logの引数もテンプレートリテラルで変更できます。


for (i in brothers) {
  console.log(`名前は:  ${brothers[i].firstName}`);
  console.log(`年齢は:  ${brothers[i].age}`);
  console.log(`身長は:  ${brothers[i].height}`);
  console.log(`体重は: ${brothers[i].weight}`);
}

オブジェクトをJSONに変換する

ここまではJSONデータをJSON.parseを利用してオブジェクトに変換してJSONデータのキーや値にアクセスを行なってきましたが今後は逆にオブジェクトからJSONデータに変換します。

JavaScritpのオブジェクトからJSONデータへの変化はJSON.stringify()を利用します。JavaScriptのオブジェクトをJSONデータ(文字列)に変換する際にはシリアライズするといいます。


const person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
};

console.log(JSON.stringify(person));

//結果
{"firstName":"五郎","lastName":"山下","age":"22"}

変換されたJSONデータは文字列なのでtypeofを利用することで’string’が表示されます。元のpersonの型はobjectです。


const person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
};

console.log('personの型: ', typeof person);

const json = JSON.stringify(person);

console.log('jsonの型: ', typeof json);

console.log(json);

//結果
personの型:  object
jsonの型:  string
{"firstName":"五郎","lastName":"山下","age":"22"}

オブジェクトからJSONに変換(JSON.stringify)し再度オブジェクトに戻す(JSON.parse)こともできます。コンソールに表示される内容を見るとJSONデータとオブジェクトで表示が異なっていることがわかります。


let person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
};

console.log(JSON.stringify(person));
const json = JSON.stringify(person);
console.log(JSON.parse(json));
//
{"firstName":"五郎","lastName":"山下","age":"22"} //JSON
{ firstName: '五郎', lastName: '山下', age: '22' } //オブジェクト

実行するとJSON.stringifyで変換したJSONはfirsNameやlastName, ageに””(ダブルクオテーション)がついていますがJSONデータをJSON.parseしたJavaScriptオブジェクトにはついていません。


{"firstName":"五郎","lastName":"山下","age":"22"} //JSON
{ firstName: '五郎', lastName: '山下', age: '22' } //オブジェクト

JSONデータは文字列なのでfirstNameにアクセスしていもundefinedとなりますがオブジェクトの場合はプロパティにアクセスを行うことができます。


let person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
};

const json = JSON.stringify(person);
const obj = JSON.parse(json);

console.log(json.firstName);
console.log(obj.firstName);
//
undefined
五郎

関数を持つオブジェクトでstringify

JavaScriptのオブジェクトでは関数を持つことができるので関数を持つオブジェクトに対してJSON.stringifyを実行した場合にどのように変換されるか確認します。

関数greetingを持つpersonを定義します。問題なくperson.greetingが実行され”Hello”が表示されます。


const person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
  greeting: () => {
    console.log('Hello');
  },
};

person.greeting();
//Hello

関数を含むpsersonオブジェクトをJSON.stringifyを実行すると関数はJSONデータには含まれないことがわかります。つまり、関数はJSONに変換されず、結果の文字列には含まれません。


const person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
  greeting: () => {
    console.log('Hello');
  },
};

const json = JSON.stringify(person);

console.log(json);
//結果
{"firstName":"五郎","lastName":"山下","age":"22"}

では関数を持ったオブジェクトをJSONデータに保存することはできないのでしょうか?下記のコードのように一度関数を文字列として保存しJSON.parseでJavaScriptに戻す際に文字列から関数に戻すことで保存することは可能です。


const person = {
  firstName: '五郎',
  lastName: '山下',
  age: '22',
  greeting: function () {
    console.log('Hello');
  },
};

const json = JSON.stringify(person, (key, value) => {
  if (typeof value === 'function') {
    return value.toString();
  }
  return value;
});

console.log(json);

const parsedPerson = JSON.parse(json, (key, value) => {
  if (typeof value === 'string' && value.startsWith('function')) {
    return new Function('return ' + value)();
  }
  return value;
});

console.log(parsedPerson);
parsedPerson.greeting(); 

JSONをさらに理解する

ここまでの確認でJSONデータがどのようなデータ形式を持っておりJSON.parse, JSON.stringifyなどを利用することでオブジェクトへの変換、オブジェクトからの変換を理解することができました。JSONデータは外部リソースからデータを取得する際に利用することができるので無料のサービスであるJSONPlaceHolderを利用してJSONデータを外部から取得してみましょう。

JSONPlaceHolderが提供しているURLにアクセスするだけでJSONデータを取得することができます。

ブラウザはFirefoxを利用しておりURLにhttps://jsonplaceholder.typicode.com/users/1を入力すると画面に取得したデータが表示されます。綺麗に整形されているのでこれがJSONデータかどうかわからないのですが、上部にあるJSONタブをRaw Dataタグに変更するためクリックしてください。

JSONデータをFirefoxで確認
JSONデータをFirefoxで確認

本文書で見られたJSONデータの形式であるキーとバリューでキーはダブルクオテーションされていることが確認できます。

JSON Raw Dataの確認
JSON Raw Dataの確認

Headersタグを見るとcontent-typeがapplication/json; charset=utf-8であることも確認できます。

XMLHTTPRequestを利用

XMLHTTPRequestを利用してJSONデータを取得してみましょう。fetch関数やaxiosを利用してのでXMLHTTPRequestの処理を忘れたという人も多いとは思いますが(2)の下にあるthis.responseTextの中に戻り値のJSONデータが保存されます。任意のフォルダにindex.htmlファイルを作成して以下を記述してください。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>JSON</title>
  </head>
  <body>
    <script>
      // (1)XMLHttpRequestオブジェクトを作成
      var xmlHttpRequest = new XMLHttpRequest();

      // (2)onreadystatechangeイベントで処理の状況変化を監視
      xmlHttpRequest.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
          console.log(this.responseText);
        }
      };

      // (3)HTTPのGETメソッドとアクセスする場所を指定
      xmlHttpRequest.open(
        'GET',
        'https://jsonplaceholder.typicode.com/users/1',
        true
      );

      // (4)HTTPリクエストを送信
      xmlHttpRequest.send();
    </script>
  </body>
</html>

デベロッパーツールのコンソールを確認するとJSONデータを確認することができます。

JSONデータの確認
JSONデータの確認

データを取得できたのでオブジェクトのようにアクセスできるのではと思う人もいるかと思います。しかしJSONデータは文字列なのでこれまでに学んだ通りそのままではキーの値にアクセスすることができます。

JSONデータが文字列かどうかはtypeof演算子で確認できます。


console.log(typeof this.responseText);
//
string

ここでJSON.parseを利用してオブジェクトに変更することでプロパティへのアクセスが可能となります。


xmlHttpRequest.onreadystatechange = function () {
  if (this.readyState == 4 && this.status == 200) {
    const json = JSON.parse(this.responseText);
    console.log(json);
  }
};

コンソールに表示される情報もオブジェクトに変わっていることがわかります。

JSONデータからオブジェクトへ
JSONデータからオブジェクトへ

parseによって作成したオブジェクトであればプロパティにアクセスすることができます。


const json = JSON.parse(this.responseText);
console.log(json.name);
//
Leanne Graham

axiosを利用した場合

axiosを利用してデータの取得を行いJSONデータがどのように扱われているのか確認していみましょう。axiosはcdnを利用しています。取得したデータはreponseの中に入っているのでconsole.logで中身を確認します。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>JSON</title>
    <script>
      src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.26.0/axios.min.js"
      integrity="sha512-bPh3uwgU5qEMipS/VOmRqynnMXGGSRv+72H/N260MQeXZIK4PG48401Bsby9Nq5P5fz7hy5UGNmC/W1Z51h2GQ=="
      crossorigin="anonymous"
      referrerpolicy="no-referrer"
    ></script>
  </head>
  <body>
    <script>>
      axios
        .get('https://jsonplaceholder.typicode.com/users/1')
        .then((response) => console.log(response));
    </script>
  </body>
</html>

axiosの場合は下記にあるようにJSONデータからオブジェクトへの変換が行われているのでキーやバリューに対するダブルクオテーションを見つけることができません。JSONデータからオブジェクトへの変換という作業がないため便利にはなっていますがJSONデータがどのようなものか意識する必要がないためJSONデータがどのようなものなのかという知識は得られないかもしれません。

axiosによるデータの確認
axiosによるデータの確認

fetch関数を利用した場合

fetch関数を利用してデータの取得を行いJSONデータがどのように扱われているのか確認していみましょう。以下のコードを実行するとdataにはオブジェクトが入っているためオブジェクトとして表示されます。


fetch('https://jsonplaceholder.typicode.com/users/1')
  .then((response) => response.json())
  .then((data) => console.log(data));
JSONデータからオブジェクトへ
JSONデータからオブジェクトへ

fetch関数の場合はresponseの中のbodyに取得したデータが含まれていますが直接アクセスしてデータを取得することができません。その代わりresponse.json()を実行することでJSONデータではなくオブジェクトへの変換が完了したデータを取得することができます。json()となっているのでJSONデータではなくJavaScriptのオブジェクトであることに注意が必要です。直接ではありまっせんがresponse.text()を実行するとJSONデータとして取得することはできます。axiosと同様にfetch関数でも処理の流れの中でJSONデータを直接確認することはありません。

XMLHTTPRequest、axios、fetch関数を通して外部リソースからJSONデータを取得してJavaScriptのコードで利用するためには取得したJSONデータを必ずparseしてオブジェクトに変換する必要があることがわかりました。

JSON実践(Local Storage)

ブラウザ上にデータを保存する際にLocal Storageを利用することができますがLocal Storageにデータを保存する際にJSONデータを利用することができます。

ローカルストレージの基礎

local Storageにデータを保存したい場合にはsetItemメソッドを利用して第一引数にキー、第2引数に値を設定します。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>JSON</title>
  </head>
  <body>
    <script>
      localStorage.setItem('name', 'John Doe');
    </script>
  </body>
</html>

ブラウザのデベロッパーツールのアプリケーションタグを確認するとローカルストレージの中にキーがnameで値がJohn Doeのデータを見つけることができます。

ローカルストレージの確認
ローカルストレージの確認

localStorage.setItem('name', 'John Doe');
console.log(localStorage.getItem('name'));
//
John Doe

この値を取得したい場合はgetItemメソッドでキーを取得することで確認することができます。

ローカルストレージはブラウザをリロードしても値が消えることはありません。削除はclearメソッドまたはremoveItemメソッドで行うことができます。

clearメソッドではローカルストレージに保存されているすべてのキー・バリューペアが削除されます。


localStorage.setItem('name', 'John Doe');
localStorage.setItem('id', 1);
localStorage.removeItem('id');
console.log(localStorage.getItem('name'));
console.log(localStorage.getItem('id'));
//
null

removeItemメソッドでは指定したキーのみ削除することができます。


localStorage.setItem('name', 'John Doe');
localStorage.setItem('id', 1);
localStorage.removeItem('name');
console.log(localStorage.getItem('name'));
console.log(localStorage.getItem('id'));
//
null
1

オブジェクトを保存

ローカルストレージへの文字列と数値の保存は問題なく行うことができました。次はオブジェクトを保存してみましょう。


const user = {
  name: 'John Doe',
  age: 20,
};

localStorage.setItem('user', user);

ブラウザのローカルストレージを確認すると[Object, Object]と表示されています。

オブジェクトを保存した場合
オブジェクトを保存した場合

getItemメソッドを利用して保存したuserを取得しても同じように[object Object]が表示されます。


const user = {
  name: 'John Doe',
  age: 20,
};

localStorage.setItem('user', user);
console.log(localStorage.getItem('user'));
//
[object Object]

現在はローカルストーレージには文字列しか保存することができないためです。

この問題を解決するためにオブジェクトデータはJSONデータに変換でき、JSONデータは文字列だということを思い出してください。

JSON.stringifyによってオブジェクトをJSONデータに変換します。


localStorage.setItem('user', JSON.stringify(user));

ブラウザのアプリケーションを確認すると[object Object]の形ではなくJSONデータとして保存されていることがわかります。キーにダブルクオテーションがついておりJavaScriptのオブジェクトではないことがわかります。これをJavaScriptのオブジェクトだと思う人はまだJSONデータとオブジェクトの違いが理解できていないかもしれません。

値がJSONデータで保存
値がJSONデータで保存

今度はgetItemで保存したデータを取り出します。JSONデータであることがわかります。


localStorage.setItem('user', JSON.stringify(user));
console.log(localStorage.getItem('user'));
//
{"name":"John Doe","age":20}

typeof演算子で型を確認するとJSONデータなのでstringになります。


console.log(typeof localStorage.getItem('user'));
//
string

JSONデータから下記のようにnameを取得しようとしないでください。文字列なのでnameにアクセスすることはできません。


localStorage.setItem('user', JSON.stringify(user));

const json = localStorage.getItem('user');

console.log(json.name);
//
undefined

ではnameの値を取得するのはどのように行うのでしょうか?JSON.parseを利用します。今回はJSONデータからオブジェクトへ変換します。オブジェクトに変換後はnameプロパティへのアクセスが可能になります。


localStorage.setItem('user', JSON.stringify(user));

const obj = JSON.parse(localStorage.getItem('user'));

console.log(obj.name);
//
John Doe

このようにローカルストレージを利用する場合はJSONデータを活用することでオブジェクトデータをJSONデータで保存して取り出す時にはJSONデータをオブジェクトに変換することでローカルストレージを活用することができます。オブジェクトだけではなく配列も同じ方法でJSONデータとして保存することができます。

JSON実践(PHP編)

楽天ブックス系APIを利用してJSONデータを取得してみよう

ここまでの説明でJSONデータの基本を理解したので実際にAPIを使用してJSONデータの取得を行ってみます。

楽天市場のAPIを利用するためには、事前に楽天ウェブサービスから登録を行いアプリID/デベロッパーIDを取得する必要があります。

APIを使用して楽天ブックスで扱う洋書の中で、タイトルにPHPを含む書籍のJSONデータを取得します。APIのパラメータ等の詳細は、楽天ブックス洋書検索APIから確認して下さい

必須パラメータのappkicationIdに取得したアプリID、titleパラメータにPHPを入力します。下記の入力した文字列をブラウザのアドレスバーに入れて情報を取得します。


https://app.rakuten.co.jp/services/api/BooksForeignBook/Search/20170404??applicationId=XXX&title=PHP

ブラウザ上にはAPIから取得したデータが出力されますが、取得したJSONデータは、キーと値のペア、また配列とネストされたJSONデータで構成されています。本文書でJSONデータの扱い方を理解していれば、取得したデータの読み方もわかるかと思います。


{"count":19,"page":1,"first":1,"last":19,"hits":19,"carrier":0,"pageCount":1,"Items":[{"Item":{"title":"PHP: 20 Lessons to Successful Web Development","titleKana":"","japaneseTitle":"PHP: 20 Lessons to Successful Web Development","author":"Robin Nixon":......

URLの指定等が誤っている場合、エラーもJSONで戻されます。


{"error":"wrong_parameter","error_description":"BooksBook/Search doesn't have version 23456"}

JSONデータをPHPで処理する

JSONデータはプログラム言語に依存しないという特徴を持っているのでさまざなな言語で処理を行うことができますが、ここではPHPを使ったJSONデータの扱い方について説明します。

JSONデータは、楽天APIを使用して取得したものを使用します。


$url = 'https://app.rakuten.co.jp/services/api/BooksForeignBook/Search/20170404?applicationId=XXX&title=PHP';

$json_book_data = file_get_contents($url,true);

JSONデータは文字列なのでそのまま扱うことができないのでjson_decodeを利用してJSONデータを配列に変換します。


$array_book_data = json_decode($json_data,true);

json_decodeでJSONデータを配列にすると下記のようになります。


array:9 [▼
  "count" => 19
  "page" => 1
  "first" => 1
  "last" => 19
  "hits" => 19
  "carrier" => 0
  "pageCount" => 1
  "Items" => array:19 [▼
    0 => array:1 [▼
      "Item" => array:24 [▼
        "title" => "PHP: 20 Lessons to Successful Web Development"
        "titleKana" => ""
        "japaneseTitle" => "PHP: 20 Lessons to Successful Web Development"
        "author" => "Robin Nixon"
        ・
        ・
      ]
    ]
    1 => array:1 [▼
      "Item" => array:24 [▼
        "title" => "PHP for the Web: Visual QuickStart Guide【バーゲンブック】"
        "titleKana" => ""
        "japaneseTitle" => "PHP for the Web: Visual QuickStart Guide【バーゲンブック】"
        "author" => "Larry Ullman"
        ・
        ・
    2 => array:1 [▶]
    ・
    ・

  ]
  "GenreInformation" => []
]

PHPの本のタイトルだけ確認したい場合は配列の構造を確認しforeachのループ処理で本のタイトルだけ出力させることが可能です。


foreach ($array_book_data['Items'] as $item){
             echo $item['Item']['title'].'
'; }

PHP: 20 Lessons to Successful Web Development
PHP for the Web: Visual QuickStart Guide【バーゲンブック】
Murach's PHP and MySQL (2nd Edition)
PHP Quick Scripting Reference
Effortless E-Commerce with PHP and MySQL
PHP and MySQL in Easy Steps
   ・
   ・

まとめ

JSONの基礎から実践まで一通り説明しました。特に基礎を理解していれば、APIで取得したJSONデータも比較的簡単に読むことができたかと思います。少しでもJSONデータを身近に感じてもらったと思うので、JSONの理解があいまいだった人もこれを機にJSONデータを活用してください。