RubyでHTTPリクエストを行う5つの方法

February 24, 2021
執筆者
レビュー担当者
Phil Nash
Twilion

5 ways to make http request in ruby

この記事はTwilio Developer EvangelistのValériane Venanceこちら(英語)て執筆した記事を日本語化したものてす。

こんにちは、この記事へようこそ。今日は、RubyでHTTPリクエストを行う5つの方法をご紹介します。

コードの記述を開始する前に、私がこのチュートリアルを書いたことをとても嬉しく感じていることをお伝えしたいと思います。Ruby on Railsは、世界中で私が一番好きなフレームワークであり、こだわりの強い私はいつも大好きなものを使用する傾向があります。

HTTPリクエストのようなシンプルなものに戻り、シンプルな.rbファイルを記述し実行することにより、私の手でRubyの力を解放でき、私達を言語の基本から遠ざけがちな、Railsの魔法に頼る必要がなく嬉しいです。

クラシックのさらなる利点は、複雑な環境で機能することです。自分の.rbファイルで実践できるように方法をお見せしますが、Rubyベースのフレームワークでも機能します。

この記事ではRubyベースのプログラムでHTTP呼び出しを作成する5つの方法について説明します。

要件

このチュートリアルを実行するには、以下が必要です。

  • Rubyがお使いのマシンにインストールされていること。私はRubyの最新バージョン(現在3.0.0)とOSXでrvmを使用していますが皆さんはご希望の方法を使用してください。
  • テキストエディター。私はsublime textまたはvimを使用しますが、ご希望のものを使用してください。

何を達成するか

5つの方法を使用し、GETリクエストとPOSTリクエストを作成します。プレーンなRubyで作成するため、各リクエストに.rbの拡張子の付いたファイルを作成し、以下のRubyコマンドを使用しコンソールで実行します。

$ ruby file.rb

一緒に確認していく内容

以下のライブラリを見ていきます。

GETリクエスト

NASAの今日の写真のAPI、APODを使用します。

このAPIは、リクエスト成功のレスポンスとしてJSONを、レスポンスコード200と共に送信します。レスポンスの本文をコンソールに表示することにします。

APIキーに関するメモ: ここでは、NASAが提供するDEMO_KEYを使用します。リクエストを数件作成するに留まり、API使用制限に達する心配はないからです。何度も使用する予定の場合には、ご自身でAPIキーを確保することを検討してください。

{
  "date": "2019-07-20",
  "explanation": "Have you seen a panorama from another world lately? ...",
  "hdurl": "https://apod.nasa.gov/apod/image/1907/a11pan1040226lftsm.jpg",
  "media_type": "image",
  "service_version": "v1",
  "title": "Apollo 11 Landing Panorama",
  "url": "https://apod.nasa.gov/apod/image/1907/a11pan1040226lftsm600.jpg"
}

POSTリクエスト

POSTリクエストでは、APIリクエストのデモツールである、JSONPlaceholderを使用し記事を作成します。

タイトルをfooに、本文をbarにし、userIDを1に設定し、新しい記事の作成をシミュレーションします。もちろんこれは、学習目的の偽のデータです。

ここではAPIキーは必要ありません。皆さんのコンソールに以下のような出力が表示されます。

{
  "title": "foo",
  "body": "bar",
  "userID": "1",
  "id": 101
}

標準: net/HTTP

Net/HTTPは、デフォルトのRubyクラスです。ほとんどの場合、URIと共に使用されます。

基本的なGETリクエスト

# nethttp.rb
require 'uri'
require 'net/http'

