【Ruby】JSON形式のデータをRubyで扱う方法とは?

Ruby

Rubyでは、JSONモジュールを利用することでJSON文字列をHashへ変換したり、HashからJSON文字列に変換する事が出来ます。

以下のように、irbでJSONモジュールを使って、JSON文字列をハッシュに変換したり、ハッシュをJSON文字列に変換する事が出来ます。

irb | JSON文字列とハッシュの変換方法
1
2
3
4
5
6
7
8
9
irb(main):001:0> require "json" # JSONモジュールを利用する

# JSON文字列をハッシュへ変換
irb(main):002:0> JSON.parse('{"id": 1, "first_name": "Taro", "last_name": "Suzuki", "age": 25}')
=> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25}

# ハッシュをJSON文字列に変換
irb(main):003:0> JSON.generate({"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25})
=> "{\"id\":1,\"first_name\":\"Taro\",\"last_name\":\"Suzuki\",\"age\":25}"

JSON文字列やハッシュを変換する操作は、WebAPIでのデータ交換の際によく利用される方法です。

JSONファイルを取り扱う方法

JSONファイルをRubyで扱う場合は、JSONをHashオブジェクトに変換する必要があります。

JSON | ユーザー情報を記載するJSONファイル
1
2
3
4
5
6
{  
    "id": 1,
    "first_name": "Taro",
    "last_name": "Suzuki",
    "age": 25
}

上記のJSONファイルを以下のように、Hashに変換してRubyで扱えるようにするために、JSONファイルをRubyで読み込む方法、書き出す方法を学んでいきます。

irb | JSONファイルの内容をHashオブジェクトに変換
1
irb(main):001:0>  {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25}

JSONが良く分からないという方は、ゼロから始めるJSON入門を参考にして下さい。

読み込み
リンクをコピーしました

JSONファイルを読み込んでJSON形式の文字列をHashに変換するには、以下のようにFile.openメソッドとJSON.loadメソッドを使います。

irb | JSONファイルを読み込んでJSON形式の文字列をHashに変換する方法
1
2
3
4
5
irb(main):001:0> require "json" # JSONモジュールを利用する
irb(main):002:0>File.open("ファイルの保存場所") do |file| # ファイル開いて読み込みモードへ
irb(main):003:1*>  hash = JSON.load(fileオブジェクト) # Hashに変換する
irb(main):004:1>  # 処理
irb(main):005:1>end

それでは、JSONファイルの読み込み手順について確認していきましょう。

JSONファイルの読み込み手順
リンクをコピーしました

JSONファイルの読み込みには、以下のファイルを使って解説します。
まずは、このファイルにsample.jsonと名前を付けて、~/Desktop以下に配置します。

~/Desktop/sample.json | ユーザー情報を記載するJSONファイル
1
2
3
4
5
6
{  
    "id": 1,
    "first_name": "Taro",
    "last_name": "Suzuki",
    "age": 25
}

そして、作業ディレクトリを~/Desktopに移動させてからirbを起動させます。

ターミナル | 作業ディレクトリをDesktopへ移動させてからirbを起動する
1
2
cd ~/Desktop 
irb  # Desktopでirbを起動させる

また、irbの起動後に以下を実行する事で、JSONモジュールを利用出来るようにします。

irb | JSONモジュールを利用出来るようにする
1
2
irb(main):001:0> require "json"
=> true

作業ディレクトリをDesktopにしてirbを起動すると、以下のようにファイルの保存場所を絶対パスだけではなく、./sample.jsonのように相対パスで指定が出来ます。(これ以降は、相対パスを使います。)

irb | File.openのファイルの保存場所の指定の方法
1
2
3
4
5
6
# File.open("ファイルの保存場所") 
irb(main):001:0>File.open("/Users/ユーザー名/Desktop/sample.json") # 絶対パスで指定
=> #<File:./sample.json>

irb(main):002:0>File.open("./sample.json") # 相対パスで指定
=> #<File:./sample.json>

また、File.open()は、引数に指定したファイルを開いてくれるだけではなく、ファイルオブジェクトを生成して返します。

このファイルオブジェクトをブロックでJSON.load()に渡す事で、JSONファイルをRubyで扱えるHashに変換する事が出来ます。

irb | JSONファイルを読み込んでRubyのHashに変換する
1
2
3
4
irb(main):002:0>File.open("./sample.json") do |file| 
irb(main):003:1*>  hash = JSON.load(file) # Hashに変換
irb(main):004:1>  p hash
irb(main):005:1>end

上記を実行すると、以下のようにJSON文字列をHashに変換することが出来ています。

irb | サンプルコードの実行結果
1
2
{"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25} # p hashの処理結果
=> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25} # 返り値

このようにFile.open()JSON.load()を使うことで、JSONファイルを読み込んでJSON文字列をHashに変換させる事が出来ます。

書き出し
リンクをコピーしました

HashをJSON文字列に変換して、JSONファイルに書き出すには、以下のようにFile.open()JSON.dump()を使います。

irb | HashをJSON文字列に変換してJSONファイルに書き出す方法
1
2
3
4
irb(main):001:0> require 'json' # JSONモジュールを使う
irb(main):002:0> File.open("ファイルの保存場所", 'w') do |file| # ファイルを開いて書き出しモードへ
irb(main):003:0> str = JSON.dump(ファイルに書き出すHash, fileオブジェクト) # JSON文字列に変換する
irb(main):004:0> end

それでは、HashをJSONファイルに書き出す手順について確認していきましょう。

JSONファイルに書き出す手順
リンクをコピーしました

それでは、以下のHashをJSON文字列に変換してexample.jsonファイルに書き出す手順を解説します。

JSONファイルに書き出すHash
1
{"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25} 

まず、作業ディレクトリを~/Desktopに移動させてからirbを起動させます。

ターミナル | 作業ディレクトリをDesktopへ移動させてからirbを起動する
1
2
cd ~/Desktop 
irb  # Desktopでirbを起動させる

また、irbの起動後に以下を実行する事で、JSONモジュールを利用出来るようにします。

irb | JSONモジュールを利用出来るようにする
1
2
irb(main):001:0> require "json"
=> true

ファイルの書き出しは、File.open()を以下のように記述することで書き込みモードでファイルを開くことが出来ます。

書き込みモードでファイルを開く
1
File.open("ファイル保存場所", "w")

Pikawakaマーク書き込みモードにする時のポイント

File.open()の第一引数のファイルが既に存在する場合は、ファイルの中身を空にして開きます。そして、ファイルが存在しなければ、ファイルを開くと同時に作成します。

作業ディレクトリをDesktopにしてirbを起動したので、以下のようにファイルの保存場所を相対パスで./example.jsonと指定すると、Desktop以下にexample.jsonを作成することが出来ます。

irb | example.jsonにハッシュを書き出す方法
1
2
3
4
5
irb(main):002:0> File.open("./example.json", 'w') do |file| # ファイルをDesktop以下に開いて作成する
irb(main):003:0> str = JSON.dump({"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25} , file)
irb(main):004:0>  end

=> #<File:./example.json (closed)> # 書き込みが終わりファイルが閉じられる

そして、ブロック内のJSON.dump()に「JSONファイルに書き出すHash」と「ファイルオブジェクト」を渡します。Hashは、JSON文字列に変換されてJSONファイルに書き出されます。

ターミナル | example.jsonの中身を確認する
1
2
3
cd ~/Desktop
cat example.json # ファイルの中身を確認
{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25} # ファイルの中身

上記のようにDesktop以下に作成されたexample.jsonファイルを開くと、Hashで渡したデータをJSON文字列に変換されてファイルに書き出すことが出来ています。

JSON形式の文字列とRubyのHashへの変換方法

この章では、「JSON形式の文字列からRubyのHash」や「RubyのHashからJSON形式の文字列」に変換する方法を解説します。

JSON形式の文字列からRubyのHashへ変換する
リンクをコピーしました

JSON形式の文字列からRubyのHashに変換は、JSONモジュールのJSON.parseを使います。

以下のようにJSON.parse()にJSON文字列を渡すことでRubyのHashに変換することが出来ます。

irb |JSON形式の文字列をRubyのHashに変換する
1
2
3
4
5
6
7
8
irb(main):001:0> require "json" # JSONモジュールを使える様にする
=> true

# 引数の一番外側の引用符は、シングルクォーテーションにすること!
irb(main):002:0> JSON.parse('{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25}')

# デフォルトではキー名が文字列になって返る
=> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25}

そして、RubyのHashに変換したデータは、以下のようにhash["キー名"]で取り出すことが出来ます。

irb |RubyのHashに変換したデータを取り出す方法
1
2
3
4
5
irb(main):002:0> hash = JSON.parse('{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25}')
=> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25}

irb(main):003:0> hash["first_name"]
=> "Taro"

JSON.parseは、WebAPIで取得したJSONデータをRubyで使える様にするといった場面で利用されます。

変換するHashのキー名をシンボルに指定
リンクをコピーしました

JSON.parse()で変換したHashのキー名はデフォルトで文字列になります。文字列ではなく、シンボルにするには、以下のように第二引数にsymbolize_names: trueを渡します。

irb | Hashのキー名を文字列ではなくシンボルに指定する場合
1
2
3
4
5
6
7
# デフォルトの場合
irb(main):002:0> hash = JSON.parse('{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25}')
=> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25} # キー名が文字列

# 第二引数に`symbolize_names: true`を渡した場合
irb(main):003:0> JSON.parse('{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25}', symbolize_names: true)
=> {:id=>1, :first_name=>"Taro", :last_name=>"Suzuki", :age=>25} # キー名がシンボル

また、キー名がシンボルのHashは、以下のようにhash[: first_name]で取り出すことが出来ます。

irb | キー名をシンボルで指定して取得する
1
2
3
4
5
irb(main):003:0> hash = JSON.parse('{"id":1,"first_name":"Taro","last_name":"Suzuki","age":25}', symbolize_names: true)
=> {:id=>1, :first_name=>"Taro", :last_name=>"Suzuki", :age=>25} # キー名がシンボル

irb(main):004:0> hash[:first_name] # キー名をシンボルで指定
=> "Taro"

RubyのHashからJSON形式の文字列へ変換する
リンクをコピーしました

RubyのHashからJSON形式の文字列への変換は、JSONモジュールの JSON.generateとRubyの配列とHashのメソッドであるto_jsonを使います。

to_jsonメソッドで変換する
リンクをコピーしました

to_jsonメソッドは配列Hashのメソッドで、配列やHashをJSON形式の文字列に変換します。

irb | 配列とHashをJSON形式のデータに変換する
1
2
3
4
5
6
7
 # 配列.to_json
irb(main):001:0>  [2, 5, 7].to_json
=> "[2,5,7]"

 # Hash.to_json
irb(main):002:0> {"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25}.to_json
=> "{\"id\":1,\"first_name\":\"Taro\",\"last_name\":\"Suzuki\",\"age\":25}"

また、以下のようにArray.methodsHash.methodsを実行すると、配列やHashで使えるメソッドが分かります。

配列のto_jsonメソッドをmethodsで確認

JSON.generateメソッドで変換する
リンクをコピーしました

JSON.generateは、引数に渡したRubyのHashをJSON形式の文字列に1行で変換して返します。

to_jsonメソッドと違い、JSONモジュールを使用できる様にする為にrequire "json"を実行する必要があります。

irb | JSONモジュールを使える様にする
1
2
irb(main):001:0>  require "json"
=> true

そして、以下のように記述することでHashをJSON文字列に変換することが出来ます。

irb | HashをJSON文字列に変換する
1
2
irb(main):001:0> JSON.generate("id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25)
=> "{\"id\":1,\"first_name\":\"Taro\",\"last_name\":\"Suzuki\",\"age\":25}"

JSON文字列にインデントを付けて変換する方法
リンクをコピーしました

RubyのHashからJSON形式の文字列に変換する際に、JSON.generate()ではなくJSON.pretty_generate()を使うと、インデントを整形して変換します。

JSON.generateでJSON形式の文字列に変換した場合
1
2
irb(main):001:0> JSON.generate("id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25)
=> "{\"id\":1,\"first_name\":\"Taro\",\"last_name\":\"Suzuki\",\"age\":25}"
JSON.pretty_generateでJSON形式の文字列に変換した場合
1
2
3
4
5
6
7
8
9
irb(main):032:0> JSON.pretty_generate({"id"=>1, "first_name"=>"Taro", "last_name"=>"Suzuki", "age"=>25})
=> "{\n  \"id\": 1,\n  \"first_name\": \"Taro\",\n  \"last_name\": \"Suzuki\",\n  \"age\": 25\n}"

# => {
#      "id": 1,
#      "first_name": "Taro",
#       "last_name": "Suzuki",
#       "age": 25
#    }

Web APIのJSONデータの操作方法

この章では、Web APIを利用してJSONデータを取得し、表示する手順を解説します。

Web APIからJSON形式のデータを取得する
リンクをコピーしました

Web APIとは、外部のWebアプリケーション等が公開している情報を呼び出して、利用する仕組みのことです。やり取りされるデータ形式はXMLJSONなどがあります。

今回は、ダミーのユーザー情報をAPIとして提供する「RANDOM USER GENERATOR」を使います。

curlコマンドでWeb APIを叩こう
リンクをコピーしました

まずは、簡単にHTTPリクエストが出来るcurlコマンドでランダムにダミーのユーザーを取得できる「RANDOM USER GENERATOR」のapiを叩いて、どの様に取得出来るのかを確認していきましょう。

ターミナル | curlコマンドでWeb APIを叩く
1
curl https://randomuser.me/api\?callback\=jsonData

上記をターミナルで実行すると、以下のようにユーザー情報がJSON形式で取得する事が出来ます。

ターミナル | Web APIを叩いた結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
  "results": [
    {
      "gender": "female",
      "name": {
        "title": "Miss",
        "first": "Addison",
        "last": "Cooper"
      },
      "location": {
        "street": {
          "number": 1637,
          "name": "Collingwood Street"
        },
        "city": "Dunedin",
        "state": "Wellington",
        "country": "New Zealand",
        "postcode": 22975,
        "coordinates": {
          "latitude": "68.4100",
          "longitude": "48.0519"
        },# 以下省略

今回は、curlコマンドをコマンドを使いましたが、ブラウザのアドレスバーにhttps://randomuser.me/api\?callback\=jsonDataを入れて実行すると、以下のように情報を表示する事も出来ます。

ブラウザでapiの情報を確認

本来、URIはhttps://randomuser.me/apiですが、ここではJSON形式のデータで取得する為にhttps://randomuser.me/api\?callback\=jsonDataにしてあります。

RubyでWeb APIのデータを取得する
リンクをコピーしました

次はcurlではなくRubyを使って、ランダムにダミーのユーザーを取得できる「RANDOM USER GENERATOR」apiを叩く方法について解説します。

まずは、irbをターミナルで起動します。

ターミナル | irbを起動する
1
2
$ irb
irb(main):001:0>

次に、JSONモジュールを扱う為にrequire "json" を実行しますが、それ以外にもHTTPを扱う為のライブラリやURIを扱うモジュールを使う為に下記を実行します。

irb | モジュールやライブラリを使う
1
2
3
4
5
6
irb(main):001:0> require 'uri' # URIモジュールを利用する 
=> true 
irb(main):002:0> require 'net/http' # HTTPを扱う為のライブラリ
=> true
irb(main):003:0> require 'json' # JSONモジュールを利用する 
=> true

そして、「RANDOM USER GENERATOR」のダミーのユーザー情報を取得する為に、リクエストを送信する必要があります。

先ほどnet/httpのライブラリとuriのモジュールをrequireして使える様にしたので、以下のコマンドで指定したURIにリクエストを送信する事が出来ます。(net/httpのライブラリとuriのモジュールについては、別記事で詳しく解説させて頂きます。)

Rubyで指定したURIにHTTPリクエストを実行する
1
Net::HTTP.get(URI.parse('指定するURI'))

https://randomuser.me/api指定するURIに記述して実行すると、以下のようにJSON形式のデータでダミーユーザーを取得する事が出来ています。

irb | ダミーユーザー情報を取得する
1
2
3
4
5
6
7
irb(main):004:0> Net::HTTP.get(URI.parse('https://randomuser.me/api'))
=> "{\"results\":[{\"gender\":\"female\",\"name\":
{\"title\":\"Miss\",\"first\":\"Flaviana\",\"last\":\"Lima\"},\"location\":{\"street\":
{\"number\":9550,\"name\":\"Rua Minas Gerais 
\"},\"city\":\"Cama\xC3\xA7ari\",\"state\":\"Sergipe\",\"country\":\"Brazil\",\"postcode\":89426,\"
coordinates\":{\"latitude\":\"-76.9813\",\"longitude\":\"173.7176\"},\"timezone\":
# 以下省略

JSON形式のデータでユーザー情報を取得する事が出来ましたが、このままではRubyで扱う事が出来ないので、JSON形式のデータをRubyのHashに変換する必要があります。

※「RANDOM USER GENERATOR」は、アクセスする度にダミーユーザーの情報は変更されます。

RubyのHashに変換して表示する
リンクをコピーしました

取得したJSON形式のユーザー情報をRubyのHashに変換する為に、JSON.parseを使います。取得したデータを変数resに格納してJSON.parseに渡してRubyのHashに変換します。

irb | JSON形式のデータからRubyのHashに変換する
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
irb(main):004:0> res = Net::HTTP.get(URI.parse('https://randomuser.me/api'))
=> "{\"results\":[{\"gender\":\"female\",\"name\":
{\"title\":\"Miss\",\"first\":\"Flaviana\",\"last\":\"Lima\"},\"location\":{\"street\":
{\"number\":9550,\"name\":\"Rua Minas Gerais 
\"},\"city\":\"Cama\xC3\xA7ari\",\"state\":\"Sergipe\",\"country\":\"Brazil\",\"postcode\":89426,\"
coordinates\":{\"latitude\":\"-76.9813\",\"longitude\":\"173.7176\"},\"timezone\":
# 以下省略

# JSON形式のデータからRubyのHashに変換する
irb(main):005:0> hash = JSON.parse(res)
=> {"results"=>[{"gender"=>"female", "name"=>{"title"=>"Miss", "first"=>"Flaviana", 
"last"=>"Lima"}, "location"=>{"street"=>{"number"=>9550, "name"=>"Rua Minas Gerais "}, 
"city"=>"Camaçari", "state"=>"Sergipe", "country"=>"Brazil", "postcode"=>89426, 
"coordinates"=>{"latitude"=>"-76.9813", "longitude"=>"173.7176"}, "timezone"=>
{"offset"=>"+5:00", "description"=>"Ekaterinburg, Islamabad, Karachi, Tashkent"}}, 
"email"=>"flaviana.lima@example.com",
# 以下省略

JSON.parse(res)の返り値を確認すると、RubyのHashに変換されている事が分かります。これで、このデータをRubyで扱う事が出来ます。

試しに16行目のemailの値を取り出してみます。RubyのHashに変換されたデータは変数hashに入っているので、以下のように取り出す事が出来ます。

irb | emailの値を取り出す
1
2
irb(main):006:0> p hash["results"][0]["email"]
=> "flaviana.lima@example.com"

この様にWeb APIの公開されている機能や情報をRubyのHashに変換することによって、Webアプリケーションに組み込んで利用する事が出来ます。

今回は、Web APIを使ってJSON形式のデータをRubyで扱うシンプルな方法を解説しましたが、他にも失敗した際の処理やクエリパラメータの設定などがありますので、ドキュメントなどを参考に色々試してみてください。

まとめ
  • Rubyでは、JSONモジュールを利用することでJSONの操作を簡単にする事が出来ます。
  • JSON形式の文字列からRubyのHashの変換は、JSON.parse()を使います。
  • RubyのHashからJSON形式の文字列の変換は、JSON.generate()to_jsonを使います。