🤖
Railsアプリケーションの行うHTTP通信の内容を覗いてみた
これは株式会社TimeTree Advent Calendar 2023の10日目の記事です。
はじめに
こんにちは、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バージョンを使用する
- GETメソッドを使用して
-
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:
- ブラウザのリダイレクト先のURLを指定する
- 作成したBookの詳細ページ( http://localhost:3000/books/4) が指定されている
-
Cache-Control: no-cache
- このレスポンスはキャッシュされるべきではないことを示す
-
Content-Length: 0
- レスポンスボディの長さを示す
- リダイレクトレスポンスのため、0に設定されている
おわりに
普段あまり意識できていなかった、Railsアプリケーションが行うHTTP通信の内容を覗いてみることで、HTTPの基礎的な内容について理解を深めることができました。
今回は基礎的な内容だけでしたが、今後はRails特有のHTTPヘッダー項目など、より実践的な内容についても理解を深めていきたいと思います。
TimeTreeの採用情報🌟
TimeTreeのミッションに向かって一緒に挑戦してくれる仲間を探しています。TimeTreeで働くことに興味がある方はぜひ、Company Deck(会社紹介資料)や採用ページをご覧ください!
TimeTreeのエンジニアによる記事です。メンバーのインタビューはこちらで発信中! note.com/timetree_inc/m/m4735531db852
Discussion