uri = URI('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)
$ ruby nethttp.rb

さて、ここではクエリするURLをURIに伝えます。これがURLなのは、https://が指定されているからです。次に、Net::HTTPライブラリからget_responseメソッドを使用します。

最後にリクエストが成功したかどうかを確認し、成功した場合にはコンソールで結果を印刷します。

個別のパラメータ

# nethttp2.rb
require 'uri'
require 'net/http'

uri = URI('https://api.nasa.gov/planetary/apod')
params = { :api_key => 'your_api_key' }
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
puts res.body if res.is_a?(Net::HTTPSuccess)

ここでは前回と同様ですが、パラメータを個別にハッシュとして渡します。これは、別々のソースからパラメータを取得する必要がある場合や、パラメータの数が多い場合に非常に便利です。ハッシュは、Rubyで広範に使用されるオブジェクトであり、コードを読みやすくするために簡単にフォーマットできます。気軽に使用してください。

パラメータを定義したら、パラメータにuri.queryを設定し、encode_www_formの形式を使用し、Webと互換性を持つ形式にエンコードします。これが違いを生みます。

POSTリクエスト

# nethttp3.rb
require 'uri'
require 'net/http'

uri = URI('https://jsonplaceholder.typicode.com/posts')
res = Net::HTTP.post_form(uri, 'title' => 'foo', 'body' => 'bar', 'userID' => 1)
puts res.body  if res.is_a?(Net::HTTPSuccess)

このリクエストでは、Net::HTTPpost_formメソッドを使用し、uriの後にキー値の形式でパラメータを指定します。次にリクエストが成功した場合には、レスポンスの本文を印刷します。

もちろん、ドキュメントも気軽に活用してください。こちらには、簡単に参照できるチートシートもご用意しています。複雑な用途には、OpenURIラッパーをお勧めします。これは、他の2つの便利なライブラリもラップします。

httparty: リクエストをまた楽しく!

Httpartyは、リクエストをするために頻繁に使用されるgemです。以下のようにインストールします。

$ gem install httparty
# httparty.rb
require 'httparty'

response = HTTParty.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
puts response.body if response.code == 200

このリクエストでは、httpartyに使用するメソッドを伝えます。ここではgetです。完全なURLを提供します。

httpartyの提供するレスポンスオブジェクトには、便利なメソッドが多数含まれます。ここでは、リクエストが成功したかどうかをcodeメソッドにより確認し、成功した場合にはbodyメソッドを使用し、NASAのAPIが返したJSON本文を印刷します。しかし、他にも使用できるメソッドは多数あります。例えば、response.parsed_responseは、解析されたJSONを返します。

クラシックなPOSTリクエスト

広範に使用されており、しかしgemで実装がオプションなのは、そこからクラスを作成することです。これも1つの.rbファイルで実行できます。

# httparty2.rb
require "httparty"

class PostManager
  include HTTParty
  base_uri 'https://jsonplaceholder.typicode.com'

  def initialize()

  end

  def create_post(title, body, user_id)
    params = { body: { title: title, body: body, userID: user_id } }
    self.class.post("/posts", params).parsed_response
  end
end

post_manager = PostManager.new()
p post_manager.create_post("foo", "bar", 1)

ここでは、PostManagerクラスを作成し、base_uriを、リクエストするAPIのベースURLに設定します。

このクラスには、create_postメソッドがあり、これには3つのパラメータを指定できます。これは前述の、タイトル、本文、userIDです。

次に、self.classpostメソッドを使用し、メソッド初期化から取得したパラメータを渡します。

次にすべきことは、PostManager.new()を使用し、このクラスの新しいインスタンスを作成することです。

次に、引数を使用し、create_postメソッドを使用します。

ご覧のように、このクラスにはinitializeメソッドもあり、より複雑なユースケースを構築する際に活用できます。

他のメソッドを追加することもできます。このコンテキストでは、read_postgetメソッドを使用)、またはdelete_postメソッド(deleteメソッドを使用)を追加するのが適切です。可能性は無限大です。

ボーナス

httpartyにはCLIが付属します。これは、一度gemをインストールすると、コンソールから直接使用できるようになります。

$ httparty your_url

HTTP(Gem!別名はhttp.rb)

http.rbはもう1つの人気のあるgemです。以下のようにインストールします。

$ gem install http
# http.rb
require "http"

response = HTTP.get("https://api.nasa.gov/planetary/apod", :params => {:api_key => "DEMO_KEY"})
p response.parse

HTTPgetメソッドを使用することによりurlを指定し、paramsという名前のハッシュでパラメータを渡します。

レスポンスオブジェクトで.parseを使用すると、JSONがハッシュに解析されます。

POSTリクエスト

# http2.rb
require "http"

response = HTTP.post("https://jsonplaceholder.typicode.com/posts", :form => {'title' => 'foo', 'body' => 'bar', 'userID' => 1})
p response.parse

ボーナスのレスポンス処理

JSONであることを承知していたため、私達は出力したすべてのレスポンスを.parseで解析したことに注意してください。けれど、レスポンスの本文を操作するために使用できるその他の便利なメソッドもあります。

  • to_s。「to string」Rubyメソッドを、response.body.to_sのように呼び出すと、コンテンツのレスポンスがすべて文字列に入れられます。
  • readpartial: htmlドキュメントを一行ずつ読むために便利です。response.body.readpartialのように使用します。読むhtmlドキュメントのチャンク数と同じだけこのメソッドを呼び出す必要があります。詳細については、こちら

並列処理HTTPX

他のgemとhttpxの最大の違いは、デフォルトでHTTP2であることです。これは、リクエストの並列処理に便利です。以下のようにインストールします。

$ gem install httpx
# httpx.rb
require "httpx"

response = HTTPX.get("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")
puts response.body if response.status == 200

httpxの基本的機能はシンプルです。パラメータを含む完全なURLを指定し、使用するHTTP動詞にちなむ名前を持つオブジェクトメソッドを使用します。

POSTリクエスト

# httpx2.rb
require "httpx"

response = HTTPX.post("https://jsonplaceholder.typicode.com/posts", :json => {'title' => 'foo', 'body' => 'bar', 'userID' => 1})
puts response.body if response.status == 201

