Script

Script は、フロントエンドが HTTP で呼び出す宣言型のバックエンドエンドポイントです。サーバーコードを書かずに「何をするか」を JSON で宣言すると、WEEGLOO エンジンが代わりに実行します。認証、条件チェック(guard)、連鎖 CRUD、外部 API 呼び出し、値の加工といった、フロントエンドを支える典型的なバックエンドの配管(BFF、Backend-for-Frontend)を Script 1 つで置き換えることが狙いです。

このドキュメント群は Script 文法の正本(reference)です。個々の文法の詳細は、以下の このグループのドキュメントで分けて扱います。

Script を作って管理する作業(作成・照会・更新・削除)は CMA(https://cma.weegloo.com/v1)で行います。実行は専用の Script ホスト(https://script.weegloo.com/v1)の実行経路が担います。この実行経路 1 つが、Weegloo User のトークンと、製品に加入した会員(ServiceUser)のトークンの両方を受け取ります。ACMA には Script API がなく、読み取り専用の配信 API(CDA、ACDA)にもありません。

メンタルモデル

  • 1 つの Script は 1 つの HTTP エンドポイントです。 呼び出しメソッド(method)で、どの Script を実行するかをマッチングします。
  • 本文は statements 配列です。 上から下へ順に実行されます。一般的なプログラミングの関数本体と同じです。
  • コードではなく宣言です。 任意のコード(FaaS)を入れるのではなく、定められた Statement タイプを組み合わせます。人が手で書くよりも、AI エージェントが MCP で生成する方に合わせて設計されています。
  • 値は JSON Pointer テンプレートで流れます。 前のステップの結果、入力 payload、変数を { /pointer } で参照して次のステップへ渡します。条件や計算が必要なときは JsonLogic 演算子を使います。詳しいルールは 値式で扱います。

最上位構造 (ScriptDefinition)

1 つの Script は、次の ScriptDefinition 構造で定義します。

{
  "method": "Post",               // Get | Post | Put | Patch | Delete。呼び出し時にマッチングする HTTP メソッド(必須)
  "payloadSchema": { /* ... */ }, // (任意) JSON Schema。指定すると実行前にリクエスト payload を検証
  "statements": [ /* Statement[]。上から下へ実行(必須、1 個以上) */ ],
  "secrets": [ /* (任意) シークレット値の一覧。Statement で { /secrets/<key> } として読む */ ]
}
フィールド必須説明
method必須この Script を呼び出す HTTP メソッドです。呼び出し時にこの値でマッチングします。
payloadSchema任意JSON Schema です。指定すると実行前にリクエスト body(payload)をこのスキーマで検証し、失敗した場合は実行せずに拒否します。
statements必須実行する Statement の順序付き配列です。最低 1 個です。
secrets任意外部 API キーや署名鍵のように、Statement にそのまま書いてはいけないシークレット値の一覧です。項目ごとに key・value・description を置き、Statement ではその value を { /secrets/<key> } で読みます。値は WEEGLOO が暗号化して安全に保存します。ルールは セキュリティモデルの secretsで扱います。

payload は JSON オブジェクトのみを受け付けます。呼び出し body は /payload コンテキストルートでアクセスし({ /payload/... })、パース前の原文の文字列が必要なときは /rawPayload でアクセスします(署名検証のように、送られたバイトの上で計算する場合)。呼び出しのリクエスト HTTP ヘッダーは /headers ルートで参照します({ /headers/... }、キーは小文字)。実行が始まった時刻は /now ルートにあります。secrets に宣言したシークレット値は /secrets ルートで読みます({ /secrets/<key> })。コンテキストルート全体は 値式で扱います。

リクエストとレスポンス

Script は最終的に Return Statement の値を呼び出し元へ返します。レスポンスの形は次のとおりです。

{
  "requestId": "…",     // 実行識別子
  "durationMs": 1234,   // 実行にかかった時間(ms)
  "statusCode": 200,    // 到達した Return の statusCode(デフォルト 200)
  "return": <value>     // Return.isError が false のときのみ。値が null なら ""
  // "error": <value>   // Return.isError が true のとき、または実行が失敗したとき(このとき "return" はない)。値が null なら ""
}
  • requestId はこの実行の識別子です。同じ値が、その実行が残した ScriptLog の sys.requestId に入るため、ログからこの実行を見つける鍵になります。
  • return と error は同時には出ません。Return Statement の isError がどちらかを決めます。
  • Return Statement に到達しないまま最後まで実行された場合、return と error はどちらも出ず、statusCode はデフォルト値(200)になります。
  • 実行が失敗すると、Return がなくても error が入ります。 不正な payload のように呼び出し側の原因で失敗し、Try が捕捉しない場合は、error に失敗の理由が入り、statusCode はその失敗に対応するコードになります(不正な payload は 4xx、外部呼び出しやメール送信が失敗すると 502)。実際に最もよく出会うエラーレスポンスがこの形です。時間予算を超えた実行は、このレスポンスエンベロープではなく 408 で応答します。
  • 値が null の場合、そのフィールドは空文字列 "" として出ます。

Return の value・isError・statusCode でレスポンス本文とステータスコードを制御します。詳しくは Statement カタログの Returnで扱います。

1 回の実行に与えられる時間

Script は、呼び出しリクエストを処理する経路でインラインに実行されます。バックグラウンドへ回したり、受付のレスポンスを先に返すような流れはなく、呼び出しのレスポンス本文がそのまま実行結果です。結果を後から取りに行くポーリングの経路もありません。

1 回の実行に許される時間は最大 180 秒です。基本の 30 秒に外部呼び出し(Http・EmailSend)が使える時間を加えた値が許され、ファイルを送る Http はファイルごとにダウンロード時間も併せて加算されます。

  • リソースを読み書きする作業のように外部呼び出しではない作業は、基本の 30 秒の中で処理されます。
  • 反復(Loop・ResourceForEach)は、その中の時間に反復回数を掛けます。そのため、外部呼び出しのない反復は基本の 30 秒の中で終わる必要があります。
  • 計算した値が 180 秒を超えても保存と実行はでき、実行が 180 秒に達するとその時点で中断されます。

Statement ごとに加算される時間と計算例は、時間予算で扱います。

最小の例

リクエスト payload のタイトルと本文で記事の Content を作成し、そのまま公開したあと、作成した sys.id を返します。

{
  "method": "Post",
  "statements": [
    { "type": "ResourceCreate", "resource": "Content",
      "contentType": { "sys": { "id": "ct_post" } },
      "fields": {
        "title": { "en-US": "{ /payload/fields/title }" },
        "body":  { "en-US": "{ /payload/fields/body }" }
      },
      "publish": true,
      "name": "post" },
 
    { "type": "Return", "value": { "id": "{ /post/sys/id }" }, "statusCode": 201 }
  ]
}
  • ResourceCreate で Content を作成し、結果を post という名前にバインドします。
  • Return が { "id": <新しい Content id> } を 201 で返します。
  • Content の fields 値がロケールマップ({ "en-US": ... })である理由は、値式のロケールマップで扱います。

さらに多様なシナリオは クックブックにあります。

このグループのドキュメント

  • 値式: { /pointer } 参照、リテラル、JsonLogic の演算と条件、コンテキストルート、ロケールマップを扱います。文法の中核です。
  • Statement カタログ: 25 種の Statement(リソースの CRUD と読み取り、Http、EmailSend、SetVar、Cache、ParseJson、Signature、Hash、Regex、If、Loop、Parallel、Try、Return)のフィールドと結果を扱います。
  • 実行セマンティクス、制約、セキュリティ: 実行順序、guard、補償、楽観的ロック、エラー、静的制約とプラン限度、セキュリティモデルを扱います。
  • クックブック: upsert、クレジット guard、LLM プロキシ、ページネーション、並列、決済サガ、Webhook の署名検証など、完結した例を扱います。
  • Script リソースとエンドポイント: Script リソースの sys 構造とオーサリング、実行(/execute)の HTTP エンドポイント仕様、実行ログ ScriptLog を扱います。

初めてであれば、このページから 値式、Statement カタログの順に読むことをおすすめします。クックブックは丸ごと目を通しても構いません。