AWS SDK for Ruby version2 Released!

AWS SDK for Ruby version2 Released!

Clock Icon2014.09.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。望月です。
全国3000万人のAWS SDK for Rubyファンの皆様お待たせしました。本日ついにAWS SDK for RubyのメジャーバージョンアップであるAWS SDK for Ruby 2(以下 SDK v2)がリリースされました。

今までもDeveloper Previewとしてリリースされていましたが、これで正式版となったわけです。今日はインストール方法とバージョン2での新機能、今までのAWS SDK for Ruby(以下SDK v1)との違いなどについて私が気付いた点をまとめたいと思います。

インストール

以前までと同様、Rubygemsによってホストされていますので、gemコマンドでインストールします。ただしgem名はaws-sdk-coreとなっていますので注意して下さい。

$ gem install aws-sdk-core
...
$ ruby -r aws-sdk-core -e 'puts Aws::VERSION'
2.0.0

正常にインストールされた場合、バージョン番号が表示されると思います。

新機能

特筆すべきfeatureはほとんどREADMEに書かれているので、それを試してみました。

簡単なページング

APIリクエストに対して大量の結果が返される場合、一度に返される量を制限する必要があります。例えばS3のListObjectsの場合、API上ではtokenとして表現されているので、AWS CLIでは以下のような感じになります。

$ aws s3api list-objects --bucket mochizuki-bucket --profile default --max-items 10
{
    "NextToken": "None___10",
    "CommonPrefixes": [],
    "Contents": [
    <10個分のObject>
    ]
}
# 前のAPIレスポンスのNextTokenを指定
$ aws s3api list-objects --bucket mochizuki-bucket --profile default --max-items 10 --starting-token None___10
{
    "NextToken": "None___20",
    "CommonPrefixes": [],
    "Contents": [
    <10個分のObject>
    ]
}

SDK v1 で記載すると、毎回リクエストの度にmarkerを取得し、パラメータにセットし、APIリクエストを実行する、という必要があり非常に面倒でした。ですが、SDK v2でPageableResponseクラスというものが作成され、そのレスポンスクラスがページング処理のための便利な機能を持っています。実際にコードを見てみましょう。

require 'aws-sdk-core'

s3 = Aws::S3::Client.new

resp = s3.list_objects(bucket: 'mochizuki-bucket', max_keys: "10")
resp.contents.each{ |obj| puysobj[:key] }

# 続きがあるかどうかを判定
until resp.last_page?
  resp = resp.next_page # 次のリソースを取得 = APIコール実施
  resp.contents.each{ |obj| puts c[:key] }
end

last_page?next_pageを利用しました。意味は名前を見ると通じるかと思いますが、last_page?はこれが最後の取得出来るリソースかどうかを判定し、next_pageで次の10個のリソースを取得しています。これ以上取得できるリソースがない状態でnext_pageを実行すると、LastPageErrorが発生するので注意しましょう。

また、each_pageという、全ページを順番に取得して処理を実施するメソッドも用意されています。全リソースに対して必ず処理を実施する場合はかなり便利だと思います。上の例は、以下の様に書きなおすことが出来ます。

require 'aws-sdk-core'

s3 = Aws::S3::Client.new

s3.list_objects(bucket: 'mochizuki-bucket', max_keys: "10").each_page do |resp|
  puts resp.contents.map{ |obj| obj[:key] }
end

だいぶ記述がすっきりしました!

Waiters

AWSのAPIは、基本的にあるリクエストに対するレスポンスを即座に返しますが、そのリクエストで意図した結果が必ず起こるとは限らない、というところには注意が必要です。例えばstart-instancesというAPIは、Stop状態のEC2インスタンスを起動するためのAPIです。APIリクエストに成功すると、HTTPコード200 とともにインスタンスの情報が返ってきます。ですが、HTTP 200を受け取ったからといって、このインスタンスがrunningになるとは限りません。例えば起動処理中にAWSのデータセンターに隕石が落ちてDCが破損した場合(参考)、そのEC2の最終的な状態は保証できません。
何が言いたいかというと、APIレスポンスが返ってきた後、その対象が望むべきStatusになっているかどうかを暫くの間監視しておく必要があるのです。 これを普通にやろうとすると、APIリクエスト後、定期的にdescribe-instanceを叩いてStatusの値をチェックして、何回以内に成功しなければ異常と判断されるので例外を投げる、、等、だいぶ面倒なのですが、SDK v2では各サービスのクライアントクラスにwait_untilというメソッドが追加され、このあたりの制御が簡単に行えるようになりました。コードを見てみましょう。

require 'aws-sdk-core'

ec2 = Aws::EC2::Client.new

begin
  ec2.start_instances(instance_ids: ['i-1234567'])
  ec2.wait_until(:instance_running,  instance_ids:['i-1234567'])
  puts "instance running"
rescue Aws::Waiters::Errors::WaiterFailed => error
  puts "failed waiting for instance running: #{error.message}"
end

start-instancesを実行した後、7行目のwait_untilの部分でステータスのポーリングを実施し、ステータスがinstance_runningになるまで監視してくれます。ただし、一定期間内にステータスが想定のステータスにならなかった場合、例外となります。
以下のように記述することで、監視のインターバルや最大リトライ数を調整することもできます。

require 'aws-sdk-core'

ec2 = Aws::EC2::Client.new

begin
  ec2.start_instances(instance_ids: ['i-1234567'])
  ec2.wait_until(:instance_running,  instance_ids:['i-1234567']) do |waiter|
    waiter.interval     = 5 # number of seconds to sleep between attempts
    waiter.max_attempts = 1 # maximum number of polling attempts
  end
  puts "instance running"
rescue Aws::Waiters::Errors::WaiterFailed => error
  puts "failed waiting for instance running: #{error.message}"
end

対話型コンソール

SDK v2のgemに付随して、aws.rbというコマンドもついてきます。これはirbやpryといった対話型コンソールで、手元で簡単にSDKの動きを確認したい時に使えます。
...と思ったら、SDK v1にもaws-rbというのがありました。(このブログを書いていて初めて知りました。。。)

SDK v1との相違点

SDK v2のREADMEにも記載されていますが、セマンティックバージョニングを採用しているので、メジャーバージョンアップには互換性のない変更も含まれます。
上のコードを見ていて気づかれた方もいるかと思いますが、SDK v1とv2では名前空間が異なります。SDK v1ではAWSモジュールに含まれていましたが、SDK v2ではAwsモジュールとなります。大文字小文字に注意しましょう。

また、SDK v1で利用していたAPIの高度なラッパークラスであるResourceクラス(AWS::EC2::Instances等)は、SDK v2の2014/09/26時点ではexperimentalとされています。さらに、aws-sdk-resourcesという別のGemに切り出されたようなので、利用する際には十分に注意しましょう。追加でインストールする場合には、gemコマンドを使ってインストールします。

$ gem install aws-sdk-resources

まとめ

Githubの履歴を見ていたら、SDK v2のrc1がリリースされたのが昨年の11月ということで、最初のrcから1年弱が経過して、ようやく正式版リリースとなりました。まだまだ開発途中の機能もあるようですが、興味のある方は使ってみてはいかがでしょうか。

参考資料

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.