0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHP Slim 環境構築(7) DynamoDB

Last updated at Posted at 2019-09-25

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関連のソースが抜けていたので追加。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?