SlideShare a Scribd company logo
UnityのLambda APIを
DynamoDB APIっぽく使う
2017年3月17日
株式会社エクストーン 木野瀬友人
2017年サーバーレスの時代へ
API Gateway
(インターフェース)
Lambda
(ロジック)
DynamoDB
(データ保存)
AWS Mobile SDK for Unityで豊富なサポート
前出のAPIGatewayはない
DynamoDBのAPIがモダンで便利
DynamoDB
(データ保存)
Cognito
(ユーザー認証) Context.LoadAsync<Book>(bookID, (result) => {
Debug.Log(result.Response.Title);
}, null);
DynamoDB APIが便利な理由その1
指定したクラスで受け取れる
Unity
DynamoDB APIが便利な理由その2
アノテーションで細かな振る舞いを指定できる
[DynamoDBTable("EXAMPLE_TABLE")] // テーブル名のマッピング
public class IntegrationExample{
[DynamoDBHashKey]
public string RoomId;
[DynamoDBRangeKey]
public string Created;
[DynamoDBProperty("Message")] // カラム名のマッピング
public string TextMessage;
[DynamoDBIgnore]
public bool SomeFlag; // DinamoDBIgnore属性は無視される
private int _counter; // privateフィールドは無視される
}
DynamoDB APIが便利な理由その3
Global Secondary Index / Local Secondary Indexに対応
[DynamoDBTable("EXAMPLE_TABLE")] // テーブル名のマッピング
public class IntegrationExample{
[DynamoDBHashKey]
public string RoomId;
[DynamoDBRangeKey]
public string Created;
[DynamoDBProperty("Message")] // カラム名のマッピング
public string TextMessage;
[DynamoDBIgnore]
public bool SomeFlag; // DinamoDBIgnore属性は無視される
private int _counter; // privateフィールドは無視される
[DynamoDBGlobalSecondaryIndexHashKey("GSI-Key-Name")]
public string UserId;
[DynamoDBGlobalSecondaryIndexRangeKey("GSI-Key-Name")]
public string SomeRange;
}
別条件での検索と
そのページめくりに使用
DynamoDB APIが便利な理由その4
独自のConverterを指定できる
[DynamoDBProperty(typeof(DimensionTypeConverter))]
public DimensionType Dimensions;
public class DimensionType {
public decimal Length;
public decimal Height;
public decimal Thickness;
}
// 寸法文字列 "8.5x11x.05" を DimensionType に変換
public class DimensionTypeConverter : IPropertyConverter {
public object FromEntry(DynamoDBEntry entry) {
Primitive primitive = entry as Primitive;
string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
if (data.Length != 3) throw new ArgumentOutOfRangeException();
DimensionType complexData = new DimensionType {
Length = Convert.ToDecimal(data[0]),
Height = Convert.ToDecimal(data[1]),
Thickness = Convert.ToDecimal(data[2])
};
return complexData;
}
}
DynamoDB APIが便利な理由その5
複雑なオブジェクトにも対応
[DynamoDBTable("IntegrationExample")]
public class IntegrationExample{
[DynamoDBProperty(typeof(ListOfDocumentTypeConverter))]
public List<Document> Books;
[DynamoDBProperty]
public Dictionary<string,string> EJDictionary;
}
// 参照方法
Debug.Log(result.Response.Books[0]["Author"]); // Yamada Taro
Debug.Log(result.Response.EJDictionary["apple"]); // ringo
DynamoDBのカラムの例
VBのVariant型のようなもの
Dictionaryに対応
問題点:
✕ リクエスト(クエリ条件等)の指定はクライアント側からしかできない
✕ IAMの設定を間違えたら無関係のデータまで読めてしまう
  レコードごとに権限管理できるのか?
  できたとしても設定ミスを検知しにくい
  IAMにプレイヤーごとの権限管理を求めるのは間違っている気がする
 →熟練者のいない環境では怖くて使えない
問題点:
✕ リクエスト(クエリ条件等)の指定はクライアント側からしかできない
✕ IAMの設定を間違えたら無関係のデータまで読めてしまう
  レコードごとに権限管理できるのか?
  できたとしても設定ミスを検知しにくい
  IAMにプレイヤーごとの権限管理を求めるのは間違っている気がする
 →熟練者のいない環境では怖くて使えない
