Next.js の API と Playwright のコンテナを連動させる(中編)

公開日 :

Next.js の API として Web サイトのサムネイルを表示するための仕組みを実装していきます。今回は、取得した URL を利用して画像を表示するところまで進めていきます。

Playwright のコンテナの動作を変更

すでに実装していた Playwright の動作するコンテナのサンプルですが、URL をパラメータで渡すと画像を表示するように作成していました。今回は連携で利用しやすくするために、返値として Json 形式で返しつつ、画像のデータは base64 で出力するようにします。

この部分の変更は非常にシンプルで、該当するコードを以下のように書き換えてください。

  const screenshot = await page.screenshot();

  // Base64エンコードされたスクリーンショットをHTTPレスポンスとして送信
  const base64Screenshot = screenshot.toString("base64");
  res.json({ screenshot: base64Screenshot });

実際にアクセスをすると以下のように Json のデータが返ってきます。

random desc

画像を取得する

上記の API を利用して Base64 で取得したデータを画像として表示するようにコードを書き換えていきます。

今回は非同期処理を実装するために、axios を利用します。以下のようにインストールをしてください。

npm install axios

続いて最初のエリアでこれを利用する定義を追加します。

const axios = require("axios");

そして前回紹介をしていたコードで最後に Json の結果を返していたところを以下のように書き換えます。URL のところは既に展開しているコンテナが動いている Web app もしくはローカルで動かしている場合はその URL を利用してください。

    const externalApiUrl =
      "https://yourplaywright.domain/api/screenshot?url=" +
      url;
    const response = await axios.get(externalApiUrl);
    const imageData = response.data.screenshot;

    const decodedImageData = Buffer.from(imageData, "base64");

    res.setHeader("Content-Type", "image/png");
    res.status(200).end(decodedImageData, "binary");
  } catch (error) {
    return res.status(500).json({ error: "Can't get content data" });
  }

これで URL をアプリに私、Base64 で返された値を画像に変換して表示させることができます。結果は以下のようになります。

random desc

サーバーを環境変数として定義する

上記のサンプルのコードではサーバーの URL が埋め込まれている形となります。これを環境変数として定義します。まずは、.env で以下の項目を追加します。

NEXT_PUBLIC_PLAYWRIGHT=https://yourplaywright.domain

続いて上記の値を取得するために、該当するコードに以下の1行を追加します。

  const NEXT_PUBLIC_PLAYWRIGHT = process.env.NEXT_PUBLIC_PLAYWRIGHT;

最後に、URL を記載している行を以下のように書き換えます。

    const externalApiUrl = NEXT_PUBLIC_PLAYWRIGHT + "/api/screenshot?url=" + url;

上記の設定が終わったあと、問題なく動作しているか確認をしてください。

まとめ

今回は Next.js の API から Playwright の API を利用してスクリーンショットを取得する方法を紹介しました。この際、コンテナで返していたデータは画像でしたが、今回は Base64 のデータでやり取りをする形に変更をしました。また、サーバーが変更されることも多いと考えて、環境変数としてサーバーの URL を変更できるようにしました。

今の実装では毎回画像を取得する形となるため、Azure Blob Storage に画像を保存、画像があればそれを利用する部分のコードを追加していきます。