PHP Slim 環境構築(7) DynamoDB
Introduction
前回は、Redisにアクセスしてみました。
今回は、ローカル用のDynamoDBを作成して、DynamoDBへのアクセスを行います。
変更点
ソースツリー
前回からの変更・追加ソースは以下の通りです。
$(PROJECTROOT)
/compose
docker-compose.yml
/src
/hoge
/lib
/Controller
DynamodbController.php (NEW!)
/Model
/public
index.php
composer.json
composer.lock
docker-compose.yml
新たにdynamodb用コンテナを追加します。
また、web_hogeコンテナから、dynamodbコンテナにアクセスするために、linksを設定します。
これで、ホスト名"dynamodb"でdynamodbを識別することができます。
なお、dynamodbでlocalhost:18000でアクセスできるようにしているのは、ローカルホストのコマンドラインからawsコマンドで動作確認するためなので、実際の処理には必要ありません。
web_hoge:
build:
context: ./web_hoge
args:
- environment=local
links:
- mysql
- postgresql
- redis
- dynamodb (追加)
..(略)..
dynamodb:
image: amazon/dynamodb-local
container_name: dynamodb
ports:
- "18000:8000"
networks:
- localnet
composer.json/composer.lock
aws-sdkをcomposerで追加しておきます。
$ composer require aws/aws-sdk-php
index.php
/src/hoge/public/index.php
use Hoge\Controller\RedisController;
use Hoge\Controller\DynamodbController; (追加)
..(略)..
$containerBuilder->addDefinitions([
'settings' => [
..(略)..
'dynamodb' => [
'endpoint' => 'http://dynamodb:8000',
'region' => 'ap-northeast-1'
]
],
..(略)..
'dynamodb' => function (ContainerInterface $container) {
$settings = $container->get('settings')['dynamodb'];
$sdk = new Aws\Sdk([
'endpoint' => $settings['endpoint'],
'region' => $settings['region'],
'version' => '2012-08-10',
'credentials' => [
'key' => 'dummy-key',
'secret' => 'dummy-secret'
]
]);
$dynamodb = $sdk->createDynamoDb();
return $dynamodb;
}
..(略)..
$app->group('/dynamodb', function (RouteCollectorProxy $group) {
$group->get('/{key}', DynamodbController::class . ':get');
$group->post('', DynamodbController::class . ':post');
});
DynamodbController
getとpostに対応したメソッドを定義しています。
また、コンストラクタでダミー用のテーブルを作成しています。
/src/hoge/lib/Controller/DynamodbController.php
<?php
namespace Hoge\Controller;
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;
use Aws\DynamoDb\Marshaler;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Container\ContainerInterface;
class DynamodbController
{
/**
* @var ContainerInterface
*/
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$dynamodb = $this->container->get('dynamodb'); /** @var DynamoDbClient $dynamodb */
// dummy table
try {
$result = $dynamodb->describeTable([
'TableName' => 'hogehoge'
]);
} catch (DynamoDbException $ex) {
$result = $dynamodb->createTable([
'TableName' => 'hogehoge',
'AttributeDefinitions' => [
[
'AttributeName' => 'key',
'AttributeType' => 'S'
]
],
'KeySchema' => [
[
'AttributeName' => 'key',
'KeyType' => 'HASH'
]
],
'ProvisionedThroughput' => [
'ReadCapacityUnits' => 1,
'WriteCapacityUnits' => 1
]
]);
}
}
public function get(Request $request, Response $response, array $args) : Response
{
// parameters (id)
$key = $args['key'];
$dynamodb = $this->container->get('dynamodb'); /** @var DynamoDbClient $dynamodb */
$marshaller = new Marshaler();
$record = $marshaller->marshalItem(["key"=> $key]);
try {
$result = $dynamodb->getItem([
'TableName' => 'hogehoge',
'Key' => $record
]);
} catch (DynamoDbException $ex) {
return $response->withStatus(404);
}
if (!$result->hasKey('Item')) {
return $response->withStatus(404);
}
$item = $result->get('Item');
$found = $marshaller->unmarshalItem($item);
$response->getBody()->write(json_encode($found));
return $response;
}
public function post(Request $request, Response $response, array $args) : Response
{
$body = $request->getBody()->getContents();
$input = json_decode($body);
$key = $input->key;
$value = $input->value;
$dynamodb = $this->container->get('dynamodb'); /** @var DynamoDbClient $dynamodb */
$marshaller = new Marshaler();
$record = $marshaller->marshalItem(['key'=>$key, 'value'=>$value]);
$dynamodb->putItem(['TableName'=>'hogehoge', 'Item'=>$record]);
$response->getBody()->write('OK');
return $response;
}
}
ここまでのソース
こちらでどうぞ。
変更履歴
2019/10/09
- DynamodbControllerでDynamoDBのcreateTableとattributeDefinitionsとKeySchemaの数が異なっていたので修正
- リポジトリにaws-sdk-php関連のソースが抜けていたので追加。