orz
そこでLambdaをかます
Lambda
(ロジック)
DynamoDB
(データ保存)
Cognito
(ユーザー認証)
Unity
DynamoDBへの
アクセスを制御
そこでLambdaをかます
Lambda
(ロジック)
DynamoDB
(データ保存)
Cognito
(ユーザー認証)
戻り値がJSON
DynamoDB APIが使えない
Unity
DynamoDBへの
アクセスを制御
Lambdaでの実装例
// リクエストを生成
var request = new InvokeRequest(){
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse
};
LambdaClient.InvokeAsync(request, (result) => {
// レスポンスをstringに変換
string json = Encoding.UTF8.GetString(result.Response.Payload.ToArray());
// 目的のオブジェクトに変換
var item = JsonUtility.FromJson<SomeApp.Model.IntegrationExample>(json);
Debug.Log(item.Message);
});
✕ アノテーション非対応
✕ GSI/LSI非対応
✕ Converter非対応
✕ Dictionaryに変換できない
Lambdaでの実装例
// リクエストを生成
var request = new InvokeRequest(){
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse
};
LambdaClient.InvokeAsync(request, (result) => {
// レスポンスをstringに変換
string json = Encoding.UTF8.GetString(result.Response.Payload.ToArray());
// 目的のオブジェクトに変換
var item = JsonUtility.FromJson<SomeApp.Model.IntegrationExample>(json);
Debug.Log(item.Message);
});
✕ アノテーション非対応
✕ GSI/LSI非対応
✕ Converter非対応
✕ Dictionaryに変換できない
orz
今回やったハック
SDKのソースを取得
Unityでビルド環境を構築
Lambda APIとDynamoDB APIの
つなぎ込みとデバッグ
「DynamoDBのレスポンスが来た」とSDKを騙す
Lambda
(ロジック)
DynamoDB
(データ保存)
Cognito
(ユーザー認証)
レスポンスはDynamoDBとし
て処理する
Unity
DynamoDBへの
アクセスを制御リクエストはLambda
Lambda API DynamoDB API
PPAP(Pen-Pineapple-Apple-Pen Official)ペンパイナッポーアッポーペン/PIKOTARO(ピコ太郎)
Lambdaでの実装例
var request = new InvokeRequest(){
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse
};
// 従来の方法(Json文字列で受け取る)
LambdaClient.InvokeAsync(request, (result) => {
sring json = Encoding.UTF8.GetString(result.Response.Payload.ToArray());
var item = JsonUtility.FromJson<SomeApp.Model.IntegrationExample>(json);
Debug.Log(item.Message);
});
// DynamoDBっぽく受け取る(AttributeValueで受け取る)
LambdaClient.GetItemAsync(request, (result) => {
Debug.Log(result.Response.Item["Message"].S);
});
// DynamoDBっぽく受け取る(Generic対応)
LambdaClient.GetItemAsync<SomeApp.Model.IntegrationExample> (request, (result) => {
Debug.Log(result.Response.item.Message);
});
◯ 指定したクラスで受け取り
◯ アノテーション対応
◯ GSI/LSI対応
◯ Converter対応
◯ 複雑なオブジェクトに変換可能
リクエストは
Lambda
レスポンスはDynamoDB
resultとは何か
var request = new InvokeRequest(){
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse
};
// 従来の方法(Json文字列で受け取る)
LambdaClient.InvokeAsync(request, (result) => {
sring json = Encoding.UTF8.GetString(result.Response.Payload.ToArray());
var item = JsonUtility.FromJson<SomeApp.Model.IntegrationExample>(json);
Debug.Log(item.Message);
});
// DynamoDBっぽく受け取る(AttributeValueで受け取る)
LambdaClient.GetItemAsync(request, (result) => {
Debug.Log(result.Response.Item["Message"].S);
});
// DynamoDBっぽく受け取る(Generic対応)
LambdaClient.GetItemAsync<SomeApp.Model.IntegrationExample> (request, (result) => {
Debug.Log(result.Response.item.Message);
});
AmazonServiceResult<InvokeRequest,
LambdaGetItemResponse> result
AmazonServiceResult<InvokeRequest,
InvokeResponse> result
AmazonServiceResult<InvokeRequest,
LambdaGetItemResponse<SomeApp.Model.
IntegrationExample>> result
DynamoDB APIでできることがそのまま使える
DynamoDB
(データ保存)
Cognito
(ユーザー認証)
Context.GetItemAsync<Book>(request, (result) => {
Debug.Log(result.Response.Item.Title);
});
①指定したクラスで受け取れる
Unity
Lambda
(ロジック)
②アノテーションで細かな振る舞いを指定できる
[DynamoDBTable("EXAMPLE_TABLE")] // テーブル名のマッピング
public class IntegrationExample{
[DynamoDBHashKey]
public string RoomId;
[DynamoDBRangeKey]
public string Created;
[DynamoDBProperty("Message")] // カラム名のマッピング
public string TextMessage;
[DynamoDBIgnore]
public bool SomeFlag; // DinamoDBIgnore属性は無視される
private int _counter; // privateフィールドは無視される
}
③Global Secondary Index / Local Secondary Indexに対応
[DynamoDBTable("EXAMPLE_TABLE")] // テーブル名のマッピング
public class IntegrationExample{
[DynamoDBHashKey]
public string RoomId;
[DynamoDBRangeKey]
public string Created;
[DynamoDBProperty("Message")] // カラム名のマッピング
public string TextMessage;
[DynamoDBIgnore]
public bool SomeFlag; // DinamoDBIgnore属性は無視される
private int _counter; // privateフィールドは無視される
[DynamoDBGlobalSecondaryIndexHashKey("GSI-Key-Name")]
public string UserId;
[DynamoDBGlobalSecondaryIndexRangeKey("GSI-Key-Name")]
public string SomeRange;
}
別条件での検索と
そのページめくりに使用
④独自のConverterを指定できる
[DynamoDBProperty(typeof(DimensionTypeConverter))]
public DimensionType Dimensions;
public class DimensionType {
public decimal Length;
public decimal Height;
public decimal Thickness;
}
// 寸法文字列 "8.5x11x.05" を DimensionType に変換
public class DimensionTypeConverter : IPropertyConverter {
public object FromEntry(DynamoDBEntry entry) {
Primitive primitive = entry as Primitive;
string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None);
if (data.Length != 3) throw new ArgumentOutOfRangeException();
DimensionType complexData = new DimensionType {
Length = Convert.ToDecimal(data[0]),
Height = Convert.ToDecimal(data[1]),
Thickness = Convert.ToDecimal(data[2])
};
return complexData;
}
}
⑤複雑なオブジェクトにも対応
[DynamoDBTable("IntegrationExample")]
public class IntegrationExample{
[DynamoDBProperty(typeof(ListOfDocumentTypeConverter))]
public List<Document> Books;
[DynamoDBProperty]
public Dictionary<string,string> EJDictionary;
}
// 参照方法
Debug.Log(result.Response.Item.Books[0]["Author"]); // Yamada Taro
Debug.Log(result.Response.Item.EJDictionary["apple"]); // ringo
DynamoDBのカラムの例
VBのVariant型のようなもの
Dictionaryに対応
今回のハックの構成図
Lambda
(ロジック)
DynamoDB
(データ保存)
Cognito
(ユーザー認証)
レスポンスは
DynamoDB
Unity
DynamoDBへの
アクセスを制御
リクエストはLambda
DynamoDB
(DescribeTable)
テーブルの
属性を取得
IAMの設定
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-sync:*",
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable"
],
"Resource": [
"arn:aws:dynamodb:ap-northeast-1:764393641414:table/IntegrationExample"
]
}
]
}
DescribeTableを許可する
テーブルを追加
Lambdaの実行を許可
DynamoDBの
DescribeTableだけ許可
こうして世界は平和になった
【おまけ】
通信失敗時のサポート
var request = new InvokeRequest(){
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse
};
LambdaClient.GetItemAsync<SomeApp.Model.IntegrationExample> (request, callback);
var request = new ManagedInvokeRequest () { // クラスを変更
FunctionName = "getIntegrationExample",
Payload = "{"RoomId":"hoge"}",
InvocationType = InvocationType.RequestResponse,
Manage = this.Manage, // 追加。次のスライドで説明
MessageParentObject = this.MessageParentObject // 追加
};
LambdaClient.GetItemAsync<SomeApp.Model.IntegrationExample> (request, callback);
従来の実装方法
通信失敗時のサポートつき
protected void Manage(AmazonServiceResult<AmazonWebServiceRequest,AmazonWebServiceResponse> result,
AsyncOptions ao, Action<AmazonWebServiceRequest, AmazonWebServiceResponse, Exception, AsyncOptions>
callback){
var managedReq = result.Request as ManagedInvokeRequest;
if(result.Exception == null && !"Null".Equals((result.Response as IInvokeResponse).FunctionError)){
if (callback != null)
callback (result.Request, result.Response, result.Exception, ao);
}else{
if (managedReq.FailureDelegate != null)
managedReq.FailureDelegate ();
//エラーメッセージ表示
var dialogItem = new OkDialogItem{
ExplainText = "通信エラーが発生しました。",
OkText = "リトライ",
OkProcedure = delegate { managedReq.RetryDelegate(); } //リトライ
};
var dialog = OkDialog.InstantiateObject(dialogItem);
dialog.transform.SetParent(managedReq.MessageParentObject.transform, false);
dialog.Show();
}
}
エラーの判定メソッド、通信失敗時だけでなくメンテナンス時の判定もここに書ける
リトライにも対応
通信成功時
通信失敗時
2017年サーバーレスの時代
Unityプロジェクトでも
快適な開発ライフを!
UnityのLambda API を Dynamo DB APIっぽく使う

