山本と申します。
弊社のTeamFakeというチームに属しており、Rubyを中心としながらもiOSやAndroidアプリ、IoT関連事業など幅広い技術をカバーしているのが強みです。
今回は我がチームのコア技術であるRubyに関するエントリーとなります。
AWS SDK V2への移行
AWS SDK V2がリリースされて1年以上経っていますが、V1で書いていたコードを全面的にV2に対応する機会があったので、使えなくなったメソッドとその置換について、V1と比較しながらS3を中心に紹介します。
トップレベルの名前空間が変わってます
これは言わずもがなですが、
- V1 → AWS
- V2 → Aws
のように、トップレベルにおける名前空間の表記が変わっています。AWS.config とか書くと怒られます。
イニシャライズの変更
# [V1]
AWS.config(
  region: 'xx-region'
  ...
)
# [V2]
Aws.config.update(
  region: 'xx-region'
  ...
)
S3バケットオブジェクトの取得
以下からメインになってきますが、S3に関する処理で変更が多くありました。まずは、バケットを指定してのオブジェクトを取得する方法が変わってます。
# [V1]
s3 = AWS::S3::new
@bucket = s3.buckets['bucket-name']
# 関連をわかりやすくするためインスタンス変数にしています
V1ではこうすることで、@bucket は bucket-name 以下に存在するオブジェクトを扱うことができました。
# [V2]
s3_res = Aws::S3::Resource.new(region: 'xxx')
@bucket = s3_res.bucket('bucket-name')
V2からは、新たに加わったResourceクラスを使ってbucket名を指定してのオブジェクト取得を行います。
S3特定のオブジェクト以下のリソースを取得する
# [V1]
@bucket.objects.with_prefix('hogehoge').each do |obj|
  ...
end
V1では、with_prefix というalias_method_chainな書き方で、指定した名前以下のリソースにアクセスできましたが以下に変更になっています。
# [V2]
@bucket.objects(prefix: 'hogehoge').each do |obj|
  ...
end
prefixオプションで明示的に指定する感じですね。
特定のオブジェクトを読み込む
# [V1]
@bucket.objects['hogehoge.txt'].read
V1では、指定したオブジェクトに対しreadとすることでファイル自体にアクセスできましたが、V2からはプロパティ群が厳密になったようで、ファイル内容にアクセスするには少し複雑になりました。
# [V2]
@bucket.object('hogehoge.txt').get.body.read
getで取得できるあらゆる情報の中の一つにbody情報があり、readすることでデータとして取得できるようになります。
また、objects ではなく単数系のobjectになっていることも注意です。
ファイルをアップロードする
# [V1]
@bucket.objects['hogehoge.txt'].write('sample')
V1ではこれで、本文がsampleと書かれたhogehoge.txtというファイルがアップロードできました。
また、IOやStringでなくても、ファイルパスを指定するだけでその内容がアップロードできました。
# [V2]
@bucket.object('hogehoge.txt').put(body: 'sample')
V2ではwriteがputになり、bodyにIOオブジェクトかStringを記述することでアップロードされます。少し厳密になり、ファイルパスの指定は効かなくなりました。
ちなみに、Aws::S3::Clientを使ってもアップロードできます。
paperclipを使っている場合はバージョンアップもお忘れなく
ファイル管理を担ってくれるpaperclipですが、V2に対応するためには最新バージョン(5系)にする必要があります。ただ、paperclipを4->5にすることは、特にコストはかかりませんでした。
さいごに
S3に関しては、Read,Writeともに互換性がほぼない印象です。それでいて、V1->V2の対応表のようなものはないので、Try&Errorを繰り返して地道に修正していくしかないと思います。この記事が、移行に少しでもお役に立てれば幸いです。
ちなみに、S3以外ではSNSやAutoScalingもV2へ移行したのですが、イニシャライズが変わるぐらいでとくに対応がいりませんでした。(そんなに複雑な処理をしていないのですが)
