🍄

Compute@Edge を使ったコンテンツスティッチ

2021/12/04に公開

シンプルなコンテンツスティッチの実装例と Compute@Edge の開発に関する小ネタを紹介します。

この記事で紹介する小ネタ:

尚、この記事は Compute@Edge を一度は試してみたことがある方を想定して記載しています。まだの方はこちらの記事を確認してみてください。
https://zenn.dev/hrmsk66/articles/74e2e890726e99

シナリオと実装例

2つのバックエンドサーバへリクエストを並行して送信、受信したレスポンスのボディを組合せてクライアントへのレスポンスを生成します。クライアントが受信するレスポンスはバックエンドの応答順序によって異なります。

バックエンドサーバとして httpbin.org の /base64/{value} を利用します。このエンドポイントは{value}部分で指定した Base64 文字列をデコードした結果をレスポンスとして返してくれます。

Rust のコード例

src/main.rs
main.rs
use fastly::{Error, Request, Response};

#[fastly::main]
fn main(_req: Request) -> Result<Response, Error> {
    // Cat server
    let req1 = Request::get("https://httpbin.org/base64/Q2F0")
        .send_async("origin_0")?;
    // Dog server
    let req2 = Request::get("https://httpbin.org/base64/RG9n")
        .send_async("origin_1")?;
    let pending_reqs = vec![req1, req2];

    let (resp, pending_reqs) = fastly::http::request::select(pending_reqs);
    let mut resp1 = resp?;
    let (resp, _pending_reqs) = fastly::http::request::select(pending_reqs);
    let mut resp2 = resp?;

    let resp = Response::from_body(format!(
        "{} responded first, {} responded next",
        resp1.take_body_str(),
        resp2.take_body_str()
    ));

    Ok(resp)
}

Rust の例で使っている非同期 API の挙動は SDK のドキュメントに記載されています。
https://docs.rs/fastly/latest/fastly/

JavaScript のコード例

src/index.js
index.js
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));

async function handleRequest(_event) {
  const pending_reqs = [
    // Cat server
    fetch("https://httpbin.org/base64/Q2F0", { backend: "origin_0" }),
    // Dog server
    fetch("https://httpbin.org/base64/RG9n", { backend: "origin_1" }),
  ];

  const logs = [];
  const responses = [];
  await Promise.all(
    pending_reqs.map(async (req, idx) => {
      logs.push('REQ' + idx);
      const r = await req;
      const t = await r.text();
      logs.push('RESP' + idx);
      responses.push(t);
    })
  );
  console.log(logs.join(' '));

  return new Response(`${responses[0]} responded first, ${responses[1]} responded next`, {
    status: 200,
  });
}

サンプルコードからプロジェクトをつくる

紹介したコードは Developer Hub で公開されています。公開されているサンプルコードの多くは Fastly Fiddle (以下 Fiddle) という Web アプリケーションを使って書かれており Compute@Edge プロジェクトのソーステンプレートとして使うことができます。

実際にプロジェクトをつくってみましょう。こちらからサンプルを開いてください。
https://developer.fastly.com/solutions/examples/async-requests

  1. Fiddle で書かれたサンプルはブラウザ上で実行することができるようになっており RUN ボタンがついています。言語を選択して INSTALL ボタンをクリックしてください。

  2. 赤枠のコマンドをコピーします。

  3. 適当なディレクトリを作成して、ディレクトリ内でコピーしたコマンドを実行してください。サンプルからプロジェクトがつくられます。

生成されたファイルを確認してみましょう。src ディレクトリ配下のファイルにはサンプルと同じコードが含まれているはずです。

サンプルコードが依存しているパッケージがある場合、その定義が所定のファイルに含まれます。
( Rust の場合は Cargo.toml, JS の場合は package.json )

fastly.toml にはバックエンドサーバの定義が含まれています。これらの定義もサンプルのバックエンドサーバの設定に基づいて生成されています。

fastly compute serve コマンドを実行するとテスト用の HTTP サーバがローカルで起動します。http://127.0.0.1:7676 にテストリクエストを送信して動作を確認してみて下さい。

プロジェクトを Fastly にデプロイする場合は fastly compute publish コマンドを実行してください。

Fastly Fiddle について

Fiddle は Fastly サービスのコードを書いて実行し、動作を確認することができるツールで、Fastly アカウントにログインすることなく利用できます。

編集をはじめるとパーマリンクがアサインされ、URL でコードをシェアすることができるので Fastly で実行するロジックの検証だけでなく、Fastly サポートに問題のコードを共有するのに使って頂いたり、Fastly からソリューションの例をご案内するときにも利用されていたりします。

Fiddle をソーステンプレートとして使う

自分で記述した Fiddle も下記コマンドで Developer Hub のサンプルと同様に Compute@Edge プロジェクトのソーステンプレートとして使うことができます。

fastly compute init --from=(Fiddle の URL)

Fiddle のロックとクローン

Fiddle はデフォルトでは誰でも編集が可能な OPEN の状態になっています。編集を制限したい場合は画面右上のメニューから Lock または Freeze を選択します。

  • Lock: 自分だけが編集できる状態
  • Freeze: 誰も編集できない状態

同じく右上のメニューから Lock/Freeze された Fiddle の編集可能なクローンを作成することもできます。

Developer Hub で公開されている Fiddle もクローンを作成してカスタマイズすることができます。

Fiddle がサポートしているパッケージ

Compute@Edge では任意のパッケージを依存関係に含めることができますが、Fiddle で使えるものは限られています。使用可能なパッケージのリストはこちらからご確認ください。

Fiddle についてはこちらのドキュメントに詳しく記載されています。ご活用ください。
https://developer.fastly.com/learning/vcl/fiddle/

Discussion

ログインするとコメントできます