はじめに
みなさん、S3使ってますか?
- バックアップ
- Webアプリケーションからファイルをアップロード/ダウンロード
- フロントエンド用のjsやHTML保存
など色々な場面でS3は使われますね!
その中で、S3で最近出来るようになった条件付き書き込みについて紹介します。
簡単に言うと上書き防止機能
です
条件付き書き込みが出来るようになる前
ファイルをアップロードする際に、S3では
- PutObject
- CompleteMultiPartUpload(マルチパートアップロード)
を利用することになると思います。
アップロードする際はファイル名の命名規則などを取り決めてアップロードすることになると思いますが、その際に考えるべきことの1つとして、同名ファイルがアップロードされそうになった時に、どうするかという問題があります。
上書きしちゃっても問題ないファイルに関しては良いのですが、何かしらの理由で上書きされたくないってこともあると思います。
その場合、一度GetObjectしてファイルが存在するかチェックしたり、DBにアップロードしたファイル名の履歴を取っておいて既にアップロードされていないかチェックしたりすることになります。
これでも問題ないっちゃ問題ないんですが、なるべく処理はシンプルにしたいですよね
そこで、条件付き書き込みの出番です!
条件付き書き込みが出来るようになってから
API リクエスト時にif-none-match
ヘッダーを付与することで、既にアップロードされているファイルパスの場合はエラーを返してくれるため、上書きされる心配がなくなります。
では、AWS CLIで試してみます!
まず、条件付き書き込みでやらない場合ですが、以下のように上書きアップロードできます。
※${S3バケット名}
の部分はご自身の環境のS3バケットを指定してください。
# 適当なファイルを作成
touch ./duplicate.json
# ファイルをアップロード
aws s3api put-object \
--bucket ${S3バケット名} \
--key hoge/duplicate.json \
--body ./duplicate.json
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"ServerSideEncryption": "AES256"
}
aws s3api put-object \
--bucket ${S3バケット名} \
--key hoge/duplicate.json \
--body ./duplicate.json
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"ServerSideEncryption": "AES256"
}
次に、条件付き書き込みでアップロードするために--if-none-match "*"
を付けて実行します。
すると、PreconditionFailed
になりアップロードが失敗することがわかります。
aws s3api put-object \
--bucket ${S3バケット名} \
--key hoge/duplicate.json \
--body ./duplicate.json \
--if-none-match "*"
An error occurred (PreconditionFailed) when calling the PutObject operation: At least one of the pre-conditions you specified did not hold
もちろんファイルが存在しない場合は成功します。
aws s3api put-object \
--bucket ${S3バケット名} \
--key hoge/duplicate.json \
--body ./duplicate.json \
--if-none-match "*"
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"ServerSideEncryption": "AES256"
}
おわりに
今回はS3の条件付き書き込みについて、説明しました。
意外と知らないが、使うことが割と多い機能だと思うので覚えておきましょう!!!