
今回はRubyのWEBrickを使ってHTTPサーバを構築していくよ!
こんな方におすすめ
- Rubyを学習している人
- WEBrick使ってみたい人
現場でRubyを使って開発しているので、個人の勉強記録として残します。
普段はRailsで開発を行っているのですが、リクエスト周りはよしなにRailsがやってくれるので、勉強としてRubyだけでリクエスト周りを作っていきたいと思います。
目次
要件定義
- http://127.0.0.1:20080/welcomeとリクエストしたら、「ようこそ!ゲストさん」というページがブラウザで表示される
- http://127.0.0.1:20080/welcome?name=佐藤とリクエストしたら、「ようこそ!佐藤さん」というページがブラウザで表示される
- Railsのようなフレームワークは使わない
- ライブラリはWEBrickを使う
環境
Ruby 2.6.10
WEBrickとは?
一言で言うと、Rubyで簡単にHTTPサーバを立ち上げられるライブラリです。
WEBrickの特徴
- 簡単にHTTPサーバーを構築できる
- 数行のRubyコードで、HTTPサーバを起動することができます。
- Rubyの標準ライブラリ(※Ruby 3.0以降は別途インストールが必要)
- Ruby 2 までは標準ライブラリとして組み込まれていたのですが、Ruby 3.0 以降では
gem install webrick
でインストールが必要になります。
- Ruby 2 までは標準ライブラリとして組み込まれていたのですが、Ruby 3.0 以降では
- 柔軟なカスタマイズが可能
- リクエストごとに動的なレスポンスを返すAPIサーバーとしての利用もできます。
- サーブレットによる処理の管理
- サーブレットという仕組みで、URLごとに異なる処理を割り当てることができます。
サーブレットとは?
一言で言うと、リクエストを処理して、レスポンスを作成するプログラムの部品です。
「このリクエストにはこの処理を使う」と言った感じに、サーブレットを使えば、URLごとに違う処理をしたり、動的にメッセージを変えたりできます。
例えば、「/hello」 というURLにアクセスされたら「こんにちは!」と返し、
「/goodbye」 にアクセスされたら「さようなら!」と返すように、URLごとに異なる処理を実行できます。
サーブレットはWEBrick::HTTPServlet::AbstractServlet
を使って、自分だけのサーブレットを作成できます。
Ruby 3.4 リファレンスマニュアル(WEBrick::HTTPServlet::AbstractServlet)
◎サンプルコード
require 'webrick'
# ここでサーブレットを定義
class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
def do_GET(req, res)
res.status = 200
res['Content-Type'] = 'text/html'
res.body = "こんにちは!これはWEBrickのサーブレットからのメッセージです。"
end
end
server = WEBrick::HTTPServer.new(:Port => 3000)
server.mount '/hello', HelloServlet
trap('INT') { server.shutdown }
server.start
サーブレットの流れ
- リクエストの受信
WEBrickサーバーがクライアントからのHTTPリクエストを受け取ります。 - サーブレットのマッピング
リクエストされたパス(URL)に対応するサーブレットが特定されます。server.mount '/hello', HelloServlet
でパスとサーブレットの関連付けを行います。 - 対応するメソッドを決める
リクエストのHTTPメソッドに応じて、サーブレット内の対応するメソッド(例:do_GET
,do_POST
)が呼び出されます。 - レスポンスの生成
サーブレットはリクエストオブジェクトから必要なデータを取得し、レスポンスオブジェクトに適切なステータスコード、ヘッダー、ボディを設定してクライアントに返します。
WEBrickを使ってHTTPサーバーを構築してみる
◎ファイル構成
your_project_directory
├── server.rb # 上記のRubyサーバースクリプト
└── welcome.html # HTMLテンプレートファイル
※ 今回はサーブレットを使わず、手軽にリクエストを処理するために mount_proc
を使用します。
mount_proc
を使うことで、簡単な処理をブロック(do...end
)内に直接記述することができます。
Ruby 3.4 リファレンスマニュアル(mount_proc)
step
1 require 'webrick' でWEBrickを読み込む
最初に、Rubyの標準ライブラリであるWEBrickを読み込みます。
(※Ruby 3.0以降の場合は gem install webrick
でインストールが必要になります)
require webrick
step
2WEBrick::HTTPServer.new
でサーバーを作成する
サーバーの設定も行います。
srv = WEBrick::HTTPServer.new({
:DocumentRoot => './', # 現在のディレクトリをルートに設定
:BindAddress => '127.0.0.1', # ローカルホストでバインド
:Port => 20080 # ポート20080でサーバーを起動
})
step
3mount_proc
で /welcome
へのリクエストを受け付ける
/welcome
にアクセスされたときに、クエリパラメータに応じてHTMLを動的に生成する処理を設定します。
srv.mount_proc('/welcome') do |req, res|
# クエリパラメータ 'name' を取得し、UTF-8に強制変換
name = req.query['name'] ? req.query['name'].force_encoding('UTF-8') : 'ゲスト'
# welcome.html の内容をUTF-8で読み込む
html_content = File.read('welcome.html', encoding: 'UTF-8')
# {{name}} プレースホルダーをクエリパラメータの値で置き換える
updated_content = html_content.gsub('{{name}}', name)
# レスポンスとして更新されたHTMLを返す
res['Content-Type'] = 'text/html; charset=UTF-8'
res.body = updated_content
end
step
4welcome.html
のテンプレートファイルを作成する
同じディレクトリに welcome.html
というファイルを作成し、welcome.htmlのbodyにようこそ!{{name}}さん!
を記述します。
{{name}}の部分にクエリパラメータで送った名前が入ります。
・http://127.0.0.1:20080/welcome?name=佐藤でリクエストするとnameに佐藤が入る。
step
5trap("INT") { srv.shutdown }
でサーバーを安全に停止できるようにする
Ctrl + C
でサーバーを停止した際に、安全にサーバーをシャットダウンする処理を追加します
trap("INT") { srv.shutdown }
step
6srv.start
でサーバーを起動する
最後にサーバーを起動して、リクエストの待ち受けを開始します。
srv.start
◎最終的なコード
require 'webrick'
srv = WEBrick::HTTPServer.new({
:DocumentRoot => './',
:BindAddress => '127.0.0.1',
:Port => 20080
})
# /welcome のリクエスト受付
srv.mount_proc('/welcome') do |req, res|
# クエリパラメータ 'name' を取得し、UTF-8に変換
name = req.query['name'] ? req.query['name'].force_encoding('UTF-8') : 'ゲスト'
# welcome.html の内容を読み込み
html_content = File.read('welcome.html', encoding: 'UTF-8')
# {{name}} プレースホルダーをクエリパラメータの値で置き換え
updated_content = html_content.gsub('{{name}}', name)
# レスポンスとして更新されたHTMLを返す
res['Content-Type'] = 'text/html; charset=UTF-8'
res.body = updated_content
end
trap("INT") { srv.shutdown }
srv.start
動作確認
- ターミナルで「ruby server.rb」を実行します。
- http://127.0.0.1:20080/welcome?name=佐藤でアクセスし画像のように出れば成功です!
終わりに
今回はWEBrickで簡易的なHTTPサーバについて学習してみました。
少しでも学習のお役に立てれば幸いです。
参考記事
Ruby 3.4 リファレンスマニュアル(WEBrick::HTTPServlet::AbstractServlet)
おすすめ書籍
書籍:プロを目指す人のためのRuby入門
とても分かりやすい本なので、Ruby学習にはおすすめの一冊です!