More Related Content

PPTX
FIWARE Context Information Management
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.15.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)
FIWARE Context Information Management
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.1.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.15.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.1.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.6.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.5.0対応)

What's hot (20)

PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.3.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.0.0対応)
PDF
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)
PDF
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.2.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.0.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.3.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.6.0対応)
PDF
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.14.0対応)
PPTX
コア・コンテキスト管理 - FIWARE WednesdayWebinars
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.5.0対応)
PPTX
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.3.0対応)
PPTX
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応)
PPTX
Entity Framework 5.0 deep dive
PPTX
FIWAREシステム内の短期履歴の管理
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.3.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.2.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.2.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.0.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.3.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.6.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.13.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 1.14.0対応)
コア・コンテキスト管理 - FIWARE WednesdayWebinars
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 2.5.0対応)
FIWARE Orion Context Broker コンテキスト情報管理 (Orion 3.3.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応)
Entity Framework 5.0 deep dive
FIWAREシステム内の短期履歴の管理
Ad

Similar to UnityのLambda API を Dynamo DB APIっぽく使う (12)

PDF
AWS SDK for Smalltalk
PDF
[db tech showcase Tokyo 2015] A33:Amazon DynamoDB Deep Dive by アマゾン データ サービス ...
PDF
Amazon dynamo db、cloudant、blockchainの紹介 20160706
PDF
Deep Dive: Amazon DynamoDB (db tech showcase 2016)
PDF
MongoDB2.2の新機能
PDF
AWS Black Belt Techシリーズ Amazon Cognito / Amazon Mobile Analytics
PDF
Serverless backendformobilegame and_aws-appsync_gamingtechnight-2
PDF
Entity Framework
PDF
[AWSマイスターシリーズ] Amazon DynamoDB
PDF
200k/sec
PDF
20200630 AWS Black Belt Online Seminar Amazon Cognito
PDF
DynamoDBの初心者に伝えたい初めて触るときの勘所
AWS SDK for Smalltalk
[db tech showcase Tokyo 2015] A33:Amazon DynamoDB Deep Dive by アマゾン データ サービス ...
Amazon dynamo db、cloudant、blockchainの紹介 20160706
Deep Dive: Amazon DynamoDB (db tech showcase 2016)
MongoDB2.2の新機能
AWS Black Belt Techシリーズ Amazon Cognito / Amazon Mobile Analytics
Serverless backendformobilegame and_aws-appsync_gamingtechnight-2
Entity Framework
[AWSマイスターシリーズ] Amazon DynamoDB
200k/sec
20200630 AWS Black Belt Online Seminar Amazon Cognito
DynamoDBの初心者に伝えたい初めて触るときの勘所
Ad

UnityのLambda API を Dynamo DB APIっぽく使う