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 個以上) */ ]
}
フィールド必須説明
method必須この Script を呼び出す HTTP メソッドです。呼び出し時にこの値でマッチングします。
payloadSchema任意JSON Schema です。指定すると実行前にリクエスト body(payload)をこのスキーマで検証し、失敗した場合は実行せずに拒否します。
statements必須実行する文(statement)の順序付き配列です。最低 1 個です。

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

リクエストとレスポンス

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

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

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

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

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

1 回の実行に与えられる時間は、1 つの式で決まります: min(30秒 + 各文が宣言した時間の合計, 180秒)

  • 基本の予算は 30 秒です。ここに、各文が宣言した時間が加わります。
  • 宣言のない文は 0 秒です。 その文が実際に使う時間は、30 秒の基本予算から出ます。
  • 合計が 180 秒を超えても保存が拒否されるのではなく、予算が 180 秒に切り詰められます。

文ごとの宣言ルールの要点です。

宣言する時間
Http(timeoutMs、なければ 30 秒) × (1 + retry)
EmailSendtimeoutMs、なければ 10 秒
Loopbody の文の合計 × (maxIterations、なければ 10,000)
ResourceForEachonEach の文の合計 × (limit、なければ 10,000)
Ifthen 側と else 側のうち大きいほう
Parallel各ブランチのうち最も大きい値
  • 反復は掛け算です。 LoopResourceForEach は、body(onEach)が宣言した時間に反復の上限を掛けます。
  • 外部呼び出しのない反復は body の宣言時間が 0 なので、30 秒の基本予算が実質の限度です。

文ごとの詳細なルールとプランの限度は、実行セマンティクス、制約、セキュリティで扱います。

最小の例

リクエスト 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 }
  ]
}
  • ResourceCreateContent を作成し、結果を post という名前にバインドします。
  • Return{ "id": <新しい Content id> }201 で返します。
  • Contentfields 値がロケールマップ({ "en-US": ... })である理由は、値式のロケールマップで扱います。

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

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

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

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