CTC 教育サービス
[IT研修]注目キーワード Python Power Platform 最新技術動向 生成AI Docker Kubernetes
前回の内容からしばらく間があき、Ruby、Railsもさまざまなアップデートリリースが行われています。
直近のものではRubyが2.1.4(*1)、Railsはそれぞれ3.2.20、4.0.11、4.1.7(*2)、また4.2系のbeta版として4.2.0.beta4(*3)がリリースされました。安定版のリリースはセキュリティフィックスのようですので、早めにアップデートすることをお勧めいたします。
さて前回はRubyでRESTfulなWebAPIを構築するためのライブラリ「Grape」をご紹介し、簡単な検索APIを実装してみました。今回はその続きとして以下のような機能を実装してみたいと思います。
動作環境は前回同様、以下の通りです。(*4)
さっそく登録・更新APIの実装といきたいところですが、その前に少しばかりソースを修正しておきましょう。「app/api/zip_api.rb」を以下のように修正します。
class ZipAPI < Grape::API format :json helpers do def search_address Zip.where(zip_code: params[:zip_code]).first end def not_found_error error!("404 Not Found", 404) end end namespace "zip/:zip_code" do get do zip = search_address if zip zip.to_json else not_found_error end end end end
この修正では郵便番号が見つからない場合のエラー処理の追加、及びモデルへの検索処理を別メソッドへ切り出しています。
ここで利用したメソッドのうち、特筆すべきものについて以下に一覧を示します。
メソッド | |
helpers(new_mod=nil, &block) | 引数&block定義内にヘルパーメソッドやグルーピングしたい処理を記述する。 [new_mod] 上記の処理を定義したモジュールを指定 [block] 上記の処理を定義 |
error!(message, status=nil, headers=nil) | 処理をエラーとしてレスポンスを返送する。 [message] 返送するエラーメッセージを指定 [status] 返送するステータスコードを指定(未指定時は500) [headers] レスポンスヘッダに追加する情報をHashで指定 |
namespace(space=nil, options={}, &block) | ブロック内の処理にパスプレフィックスを設定する。 [space] パスプレフィックスを指定 [options] パスプレフィックス内のルートパラメータ設定するバリデーションを指定 [&block] パスプレフィックスを設定する処理を定義 |
それでは登録・削除APIを実装していきましょう。「app/api/zip_api.rb」を以下のように修正します。
class ZipAPI < Grape::API format :json helpers do def search_address Zip.where(zip_code: params[:zip_code]).first end def not_found_error error!("404 Not Found", 404) end # 以下を追加 # 追加処理用のヘルパーメソッド def add_zip zip = search_address || Zip.new(zip_code: params[:zip_code]) zip.update(address: params[:address]) end # 以下を追加 # 削除処理用のヘルパーメソッド def remove_zip zip = search_address zip.destroy if zip end end namespace "zip/:zip_code" do get do zip = search_address if zip zip.to_json else not_found_error end end # 以下を追加 put do add_zip status 204 end # 以下を追加 delete do if remove_zip status 204 else not_found_error end end end end
helpersメソッドのブロック内ではモデルの登録(更新)処理を呼び出すadd_zipと、モデルの削除処理を呼び出すremove_zipの2つのメソッドを定義しています。その上でそれぞれの処理をHTTPリクエストで受けられるように、putメソッドとdeleteメソッドを使用しています。
それでは動作確認を行ってみましょう。今回も前回同様APIらしく開発者ツールのコンソールよりXMLHttpRequestを利用してアクセスしてみます。以下のJavaScriptを実行してみましょう。
// 登録処理 var xhr_put = new XMLHttpRequest; xhr_put.open("put", "http://localhost:3000/zip/171-0022"); xhr_put.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr_put.send("address=東京都豊島区南池袋"); // 削除処理 var xhr_del = new XMLHttpRequest; xhr_del.open("delete", "http://localhost:3000/zip/171-0022"); xhr_del.send();
登録後、削除後でそれぞれ前回の参照用のJavaScriptを実行するときちんと登録(更新)もしくは削除されていることがわかるかと思います。
ここで利用したメソッドのうち、特筆すべきものについて以下に一覧を示します。
メソッド | |
status(status=nil) | 返送するステータスコードを指定する。 [status] ステータスコードを指定 |
続いてバリデーションを実装してみます。登録のPUTリクエストを受けた際、以下のリクエストパラメータの入力値チェックを行います。
それでは「app/api/zip_api.rb」を編集しましょう。既存のputメソッド呼び出しの上に、paramsメソッドの呼び出しを追加します。
class ZipAPI < Grape::API (略) # 以下の4行をputメソッド呼び出しの上に追加 params do requires :zip_code, type: String, regexp: /^\d{3}-\d{4}$/ requires :address, type: String end put do add_zip status 204 end (略)
paramsメソッドのブロック内にバリデーションの処理を記述していきます。バリデーションには以下のメソッドとメソッドの引数を設定することができます。
メソッド | |
requires(*attrs, &block) | 入力必須とするパラメータと入力チェックを行うパラメータを指定する。 [*attrs] 第一引数に入力必須とするパラメータ名を指定 第二引数以降にチェックオプションをHashで指定(後述) [&block] リクエストパラメータがネストしている際、ネスト内パラメータの入力チェックを定義(以下のようなリクエストパラメータ) {name: {given_name: "Hiroshi", family_name: "Matsunaga"} } |
チェックオプション | |
type | 入力タイプをクラスで指定 |
values | 入力を制限する項目を指定 |
regexp | 入力チェックを行う正規表現を指定 |
default | 入力がなかった場合のデフォルト値を指定 |
最後に簡単な認証機構として、Basic認証を導入してみたいと思います。ここでは登録及び削除リクエストに対してBasic認証を設定してみます。「app/api/zip_api.rb」を以下のように編集します(*5)。
class ZipAPI < Grape::API (略) group do # 以下の3行をgroupメソッドのブロック定義内に追加 http_basic do |user_name, password| {"user" => "pass"}[user_name] == password end params do requires :zip_code, type: String, regexp: /^\d{3}-\d{4}$/ requires :address, type: String end (略)
編集が終わったら前述した登録処理のJavaScriptを実行してみましょう。下記のように認証用のダイアログが出てくるかと思います(*6)。
認証ダイアログにユーザ名とパスワードを入力してもいいですが、せっかくなのでJavaScriptを少し改変します。
// 登録処理 var xhr_put = new XMLHttpRequest; // コネクションオープン時にユーザ名、パスワードを指定 xhr_put.open("put", "http://localhost:3000/zip/171-0022", true, "user", "pass"); xhr_put.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr_put.send("address=東京都豊島区南池袋");
上記のJavaScriptを実行すると、きちんと登録処理が行われるかと思います。
前回・今回と2回にわたってGrapeの紹介をいたしました。前回も書きましたがRailsアプリケーションは勿論のこと、Rackアプリケーションであれば手軽にWebAPIを作成することができますので、是非お試しください。
それでは、Enjoy Ruby!
*1 : https://www.ruby-lang.org/ja/news/2014/10/27/ruby-2-1-4-released/
*3 : http://weblog.rubyonrails.org/2014/10/30/Rails-4-2-0-beta4-has-been-released/
*4 : 執筆時のそれぞれの最新版、Chrome38、Ruby2.1.4、Rails4.1.7、Grape0.9.0でも動作確認をしています。
*5 : ここではユーザ名("user")、パスワード("pass")をソースコード上に記載していますが、当たり前ながら普通はDBなどから取得することになると思います。
*6 : 削除リクエストでも同様に、認証ダイアログがでてきます。
[IT研修]注目キーワード Python Power Platform 最新技術動向 生成AI Docker Kubernetes