RubyOnBasis[10] 新人Railsエンジニア向け講座

このシリーズについて

RubyOnBasisはRuby on Railsを業務に利用する新人Webエンジニアのための、Railsを使わないテキストだ。この講座ではWEBrickを使ってWebアプリを書きながらHTTPを始めとする基礎知識をキャッチアップしてRailsがどうやって作られ動くのかを理解していく。

このシリーズを始めから読む

ようやくWebアプリ編に突入だ! RubyでHttpサーバを簡単に構築出来る標準ライブラリ、Webrickを使ってWebアプリを作ってみよう。さっそくコードから見ていくぞ、論ずるよりも書くが易しだ。

require 'webrick'

# WEBrick::HTTPServerクラスのインスタンスを生成する
server = WEBrick::HTTPServer.new({:Port => 3000})

# HTTPServerオブジェクトにmount_procメソッドでRouteを定義する
server.mount_proc('/teapot') do |req, res|
  res.body = "I'm a little teapot short and stout."
end

trap(:INT){ server.shutdown }
server.start

実にシンプルなコードだろう? ではこいつを実行して見よう。

[2017-08-22 23:24:00] INFO  WEBrick 1.3.1
[2017-08-22 23:24:00] INFO  ruby 2.1.0 (2013-12-25) [x86_64-darwin13.0]
[2017-08-22 23:24:00] INFO  WEBrick::HTTPServer#start: pid=96323 port=3000
localhost - - [22/Aug/2017:23:24:03 JST] "GET /teapot HTTP/1.1" 200 36

次にブラウザで http://localhost:3000/teapotへアクセスしてみよう。もしも君が仮想環境やリモートの環境で実行しているのなら、localhostの部分は適当に差し替えてくれ。

>I'm a little teapot short and stout. わーお! Webページが表示されたぞ、すごい! ではコードを少し説明しよう。あ、アプリを止めたいときはCtrl+Cを押してくれ。

mount_proc

server.mount_proc('/') { |req, res| 処理 }

mount_procメソッドはurlパスにアクセスされた時の挙動を定義する。urlパスに対してHTTPリクエスト(req)とHTTPレスポンス(res)を取って処理を記述する。最低限必要なのはレスポンスのbody(本文)に文字列を代入してやることだ。

まって!HTTPいうたらなんづら?

ここで根本的な話をしよう。そもそもHTTPとはなんだ? 知っての通りHyper Text Transfer Protocolの略字であり、ハイパーテキストすなわちHTMLやXMLを通信するために開発されたプロトコルだ。もちろん、プレーンテキストだけではなくみんなが使っているように画像や音声といったバイナリデータのやりとりも出来る。 (HTMLはHyperTextMarkupLanguageの略だよ、知ってるよね)

では、HTTPはどういう通信なのか。この形式はリクエスト/レスポンス型と呼ばれるが、まずサーバーに対して何らかのリクエスト(処理の要求)が送信される。リクエストを受信したサーバーはそれに対してレスポンス(処理結果)を返す。

サーバーが返すレスポンスは特に説明する必要がないだろう。いつもブラウザで表示されているようにHTMLファイルなどが返って来る。問題はリクエストだ。今日はHTTPリクエストについて重要なことを二つだけ覚えてくれ。メソッドとURLだ。メソッドとはいわば、「何をするのか」という情報だ。普段ブラウジングしていてもあまり意識をhことはないだろうが、HTTPはリソース(resource)を中心に考えられている。

リソースとはなんだ? 言ってみれば情報の単位だ。Railsに触れたことがある人ならデータベース上のテーブルと対応しているmodelクラスを書いたことがあるだろう。例えばname, email, encrypted_passwordといった属性を持つUserクラスとかね。まさにこういったものがリソースの例だ。

そしてみんなが口にしているURLという単語そのものが「Uniform Resource Locator」であり、一意にリソースの位置を指定するものという意味なんだ。

HTTPのメソッドたち

代表的なメソッド、というより一般に使われるメソッドだけここでは説明しよう。

  • GET:指定データの情報を見る、ダウンロードする
  • POST:データセットを渡して新規作成する
  • PUT:データセットを渡して更新する
  • DELETE:指定データを削除する

気づいたかもしれないがこの4つはよくCRUDと呼ばれるデータへの基本操作だ。Create/Read/Update/Delete、まるでSQLのようだろう? リソースがこれら全ての操作を可能としている場合、CRUDfulなんて呼んだりもするよ。そう、みんなが大好きなActiveRecordもこういう操作が可能だね。少し感づいてきた?

例えばhttp://neko_daisuki.com/userをURLとしよう。userはさっき上げたようにリソースの例だ。userの情報を得たいのならこのURLに対してGETメソッドでリクエストすればいい。きっとUserの情報をHTMLやJSONで返してくれるだろう。userの情報を作成・変更したいのならPost/Put、削除したいのならDeleteメソッドでリクエストすればいい。つまり、URIで指定されたリソースに対して、何をするかはメソッドによって決まるってワケだ。

なお、普通にブラウザでurlを入力してアクセスした場合はGetメソッドでリクエストされる。そりゃあそうだ。 冒頭のサンプルコードでもブラウザでアクセスするとこんな表示が出て来る。ここを見るとGETでアクセスされたことがわかるだろう。

localhost - - [22/Aug/2017:23:24:03 JST] "GET /teapot HTTP/1.1" 200 36

trapについて

一応、コードの中に書かれているtrapについても説明しとこう。これは何のために書かれているかと言えばCtrl+Cを押してサーバアプリを終了させるための記述だ。実はtrapはUNIXのシグナルを受け取った時の処理を定義するものなんだ。

trap(:INT){ server.shutdown }

(:INT)は定義するシグナルの種別であり、INTは割り込み(interrupt)シグナル。まぁ要するに割り込みキーであるCtrl+Cが押されたときのシグナルだね。そして、ブロック内がシグナルを受けたときに実行する処理だ。HTTPServerオブジェクトを停止させているというワケ。

<< 前のチャプターへ戻る | 次のチャプターへ進む >>