PHP で QuickSight の組み込み用 URL を API で呼び出して生成する

# はじめに

QuickSight で埋め込み用 URL を生成し、好きな最初にダッシュボードや編集画面を埋め込むことができます。よくある構成として、API Gateway と Lambda で URL を生成して埋め込む方法がありますが、今回は PHP を使った Web 画面に QuickSight を埋め込む方法を紹介します。

なお、この記事の PHP の Web サーバーの構成はあくまで手元での動作確認として利用するため、PHP 付属のものを利用しています。本番環境では、パフォーマンスや機能、セキュリティの面で Apache や Nginx 等と連携してください。



# 前提条件

PHP から QuickSight の埋め込みを利用するため、AWS SDK for PHP を利用する必要があります。自分の環境だと以下のようにインストールしましたが、AWS Document を参考に準備が必要です。

composer のインストール

```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```



AWS SDK for PHP のインストール

```
php composer.phar require aws/aws-sdk-php
```



# PHP で QuickSight のダッシュボードを埋め込む

まず PHP のソースコードの全文を出します。

```php
<!DOCTYPE html>
<html>
<head>
    <title>QuickSight Dashboard Embed</title>
    <!-- ここに必要なCSSやJavaScriptを追加 -->
</head>
<body>
    <?php
    require 'vendor/autoload.php'; // AWS SDK for PHP の読み込み

    use Aws\QuickSight\QuickSightClient;
    use Aws\Exception\AwsException;

    // リージョンの指定
    $awsRegion = 'ap-northeast-1';

    // QuickSightの設定
    $accountId = '1111111111111';
    $dashboardId = '0849cdf6-0b4b-46c1-9a0d-59a084bd0bb8';
    $userArn = 'arn:aws:quicksight:ap-northeast-1:1111111111111:user/default/user01'; // ユーザーの指定。埋め込み先の Web サイトで認証済みのユーザーに合わせて、動的に切り替える。

    // QuickSightクライアントの初期化
    $client = new QuickSightClient([
        'region' => $awsRegion,
        'version' => 'latest',
        // 'credentials' => [ IAM Role に紐づけているので、シークレットキーなどはハードコードしない
        //     'key' => $awsKey,
        //     'secret' => $awsSecret,
        // ],
    ]);

    // GenerateEmbedUrlForRegisteredUser APIの呼び出し
    try {
        $result = $client->generateEmbedUrlForRegisteredUser([
            'AwsAccountId' => $accountId,
            'ExperienceConfiguration' => [
                'Dashboard' => [
                    'InitialDashboardId' => $dashboardId,
                ],
            ],
            'UserArn' => $userArn,
        ]);

        echo "<h1>Hello World</h1>";
        echo <<<HTML
        <!-- 埋め込み用コード -->
        <iframe
            width="960"
            height="720"
            src="{$result['EmbedUrl']}"
            frameborder="0"
            allowfullscreen="true">
        </iframe>
        HTML;
    } catch (AwsException $e) {
        // エラー処理
        echo "<p>Error: " . htmlspecialchars($e->getMessage()) . "</p>";
    }
    ?>
</body>
</html>
```

　

基本的にはコメントで記載している通りです。重要なものをいくつか取り上げます。

　

まず、以下のコードです。これは、QuickSight に対して認証済みの URL を生成するための呼び出し部分です。`$dashboardId` では QuickSight 上のダッシュボードの ID を指定します。そして、`UserArn` には埋め込んだダッシュボードを参照するための QuickSight 上のユーザー ARN を指定します。
`UserArn` は、埋め込み先の Web サイトで認証しているユーザーと、QuickSight 上のユーザー間で紐づけて指定する必要があります。表現を変えると、QuickSight 上にユーザーが存在しないとエラーになります。したがって、QuickSight 上にユーザーが存在しない (エラーになる) 場合は、`registerUser` の呼び出しなどを利用して自動でユーザーを作成する方法が考えられます。

```php
        $result = $client->generateEmbedUrlForRegisteredUser([
            'AwsAccountId' => $accountId,
            'ExperienceConfiguration' => [
                'Dashboard' => [
                    'InitialDashboardId' => $dashboardId,
                ],
            ],
            'UserArn' => $userArn,
        ]);
``` 
 
 


 　
生成した URL を iframe で埋め込む部分がこちらです。PHP のようなバックエンドサーバー側で HTML を生成してレスポンスするような Web アプリの場合、JavaScript は利用せずにそのまま埋め込むのが楽です。width や height などは、表示させたい見た目に合わせて適宜変更します。

```php
        <iframe
            width="960"
            height="720"
            src="{$result['EmbedUrl']}"
            frameborder="0"
            allowfullscreen="true">
        </iframe>
```



# QuickSight で埋め込み用のドメインを許可

QuickSight 側に、埋め込み先のサイトのドメインを指定する必要があります。今回は動作確認なので `http://localhost:8000` を許可しておきます。

![image-20240123221047151.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/73eca23e-3a02-ea05-eeca-5f21f2ecbd8b.png)



# 埋め込まれた画面を確認

PHP サーバーを手元で動かし、埋め込まれた様子を確認しましょう。PHP 付属の簡易的な Web サーバーを立ち上げます (本番環境では利用しないでください。)

```
php -S localhost:8000
```



実際にアクセスしてみるとこんな感じです。PHP として生成している Hello World の文字の下に、QuickSight のダッシュボードが埋め込まれています。
(これは埼玉県のトイレの場所を可視化している謎ダッシュボードです。トイレは大事。)

![image-20240123220917822.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3b347cff-b537-eb04-34bb-95062f6cf7b9.png)



通常の QuickSight と同様に「しらこばと」といった文字でフィルターを掛ける事もできます。

![image-20240123221346316.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/cfb251a6-310d-2dbf-7bd0-21f7e66ca861.png)



# 検証を通じてわかったこと

- PHP のようなバックエンドサーバー側で埋め込み用 URL を生成できる場合は、JavaScript などは不要でそのまま iframe として埋め込んでもよい
- 一方、既存の Web アプリに手を入れることが難しい場合は、API Gateway と Lambda 関数を利用して、埋め込み用 URL を生成し、JacaScript 側で埋め込んでもよい。