RustでのGoogle Cloud Storageの使い方
こんにちは。PharmaXエンジニアリング責任者の上野(@ueeeeniki)です。
PharmaXでは、最近Rustの採用を一部のプロダクトから始めています。
PharmaXでは、主要アプリケーションのインフラにGCPを利用しているので、当然、GCSもRustで使いたくなります。
一方、GCPが提供しているCloud SDKには、当然Rust用などはなく、GCSの公式ドキュメントにもRustでの使い方など載っているはずもありません。
こちらのCloud SDKの公式ドキュメントには、下に添付するような対応言語が記載されています。
調査をしてみても、RustでのGCSの使い方の解説記事は少ないのが現状です。
そこで今回は、RustでGCSの使い方を解説してみたいと思います。
Rustでなくとも、SDKが対応していない言語でGCSを使いたい方には参考になるかと思います。
Cloud Storageとは& Cloud Storageのセットアップ
Cloud Storageそのものについてはすでに多くのドキュメントや解説記事があるため、ここでは公式ドキュメントを引用するだけに留めておきます。
Rustのライブラリを使ったGCS APIの使い方
crateの選定
ここでは、cloud-storageというcrate(ライブラリ)を使ってみたいと思います。
crates.io を見てみると、最新の更新が1年前なのは気になりますが、下図のように継続的に使われていそうなので、こちらのライブラリを使ってみます。
サービスアカウントの準備
GCPを使ったことがある方はお分かりになるでしょうが、GCPのリソースを外部から操作するにはサービスアカウントというものが必要です。
公式ドキュメントによれば、このcrate(cloud-storage)のすべての機能を使うにはストレージ管理者のロールが付与されたサービスアカウントが必要です。
このあたりの詳細は省略しますが、サービスアカウントは「IAMと管理」から作成可能です。
Cloud Storageのバケットごとに権限タブで、そのバケットに権限を持っているアカウント一覧を見ることができます。
そして、json形式の秘密鍵を作成してダウンロードします。
そのファイルのパスをGOOGLE_APPLICATION_CREDENTIALS(SERVICE_ACCOUNTという変数名でもいい)という環境変数に設定してます。
このあたりは、Rustに限らずGCPを操作するライブラリの標準的な仕様ですね。
コードの書き方
早速、GCSに保存するためのコードを書いてみると以下のようになります。
let mut file = File::open("./prescriptions/sample.pdf")?;
let mut buf: Vec<u8> = Vec::new();
let _ = file.read_to_end(&mut buf)?;
let mime_type = "application/pdf";
let bucket_name = "bucket";
let folder_name = "folder";
let file_name = "sample.pdf";
let file_path = format!("{}/{}", folder_name, file_name);
let _object = cloud_storage::Client::new()
.object()
.create(&bucket_name, buf, &file_path, mime_type)
.await?;
ここでは、ローカルのフォルダ./prescriptions/sample.pdfを開き、バイト列で読み込んで保存することとします。
保存するためのbucketの名前やfolderの名前、ファイル名などは各自ご設定ください。
documentの形式であるMIME_TYPEの指定方法は、公式ドキュメントをご覧ください。
上記のようにDocument AIがサポートしてる形式を一覧で確認することができます。
今回はPDFで指定するようにします。
最後に
今回は、RustでGCSにファイルを保存する方法について解説をしました。
Rust以外の公式ドキュメントに載っていない言語をお使いの方の参考にもなったのではないでしょうか。
GCSに保存するだけなら、コードの記述量も非常に少なく簡単に書けることがわかっていただけたのではと思います。
Rustのような比較的新しい言語では、公式ドキュメントが対応していないことも多いのですが、GCSのようなメジャーなサービスではライブラリが開発されていることも多いです。
ぜひご自身で調査してお使いいただければと思います。