概要
AWS S3 の API を使うプログラムを LINQPad で作成し、AWS SDK for .NET の使い方を把握する。
対象読者
- AWSを使うアプリケーション開発をこれから始めようとしている
- C# の構文や .NET の API についてある程度の知識を持っている
- LINQPad Premium を持っている ※
※LINQPad には無料の Free Edition もあるが、この記事では有償版である Premium Edition を前提に書く。まだ持ってない?買おう!
なんでLINQPad?
LINQPad は Visual Studio よりも一億万倍くらいお手軽に .NET プログラムを作成できる開発・実行環境。小さいプログラムの作成に特化していて、プログラミングやAPIの学習にとても向いている。
LINQPad を使って学習すると次のような良いことがある。
- コードが一瞬で実行できるので、結果がすぐわかる
- 入力補完が効くので、APIの名前などを正確に覚えてなくても書ける
- 変数のダンプが見やすいので、API仕様の理解やデバッグが捗る
また、実際の開発現場でも下記のようなときに役立つ。
- テストデータを作って S3 や DynamoDB に突っ込む
- AWSコンソールを開かずにEC2インスタンスの状態を表示する
- 不慣れなAPIを使うアプリケーションのサンプル実装
AWS SDK for .NET を使う準備
AWS SDK for .NET を使うには、まず AWS の認証情報を開発端末に登録する必要がある。
手順:
- LINQPad を起動し、NuGet で AWSSDK.Core をインストール
- AWS コンソールで開発用IAMユーザの AccessKey を発行
- 発行した認証情報を開発端末に登録するコードを書いて実行
- LINQPad を再起動
NuGet で AWSSDK.Core をインストール
まず AWSSDK を使用するための NuGet パッケージをインストールする。
手順:LINQPadを起動後、エディタで右クリック、NuGet Package Manager
Search online に ASSDK と入力、リストに表示された AWSSDK - Core Runtime を Add To Queryする
これで LINQPad の準備は完了。
AccessKey/SecretKeyを発行
開発用の認証情報を発行する。手順:
AWSコンソールにログイン
⇒ IAM
⇒ Users
⇒ 開発用のユーザを選択(なかったら作る)
⇒ Security credentials
⇒ Access keys
⇒ Create access key
ここに表示された Key は次で使う。
※Secret access key は絶対に他の人に見せてはいけない。認証情報の登録がすんだら速やかに破棄すること。万が一漏洩した場合は、この画面でキーを削除して無効化できる。
発行したSecretKeyを開発端末に登録するコードを実行
LINQPad に戻って、Language を C# Program
にして認証情報を登録するコードを書く。
void Main()
{
var options = new Amazon.Runtime.CredentialManagement.CredentialProfileOptions
{
AccessKey = "accesskey", // ここに AWSコンソールで発行したKeyを入れる
SecretKey = "secretkey", // コードを実行したらすぐに消してね
};
var profile = new Amazon.Runtime.CredentialManagement.CredentialProfile("default", options);
profile.Region = Amazon.RegionEndpoint.APNortheast1; // 使うリージョンに合わせて変えて
var netSDKFile = new Amazon.Runtime.CredentialManagement.NetSDKCredentialsFile();
netSDKFile.RegisterProfile(profile);
}
5, 6行目に先に発行したKeyを設定し実行すると開発端末に認証情報が登録され、以後特に指定しない限りはこの認証情報が使われるようになる。
コードを実行するにはF5キーまたはエディタ左上の ▶ をクリック。
実行が完了したら LINQPad を再起動する。(再起動しないとAWSSDKが認証情報を読み込んでくれないっぽい)
これで AWS SDK for .NET を使う準備が整った。
初めてのS3 AWS SDK for .NET 編
ここではS3に次の操作を実行するプログラムを作成する。
- バケットを作成
- バケット一覧を取得
- オブジェクトを作成
- オブジェクト一覧を取得
- オブジェクトの削除
- バケットの削除
プログラム作成を通して、AWS SDK for .NET のお作法的なことを把握してもらえるとよい。
コードを書き始める前に知っておいてほしいこと
非同期メソッドを使おう!
.NET Framework 版の AWSSDK には同期版・非同期版それぞれの API が提供されているが、.NET Core 版には非同期版しかない。なので特に理由がなければ非同期版APIを使っておくのがよい。非同期で書いておくと LINQPad で書いたコードを後で Lambda に移植したりするのも楽だし。
.NET Framework 版の ListBucket には同期・非同期両方のメソッドがある
.NET Core版 の ListBucket には非同期のメソッドしかない
LINQPad で非同期メソッドを使うための手順
- Language を
C# Program
に設定 ※ -
void Main()
をasync Task Main()
に変える - Taskにカーソルをあてて using System.Threading.Tasks する
※毎回 Language を C# Program
に変えるのがめんどくさいときは、デフォルト設定を変えられる。
手順:メニュー Edit ⇒ Preferences ⇒ Query ⇒ Default Query Language を C# Program
これで準備完了。
AWSSDK.S3 をインストール
S3 を使うには NuGet パッケージ AWSSDK.S3
をインストールする。
手順:エディタで右クリック、NuGet Package Manager
Search online に ASSDK.S3 と入力、リストに表示された AWSSDK - Simple Storage Service を Add To Query する
なお、S3以外のサービスも同様に AWSSDK.{サービス名} という NuGet パッケージで提供されている。EC2 なら AWSSDK.EC2
、SQS なら AWSSDK.SQS
など。
サービスクライアントを作成
S3 の API を呼ぶには Amazon.S3.AmazonS3Client クラスを使う。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
}
入力補完を活用する
LINQPad は入力の候補を提示・補完してくれるので、クラスの名前を覚えてなくても Amazon.
と入力すればだいたいなんとかなる。
S3 の API も同様に、s3.
と入力すれば一覧表示される。
ちなみにこの入力候補は、.
や (
を打った時のほか、Ctrl+Space
で表示させることもできる。
ListBuckets
バケット一覧を表示してみる。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
// list buckets
var listBucketResponse = await s3.ListBucketsAsync();
listBucketResponse.Dump();
}
レスポンスを確認したかったらとりあえず Dump() しておくとよい。下記のように出力できる。
Dumpされた内容から、バケットに関する情報は Buckets プロパティに入ってきそうだなーと推測できる。(まだバケット無いけど)
PutBucket
バケットを作ってみる。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
// put bucket (create new bucket)
var putBucketResponse = await s3.PutBucketAsync("my-favorit-baketto");
// list buckets
var listBucketResponse = await s3.ListBucketsAsync();
listBucketResponse.Dump(); // バケット一覧を表示
}
作成したバケットの名前と作成時刻が表示された。
ここから次のようなことがわかる。(ドキュメントを読まなくても!)
- ListBucketResponse.Buckets にバケット情報 S3Bucket がリストで入る
- S3Bucket には BucketName と CreationDate がある
- バケット名を取得したかったら
string bucketName = listBucketResponse.Buckets[0].BucketName;
のように書けばよい
AWS コンソール上でもちゃんと作成されてることが確認できる。
PutObject
バケットの中にオブジェクト(ファイル)を作ってみる。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
PutObjectResponse putobjres = await s3.PutObjectAsync(new PutObjectRequest()
{
BucketName = "my-favorit-baketto",
Key = "test",
ContentBody = "i am a pen."
});
}
PutObjectにはS3のバケット名やキー名、コンテンツをパラメータとして渡す必要がある。このパラメータに PutObjectRequest というクラスを使っている。また、APIのレスポンスは PutObjectResponse というクラスのオブジェクトで帰ってくる。
PutObjectRequest や PutObjectRequest クラスは別の名前空間にあるので using が必要な点に注意。
AWSコンソール上でもこのコードで作成したオブジェクトを確認。
AWSSDKのクラス構造
上記のコードで使ったクラスは下記の構造になっている。
- Amazon.S3
- AmazonS3Client
- Amazon.S3.Model
- PutObjectRequest
- PutObjectResponse
- その他のRequest
- その他のResponse
これはS3に限らず、他のAWSサービスのAPIでも同様なので覚えておこう。
あらかじめ名前空間 Amazon.{サービス名}
と Amazon.{サービス名}.Model
を using しておくのもよい。
ListObject
バケットの中のオブジェクト一覧を取得する。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
var listObjRes = await s3.ListObjectsAsync("my-favorit-baketto");
listObjRes.Dump();
// ListObjects のパラメータには ListObjectsRequest クラスを使うこともできるが、
// 上記のようにクラスを作成せずに使える場合もある。
}
PutObject で作成した test が表示された。
キー名を取得したかったら string key = listObjRes.S3Objects[0].Key;
のようにすれば良い。
GetObject
オブジェクトの中身を取得する。これはひと手間必要。
GetObjectResponse を Dump() するとわかるが、GetObjectResponse にはコンテンツを直接取得するためのプロパティやメソッドがない。その代わりに ResponseStream が用意されているのでここから読みとる必要がある。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
var getObjectResponse = await s3.GetObjectAsync("my-favorit-baketto", "test");
// StreamReader を使って ResponseStream から文字列を読む
using (var sr = new StreamReader(getObjectResponse.ResponseStream))
{
var content = await sr.ReadToEndAsync();
Console.WriteLine(content);
}
// 次のようにファイルに保存することもできる。
// getObjectResponse.WriteResponseStreamToFile(@"C:\Temp\test");
//
// ※StreamReader と WriteResponseStreamToFile を同時に使うことはできない。
}
DeleteObject / DeleteBucket
上で作ったオブジェクトやバケットはいらないので削除する。
async Task Main()
{
var s3 = new Amazon.S3.AmazonS3Client();
var deleteObjRes = await s3.DeleteObjectAsync(new DeleteObjectRequest()
{
BucketName = "my-favorit-baketto",
Key = "test",
});
var deleteBucketRes = await s3.DeleteBucketAsync("my-favorit-baketto");
}
と、ここまでに使用したAPIの名前は {List/Get/Put/Delete}+{Bucket/Object} という規則になっている。これは他のAWSサービスのAPIでも同様の規則となっているので覚えておくとよい。
まとめ
S3 を操作するコードを LINQPad で作成した。また、作成を通して AWS SDK for .NET の使う上で押さえておきたいポイントも書いた。これらのポイントは S3 に限らず、ほかのAWSサービスでも共通。
- APIを使うまでの流れ:NuGetパッケージ入れる ⇒ クライアント作る ⇒ API呼ぶ
- NuGetパッケージは AWSSDK.{サービス名} で提供されている
- APIの使用に必要なクラスは主に3種類
- Amazon.{サービス名} 名前空間
- Amazon{サービス名}Client
- Amazon.{サービス名}.Model 名前空間
- {API名}Requset
- {API名}Response
- Amazon.{サービス名} 名前空間
- APIの名前は次のような動詞+対象名になっていることが多い。正確に覚えてなくても入力補完を頼れば使える。
- List
- Get
- Put
- Delete
- Describe
- .NET Core 版 AWSSDK には非同期 API しか用意されていない
- 困ったら Dump() してみる