🤖

Railsアプリケーションの行うHTTP通信の内容を覗いてみた

2023/12/10に公開

これは株式会社TimeTree Advent Calendar 2023の10日目の記事です。
https://qiita.com/advent-calendar/2023/timetree

はじめに

こんにちは、TimeTreeでバックエンドエンジニアをしている@koheiyamamoto26です。社内ではJosephと呼ばれています。

最近、個人的にHTTPの勉強をしています。
その一環として、Ruby on RailsアプリケーションによるHTTP通信の内容を確認してみました。
この記事ではその内容をまとめてみようと思います。

概要

  • Railsアプリケーションが行うHTTPリクエスト・レスポンスの内容ついて、ポイントを簡単に解説します
  • GET、POSTの2つHTTPメソッドを用いたHTTP通信に対象絞って解説します
  • HTTPリクエストの送受信、内容の確認にはブラウザ(Google Chrome)を使用します

使用環境

ruby: 3.2.2
rails: 7.1.2
Google Chrome: 120.0.6099.71 

rails newでアプリケーション作成し、Bookのscaffoldを実行します。

bin/rails generate scaffold Book title:string author:string

HTTPリクエスト・レスポンスの内容

GET

ブラウザ上でBook一覧ページ(http://localhost:3000/books)にアクセスすることで、GETリクエストを行います。

Book一覧ページ

HTTPリクエストの内容

リクエストヘッダー
GET /books HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Cookie: _rails_http_session=tqL2SqXN01OzXZO%2Bv%2BrsuFK7izb%2Fn51%2Fgf3vFEEhN20jxK8ctz%2F5C4qTLfc4eOZ9XK8SNDNt%2BQ2UdKp%2B4vba%2BNRgjBO59inqIDFBbtq2O%2FkgiPCcjx4XiFPKTq6LjLriB%2BjyuJNIriMMyMnjx3OytMC6Bwab8w%2BUhPOCq1TjVeoRQktoQKvIGF6bDbJ8ZGUMUw1Avhmi3Ac8rdZBe0wu11A%2F7A3z2UnOt9IpPVWDV7kknZV9n2ji9b5dJ7%2BVrdWKdVE%2BL0jynFtyC2OLIfc9z7MB2j4p0j%2BFpu2d--sKCdo6ibLPslbBpC--yx51G8LzE3LBP8FWoQVbNA%3D%3D
Host: localhost:3000
If-None-Match: W/"c51f4e18e17902f0b18b93346dff6289"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

🤖 ポイント

  • GET /books HTTP/1.1
    • GETメソッドを使用して/booksリソースを取得する
    • HTTP1.1バージョンを使用する
  • Accept: text/html,application/xhtml+xml...
    • クライアントが理解できるコンテンツタイプを示す
    • コンテンツタイプの指定にはMIMEタイプが用いられる
    • text/htmlなどを指定している
  • User-Agent: Mozilla/5.0...
    • クライアントのブラウザやオペレーティングシステムに関する情報
  • Cache-Control: max-age=0
    • サーバーにキャッシュの動作を指定する
    • max-age=0によって、キャッシュを使用せず最新のコンテンツを取得することになる
  • (GETメソッドはボディを含めることが期待されていない

HTTPレスポンスの内容

レスポンスヘッダー
HTTP/1.1 200 OK
x-frame-options: SAMEORIGIN
x-xss-protection: 0
x-content-type-options: nosniff
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
link: </assets/application-e0cf9d8fcb18bf7f909d8d91a5e78499f82ac29523d475bf3a9ab265d5e2b451.css>; rel=preload; as=style; nopush,</assets/es-module-shims.min-4ca9b3dd5e434131e3bb4b0c1d7dff3bfd4035672a5086deec6f73979a49be73.js>; rel=preload; as=script; nopush
content-type: text/html; charset=utf-8
etag: W/"8506af671024d6b5a3dd8812d3aa4036"
cache-control: max-age=0, private, must-revalidate
set-cookie: _rails_http_session=hzgQleWcn6dwvy%2B4eHe0VIRGw8WN8gRbKGJEauoeiiGO2cHNP7BVN2nDprsEaoGD0QN5UFpSICH6rKfk%2FS3lCUZljp7%2BPUkpM%2FWjTt5h7kXpXoktX2CqIUfUgSp3tk1feBRiI5gudIq0AMW%2Brh0T6zc1Y7IH8aQyBG4%2B0ZSiDfqY8Cw7ulXwPDJFGhaboY9tE5jEjMc3foGzaw0v8Qq1y58az3KOEweXV%2FQDckwcccumh2o9djELiSv%2BI9HWXIWMl8VcMNb1PS0ZkighGWjMro2l3xbBsrWfTOpj--2irBSVtdfZowylwF--YywWIIvA1E9FLvzOjguGZw%3D%3D; path=/; httponly; SameSite=Lax
x-request-id: 6ad275ef-0d05-44e1-b6d4-fe366300b069
x-runtime: 0.027184
server-timing: start_processing.action_controller;dur=0.03, sql.active_record;dur=0.21, instantiation.active_record;dur=0.24, render_partial.action_view;dur=0.18, render_template.action_view;dur=3.49, render_layout.action_view;dur=7.93, process_action.action_controller;dur=9.73
Content-Length: 2979

🤖 ポイント

  • HTTP/1.1 200 OK
    • ステータスコード200、ステータスメッセージOK
  • content-type: text/html; charset=utf-8
    • コンテンツタイプがHTMLで、文字エンコーディングはUTF-8であることを示す
    • content-typeの指定にはMIMEタイプが用いられる
  • x-content-type-options: nosniff
    • ブラウザに対して、content-typeで指定されたMIMEタイプを変更しないよう指示する
    • 例えば、content-type: text/plainで受信したHTMLの内容をブラウザが勝手にHTMLとして処理することを防ぐために利用される
  • etag: W/"8506af671024d6b5a3dd8812d3aa4036"
    • ETag(リソースのバージョンを一意に識別するための識別子)を示す
    • キャッシュのために利用される
  • cache-control: max-age=0, private, must-revalidate
    • キャッシュされたコンテンツが古くなっていること示す
  • set-cookie: _rails_http_session=hzgQle...
    • サーバーがクライアントにクッキーの設定を指示する
    • クッキーはセッション管理などに利用される

POST

ブラウザ上でBook作成ページ(http://localhost:3000/books/new)にアクセスし、作成ボタンをクリックすることで、POSTリクエストを行います。

Book作成ページ

HTTPリクエストの内容

リクエストヘッダー
POST /books HTTP/1.1
Accept: text/vnd.turbo-stream.html, text/html, application/xhtml+xml
Accept-Encoding: gzip, deflate, br
Accept-Language: ja,en-US;q=0.9,en;q=0.8
Connection: keep-alive
Content-Length: 231
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Cookie: _rails_http_session=HBUl2ZkuoKxzxkdCT2zPTHi%2FBYoS%2F6f3YsSVfm94uEYwzsfEnzgpgEOeHn23%2FG6fggg5M9xQKB2lcDmVBzCr68d%2Fvn6QTtDNL13NWNYkfFrmGlcPZXl9M%2FCK5QFalJ3KSr3QfeuNuv8U1ZLWrKmBHkDcUfVQeqmH3Qw6rssqPO0FPVyQaqJMzjBS91fqLjs%2B%2BL%2B2jsOZM%2Bq0UrdpDMIo89RT%2BZGRlZ%2Bg8oGSJPVVJEdlWmSUZK9qCtMjFktW8LkgH4FHXgkfrQ%2FTxp6ENUWmKH57P%2FQrMKQh9cQa--QjYmiuBsjo938rua--aN%2F7ojMn%2BCe67OziC3NG4A%3D%3D
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/books/new
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
X-CSRF-Token: uo5I6x4_XICEW5SM-ENrkgH0RevO5jo6Q9zn6yAx8uB8kLLvF4EZWIwqVohoGvtWnAtur3xCbGJfjDCP4FIQGQ
sec-ch-ua: "Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"

🤖 ポイント

  • POST /books HTTP/1.1
    • サーバーに新しいBookリソースを作成するように指示する
  • Content-Type: application/x-www-form-urlencoded;charset=UTF-8
    • リクエストボディのデータの形式(MIMEタイプ)を指定する
    • application/x-www-form-urlencodedは、リクエストボディの内容がURLエンコードされたフォームデータであること示す
リクエストボディ
# Rawデータ
authenticity_token=YJXIyCHsJXr-ju6___0IaKL3aNNY4fbyrYhAapP6dUTpq9Ti0bTu8wiXuCQwx2t5KAGFSwGSqz0RM0FhhaOfGQ&book%5Btitle%5D=%E5%91%AA%E8%A1%93%E5%BB%BB%E6%88%A6&book%5Bauthor%5D=%E8%8A%A5%E8%A6%8B%E4%B8%8B%E3%80%85&commit=Create+Book

# パース後
authenticity_token: YJXIyCHsJXr-ju6___0IaKL3aNNY4fbyrYhAapP6dUTpq9Ti0bTu8wiXuCQwx2t5KAGFSwGSqz0RM0FhhaOfGQ
book[title]: 呪術廻戦
book[author]: 芥見下々
commit: Create Book

🤖 ポイント

  • book[title]=呪術廻戦&book[author]=芥見下々
    • Content-Type: application/x-www-form-urlencodedの場合、ボディはkeyと=で接続され、各項目が&で繋がれた文字列になる
    • title に「呪術廻戦」、author に「芥見下々」という値が設定されている
    • (実際のRowデータはブラウザによってURLエンコードされている)
  • commit: Create Book
    • ユーザーが「Create Book」ボタンをクリックしたことを示す

HTTPレスポンスの内容

レスポンスヘッダー
HTTP/1.1 302 Found
x-frame-options: SAMEORIGIN
x-xss-protection: 0
x-content-type-options: nosniff
x-permitted-cross-domain-policies: none
referrer-policy: strict-origin-when-cross-origin
content-type: text/html; charset=utf-8
location: http://localhost:3000/books/4
cache-control: no-cache
set-cookie: _rails_http_session=tmYyn6YLK6BdXu5bROxI%2B4lZzzsFheoaIHLNREc2BCI9hmx9H8kMr3ILBMVGyiIqyUvbqmGaDKWZA4O1HqODIzwHD1yYavj44mn5ai3aR3oat1C%2BKkCt7vAMTkmNx9vKHHW2u0MEfpa6%2FFHqzGx3tlCJsueSSc6SFa4nvVoc7RNnVHBUp7EJ3rL0B9%2BPC3onqFC1JgHuF0CNYi4aaSj8arXn2Mnx5eeyonDQem6S22iU%2FB85eCeyauKDTUbYAJnTZxdm5k8ChSKKjnKWJ%2FIaW3UKCrHSMEZTBDYz6pXIzQOPnno9IQRN%2BrFkYt3fq0I1yIrmGc8ztCTMJjM2wWEHWTecMpYOh2%2F8lBwIzUL38RMFQ7wsfQEeYMhLiYeE6sLf6n9qUMDznV71xAA8197%2B01hwjZBRDQvXjC3pSDgMwg%3D%3D--%2FTDXbDqdfYMSYpOw--8%2BRu2E0WEvY8FXY2CUxfdQ%3D%3D; path=/; httponly; SameSite=Lax
x-request-id: 0478d49e-4e6a-4dc8-8a32-1f81fa073c6d
x-runtime: 0.038798
server-timing: start_processing.action_controller;dur=0.00, sql.active_record;dur=2.03, transaction.active_record;dur=1.18, redirect_to.action_controller;dur=0.12, process_action.action_controller;dur=4.40
Content-Length: 0

🤖 ポイント

  • HTTP/1.1 302 Found:
    • ステータスコード 302 は、一時的なリダイレクトを意味する
  • Location: http://localhost:3000/books/4:
  • Cache-Control: no-cache
    • このレスポンスはキャッシュされるべきではないことを示す
  • Content-Length: 0
    • レスポンスボディの長さを示す
    • リダイレクトレスポンスのため、0に設定されている

おわりに

普段あまり意識できていなかった、Railsアプリケーションが行うHTTP通信の内容を覗いてみることで、HTTPの基礎的な内容について理解を深めることができました。

今回は基礎的な内容だけでしたが、今後はRails特有のHTTPヘッダー項目など、より実践的な内容についても理解を深めていきたいと思います。

TimeTreeの採用情報🌟

TimeTreeのミッションに向かって一緒に挑戦してくれる仲間を探しています。TimeTreeで働くことに興味がある方はぜひ、Company Deck(会社紹介資料)や採用ページをご覧ください!

TimeTree Tech Blog

Discussion