【学習記録】RubyでのHTTPリクエストの処理
URI.parse
uri = URI.parse("https://www.ruby-lang.org/")
URIライブラリは、RubyでURIを扱うための標準ライブラリ。
parseメソッドは引数に与えられたURI文字列を解析して、URIオブジェクトを生成する。
URIオブジェクトを使用することで、URIの構造を簡単に取得・操作ができる。
これにより、以下のような情報が取得できる。
- uri.scheme:スキーム(例:https)
- uri.host:ホスト(例:www.ruby-lang.org)
- uri.port:ポート(例:80)
- uri.path:パス(例:"/")
- uri.query:クエリ(例:nil)
Net::HTTP::Get.new
req = Net::HTTP::Get.new(uri)
Net:HTTPライブラリは、RubyでHTTPプロトコルを扱うための標準ライブラリ。
HTTPリクエストを送信したり、HTTPレスポンスを受信したりできる。
Net::HTTP::GetクラスはHTTPのGETリクエストを表すクラス。
GETリクエストはWebサイトのページを取得したり、APIエンドポイントにアクセスする際に使用する。
new(uri)で指定されたURIに対するGETリクエストを作成する。
JSON.pretty_generate
req.body = JSON.pretty_generate(post_body).to_json.to_s.gsub('/', '\/')
JSONライブラリは、RubyでJSONを扱うための標準ライブラリ。
JSONモジュールにJSONを操作するための代表的なメソッドが集められている。
-
pretty_generateはRubyのオブジェクトを「JSON形式の文字列」に変換する。JSONデータが整形されて読みやすくなる。
-
.to_jsonで整形された文字列をさらに「JSON形式のオブジェクト」に変換している。これにより、JSON文字列内の特殊文字やエスケープされた文字列が適切に処理される。
-
HTTPリクエストのボディ部分に設定するには文字列形式である必要があるため、.to_sでJSON形式のオブジェクトを文字列に変換する。
-
JavaScriptなどで正規表現の区切り記号で認識されることを防ぐため、.gsub('/', '/')でJSON形式の文字列の'/'を'/'にエスケープする。
Net::HTTP.start
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.request(req)
end
Net::HTTP.startは、新しいNet::HTTPオブジェクトを生成し、TCPコネクション、HTTPセッションを開始する。
ブロックを与えると、オブジェクトをブロックに渡してブロックが終わった時に接続を閉じ、ブロックの値が返り値になる。
ブロックを与えない場合は、生成したオブジェクトを渡し、利用後にこのオブジェクトをNet::HTTP#finishでHTTPセッションを終了させる必要がある。
-
startメソッドでHTTPリクエストの送信準備を行う。指定されたホストとポートに対してHTTP接続を開始する。
HTTPSを使用する場合はuse_sslオプションにtrueを指定する。 -
do|http| ... end:HTTPリクエストの送信をレスポンスの受信を行うブロックを定義する。httpパラメータはHTTP接続を操作するためのNet::HTTPインスタンスを示す。
-
http.request(req):httpインスタンスのrequestメソッドを呼び出してHTTPリクエストを送信する。受信したレスポンスが戻り値になる。
httpインスタンスはNet::HTTP.startメソッドで作成される、HTTP通信を行うためのNet::HTTPインスタンス。 -
resにレスポンスを代入し、後の処理でレスポンスを参照できるようになる。
Net::HTTPSuccess
HTTPレスポンス2xx(Success)を表現するクラス。
リクエストが正常に受信、処理されたことを表す。
res.is_a?(Net::HTTPSuccess)
is_a?メソッドは、オブジェクトが指定されたクラスかそのサブクラスのインスタンスである時に真を返す。
用語memo
URI
URI(Uniform Resource Identifier):Web上にあるあらゆるファイルを認識するための識別しの総称。URNとURLはURIに含まれる
URL(Uniform Resource Locator):Web上にあるファイルがWeb上のどこにあるかを表したもの
URN(Uniform Resource Name):Web上での名前を指す(Web側で認識される名前のようなもの)
HTTP
HTTP(Hyper Text Transfer Protocol)とは、Web上でWebサーバとクライアントがHTML文書などの情報をやり取りするときに使われるプロトコル(通信手順)。
HTTP通信はHTTPプロトコルに従って行われる通信。
スキームは、通信手段を示す情報。
HTTP通信をすることを意味するスキーム名が「http」。
HTTPリクエストの中身(GETの場合)
- リクエスト行(Request Line):リクエストの開始を示す
- メソッド:GET
- リクエスト先(指定したURI)
- HTTPのバージョン
- ヘッダー(Headers):リクエストの詳細
- User-Agent:クライアントの種類やバージョンなど
- Accept:受け入れ可能なコンテンツタイプ
- Referrer:遷移元のページ
- Content-Type:リクエストボディのデータ形式
- Authorization:認証情報
- Cookie:クラウアントがサーバーに送信するCookie情報。サーバーはこれを使用してクライアントのセッションを管理する
- ボディ(Body):リクエストボディ。主にPOSTで使われ、データの送信や操作に使う
TCPコネクション
TCP(Transmission Control Protocol)はコンピュータネットワーク上でのデータ通信を確立し、制御するプロトコル。インターネットやローカルネットワークなどで広く使われる、信頼性が高い通信プロトコル。
データの信頼性、整合性、順序づけを保証する。
- 通信開始前にコネクションを確立する
3ウェイハンドシェイクという手順でコネクションを確立する。- クライアントがサーバーに接続要求を送信する
- サーバーが応答を返す
- クライアントが応答を確認するとコネクションが確立される
- データを転送を開始する
シーケンス番号と確認応答番号を使って送信と受信の順序を管理する。データはセグメントという単位で送信され、受信側で再構築される。 - データ転送の速度を制御するフロー制御を行う
- パケットの喪失や破損が発生した場合は再送する
- コネクションを終了する
4ウェイハンドシェイクという手順でコネクションを終了する。- クライアントが終了要求を送信する
- サーバーがそれに対する応答を返す
- サーバーが終了要求を送信する
- クライアントが応答することでコネクションが終了する
HTTPセッション
Webサーバーとクライアント間での一連の相互作用を通じて維持される状態情報のセット。
ウェブアプリケーションのユーザー認証、ショッピングカートの内容、Webページの閲覧履歴など、特定のユーザーに関連するデータを管理するのに使われる。
- 状態管理
HTTPはプロトコル自体は情報を持たないステートレスなプロトコルであるため、個々のリクエストは独立して処理される。
HTTPセッションは状態を管理するメカニズムを提供する。 - セッションID
クライアントがサーバーに初めてリクエストするとき、サーバーは新しいセッションを開始する。
セッション開始時にサーバーは一意のセッションIDをクライアントに割り当てる。
セッションIDを使うことで、サーバーは特定のセッションに関連づけられたデータを識別して管理できる。
通常、クッキーを使ってセッションIDをクライアントに送信する。 - セッションデータの保存
サーバーはセッションIDに関連づけられたデータを保存する。
ユーザーの認証状態、セッションのタイムアウト設定、セッションに関連するその他の情報が含まれる。 - セッションの維持
クライアントは2回目以降のリクエスト時にサーバーにセッションIDを提示し、サーバーは提示されたセッションIDに紐づくセッションファイルを確認する。
クライアントとサーバー間で、セッションが有効な間、セッションデータが保存される。 - セッションの終了
ユーザーがログアウトしたり、セッションがタイムアウトした場合、サーバーはセッションデータを削除する。
感想
- HTTP通信の仕組みや今回出てきた用語は一応過去にも勉強したことはあったが、なんとなくのふわっとした知識しか残っていなかったと改めて感じた
- ステートレスとかステートフルとかいうけど、なんでHTTPはステートレスっていうんだっけ?
- TCP connectionのエラーとかよく見かけたけど具体的にどんなものだっけ?なんの略だっけ?
- HTTPリクエストの中にヘッダーとかボディーとかなんか色々あった気がするけど具体的にはそれぞれ何が入ってるんだっけ
とか
- 今回はRubyのHTTPリクエスト処理のコードについてがメインだったが、HTTP通信関連についてもっと復習する必要があると感じた
- コードを丁寧に読むのが大事。
-
JSON.pretty_generate(post_body).to_json.to_s.gsub('/', '\/')
だけでも、なぜto_jsonしてさらにto_jsonしてgsubする必要があるのかが理解できた- 記事を書く前はpost_bodyをJSONになんか変換してるっぽいなくらいの認識で飛ばしていた
- 「JSON形式の文字列」と「JSON形式のオブジェクト」は別物。
-
Discussion