このpostリクエストでは、HTTPXからのpostメソッドを使用し、パラメータとハッシュを渡します。

レスポンスステータスが201の場合には本文を出力します。このステータスは、HTTP標準において作成済みを意味します。

同時で複数のGETリクエスト

# httpx3.rb
require 'httpx'

base_url = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"
response, response2 = HTTPX.get(base_url, base_url + "&date=2019-07-20")
puts response.body if response.status == 200
puts response2.body if response2.status == 200

ここでは、NASA APIのベースURLをAPIキーと共に格納し、HTTPXに2つの同時のGETリクエストを実行するように伝えます。1つはすでにリクエストしたurlに対するものであり、もう1つは同じurlに対し追加パラメータ「date」を使用したリクエストです。このリクエストにより、パラメータとして入力した特定の日付の画像に関する情報が得られます。

次に、受信したばかりの2つのレスポンス本文をコンソールに出力します。

これは基本的な用途ですが、はるかに大規模なニーズに対応するよう拡張できることは確実です。

Faraday

以下を使用し、広範に使用されるもう1つのgem、Faradayをインストールします。

$ gem install faraday
# faraday.rb
require "faraday"

response = Faraday.get("https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")
p response.body if response.status == 200

ここまで作業してきた皆さんは、次にどうするかもうお判りでしょう。Faraday getメソッドをNASAのAPI urlと共に使用し、次にステータスコードが200の場合に本文を印刷します。

コンソールに表示されているように、設計により、本文がJSONとして処理されず、文字列として表示されます。

URIがエンコードされたパラメータを持つPOSTリクエスト

# faraday2.rb
require "faraday"
require 'uri'

params = {title: "foo", body: "bar", userID: 1}
encoded_params = URI.encode_www_form(params)
response = Faraday.post("https://jsonplaceholder.typicode.com/posts", encoded_params)
p response.body if response.status == 201

paramsをハッシュとして定義します。次に、encoded_paramsを、URIからのencode_www_formメソッドを使用し、Webフォーム互換形式にエンコードしたパラメータに設定します。

URIは、net/HTTPを使用する際に見られる標準的なRubyライブラリです。次に、Faraday.postメソッドを使いレスポンスを印刷します。

doブロックのあるPOSTリクエスト

# faraday3.rb
require "faraday"

response = Faraday.post "https://jsonplaceholder.typicode.com/posts" do |request|
  request.body = URI.encode_www_form({title: "foo", body: "bar", userID: 1})
end
p response.body if response.status == 201

Faradayリクエストに追加の設定を渡すもう1つの方法は、doブロックを使用することです。

doブロックで作成されたオブジェクトを使用し、.bodyオブジェクトメソッドを使用することにより、URIでエンコードされたパラメータを追加します。

他にも、request.headers['Content-Type'] = 'application/json'(リクエストのコンテンツタイプを設定します)やrequest.paramsのような便利なメソッドがあります。

Faradayの人気の理由は、利用可能なミドルウェアの存在です。認証、xmlとymlの形式、その他を処理する多くの便利な機能があります。詳細はこちらをご覧ください。

Rubyフレームワークに基づく任意のアプリケーションでこれらを使用する

Ruby on Rails、Sinatra、Hanamiなどで上記のメソッドを使用するには、require X行を削除し、その代わりにアプリケーションのGemfileを追加します。

gem 'X'

Gemfileを編集する際には、コンソールで$ bundle installを実行するのを忘れないでください。

まとめ

ここで示したソリューションはすべてシンプルなリクエストでは同様ですが、高度な用途では異なります。

これらはすべてそれぞれ特定のニーズを満たすように設計されており、複雑なユースケースにどれを使用するかを決定する際には、設計上の仕様が決定のキーポイントになるはずです。

ここでお見せした各gemについて、さらに多くのことを説明できますが、それぞれの全機能を知るには、ドキュメントを読み、機能を試してみてください。

私自身はhttpartyを最も頻繁に使用しますが、その理由は、私がRubyを学んだ時にはすでにこれが広く使用されており、使いやすく、理解も容易だったからです。また、StackOverflowには多くの例があります。本音としては?私はhttpartyが好きです。「httpartyみたいなパーティーは他にない」というキャッチフレーズが頭から離れません。httpartyは最高です。

httpxにも注目しています。このgemはまだ新しいですが、すでに面白い機能を備えています。

リクエストの話に戻る前に、少し気分を変えませんか?画像ファイルをダウンロードする方法を学ぶ、またはWhatsAppとRubyでプレイするなどはどうでしょう!

Valériane Venanceは、Twilioの開発者エバンジェリスト(Developer Evangelist)です。Rubyで何か面白いものを構築した場合には、vvenance@twilio.comまでメッセージを送るか、Twitterでコメントお願いします。ご連絡を楽しみにしております!