🦓

[Ruby]net/httpライブラリーを使ってみる

2023/09/22に公開

はじめに

Rubyのnet/httpライブラリーを使ってhttpリクエストとレスポンスを試していきます。

Net::HTTPとは

Net::HTTP は、Rubyの標準ライブラリで提供されるhttpプロトコルを使用してリモートサーバーと通信するためのクライアントライブラリです。
RubyプログラムからHTTPリクエストを送信し、HTTPレスポンスを受け取ることができます。

https://docs.ruby-lang.org/ja/latest/library/net=2fhttp.html

ドキュメント通りにやっていきます。Rubyのファイルを作成します。

GETリクエスト

基本の操作方法

require 'net/http'

# APIエンドポイントのURLを指定する
url = URI.parse('https://example.com/api/resource') 
# 新しいHTTPリクエストを作成する
http = Net::HTTP.new(url.host, url.port)
# HTTPSを使用する場合
http.use_ssl = (url.scheme == 'https') 

request = Net::HTTP::Get.new(url)

response = http.request(request)

# レスポンス処理
if response.code.to_i == 200
  puts "Response Body: #{response.body}"
else
  puts "HTTP Error: #{response.code} - #{response.message}"
end

http://www.example.comindex.htmlページを取得してみます。

require 'net/http'

url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.path)
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}
puts res.body

コマンドからファイルを実行してみます。

~ ruby http.rb
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
        
    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>    
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

レスポンスコードを200であることを確認します。

puts res.code
200
puts res.header
#<Net::HTTPOK:0x000000010964c260>

存在しないページに書き換えてもう一度実行してみますと、400 Bad Requestが返してくることも確認します。

~ ruby http.rb
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>cloudflare</center>
</body>
</html>

POSTリクエスト

基本の操作方法

次はPOSTリクエストです。

require 'net/http'
uri = URI('http://example.com')
hostname = uri.hostname # => "example.com"
uri.path = '/posts'
req = Net::HTTP::Post.new(uri) # => #<Net::HTTP::Post POST>
req.body = '{"title": "foo","body": "bar","userId": 1}'
req.content_type = 'application/json'
res = Net::HTTP.start(hostname) do |http|
  http.request(req)
end

https://jsonplaceholder.typicode.com/ というテストサイトにPOSTリクエストを送ってみます。

require 'net/http'
require 'uri'
require 'json' # JSONモジュールを利用する

# リクエスト先
url = URI.parse('https://jsonplaceholder.typicode.com/posts')

# データ
data = {
    title: 'foo',
    body: 'bar',
    userId: 1,
}

# データをJSONにする
json_data = data.to_json
puts json_data

# リクエストを作成し、データタイプを指定する
request = Net::HTTP::Post.new(url.path, { 'Content-Type' => 'application/json' })
request.body = json_data

# 承認が必要な場合トークンを提供する
# request['Authorization'] = 'Bearer your_access_token'


http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == 'https')

# リクエストを送る
response = http.request(request)

# レスポンス処理を指定する
if response.code.to_i == 200
  puts "HTTP Success: #{response.body}"
  puts response
else
  puts "HTTP Error: #{response.code} - #{response.message}"
end

実行してみます。

ruby http.rb
{"title":"foo","body":"bar","userId":1}
HTTP Error: 201 - Created

APIからJSONデータを取得する

https://jsonplaceholder.typicode.com/posts 先のテストサイトから、投稿一覧を取得してみます。

http.rb
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse('https://jsonplaceholder.typicode.com/posts')
json = Net::HTTP.get(uri)
# JSON文字列をハッシュへ変換
data = JSON.parse(json)

data.each do |item|
    puts "ユーザー:#{item['userId']}"
    puts "投稿#{item['id']}#{item['title']}"
    puts "本文 :#{item['body']}"
end

ファイルを実行してみます。

ruby http.rb
ユーザー:1
投稿1:sunt aut facere repellat provident occaecati excepturi optio reprehenderit
本文 :quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto
ユーザー:1
投稿2:qui est esse
本文 :est rerum tempore vitae
sequi sint nihil reprehenderit dolor beatae ea dolores neque
fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis
qui aperiam non debitis possimus qui neque nisi nulla
...

終わりに

httpartyFaradayなどhttp通信を行うgemもありますがまずは基本を押さえたかったです!
https://pikawaka.com/ruby/json

Discussion