Script
Script는 프런트엔드가 HTTP로 호출하는 선언형 백엔드 엔드포인트입니다. 서버 코드를 작성하지 않고 "무엇을 할지"를 JSON으로 선언하면 WEEGLOO 엔진이 대신 실행합니다. 인증, 조건 검사(guard), 연쇄 CRUD, 외부 API 호출, 값 가공처럼 프런트엔드를 받치는 전형적인 백엔드 중간 계층(BFF, Backend-for-Frontend)을 Script 하나로 대체하는 것이 목표입니다.
이 문서 묶음은 Script 문법의 정본(reference)입니다. 개별 문법의 상세는 아래 이 그룹의 문서에서 나눠 다룹니다.
Script를 만들고 관리하는 일(생성·조회·수정·삭제)은 CMA(https://cma.weegloo.com/v1)에서 합니다. 실행은 전용 Script 호스트(https://script.weegloo.com/v1)의 실행 경로가 담당합니다. 이 실행 경로 하나가 Weegloo User 토큰과 제품에 가입한 회원(ServiceUser) 토큰을 둘 다 받습니다. ACMA에는 Script API가 없고, 읽기 전용 전달 API(CDA, ACDA)에도 없습니다.
멘탈 모델
- 하나의 Script는 하나의 HTTP 엔드포인트입니다. 호출 메서드(
method)로 어떤 Script를 실행할지 매칭합니다. - 본문은
statements배열입니다. 위에서 아래로 순차 실행됩니다. 일반 프로그래밍의 함수 본문과 같습니다. - 코드가 아니라 선언입니다. 임의 코드(FaaS)를 넣는 것이 아니라, 정해진 statement 타입을 조합합니다. 사람이 손으로 짜기보다 AI 에이전트가 MCP로 생성하는 쪽에 맞춰 설계됐습니다.
- 값은 JSON Pointer 템플릿으로 흐릅니다. 앞 단계의 결과, 입력 payload, 변수를
{ /pointer }로 참조해 다음 단계로 넘깁니다. 조건이나 계산이 필요하면 JsonLogic 연산자를 씁니다. 자세한 규칙은 값 표현식에서 다룹니다.
최상위 구조 (ScriptDefinition)
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는 이 실행의 식별자입니다. 같은 값이 그 실행이 남긴 ScriptLog의sys.requestId에 들어가므로, 로그에서 이 실행을 찾을 때 이 값을 기준으로 씁니다.return과error는 동시에 나오지 않습니다.Return문의isError가 어느 쪽인지 결정합니다.Return문에 도달하지 못한 채 끝까지 실행됐다면return과error가 둘 다 없고statusCode는 기본값(200)입니다.- 실행이 실패하면
Return없이도error가 담깁니다. 잘못된 payload처럼 호출 쪽 원인으로 실패하고Try가 잡지 않으면,error에 실패 사유가 들어가고statusCode는 그 실패에 해당하는 코드가 됩니다(잘못된 payload는 4xx, 외부 호출이나 메일 발송이 실패하면502). 실제로 가장 자주 만나는 에러 응답이 이 모양입니다. 시간 예산을 넘긴 실행은 봉투가 아니라408로 응답합니다. - 값이
null이면 해당 필드는 빈 문자열""로 나옵니다.
Return의 value, isError, statusCode로 응답 본문과 상태 코드를 제어합니다. 자세한 내용은 Statement 카탈로그의 Return에서 다룹니다.
한 번의 실행에 주어지는 시간
Script는 호출 요청을 처리하는 경로에서 인라인으로 실행됩니다. 백그라운드로 넘기거나 접수 응답을 먼저 돌려주는 흐름은 없고, 호출의 응답 본문이 곧 실행 결과입니다. 결과를 나중에 받아 가는 폴링 경로도 없습니다.
한 번의 실행에 주어지는 시간은 하나의 식으로 정해집니다: min(30초 + 문들이 선언한 시간의 합, 180초).
- 기본 예산은 30초입니다. 여기에 각 문이 선언한 시간이 더해집니다.
- 선언이 없는 문은 0초입니다. 그 문이 실제로 쓰는 시간은 30초 기본 예산에서 나갑니다.
- 합이 180초를 넘으면 저장이 거부되는 것이 아니라, 예산이 180초로 잘립니다.
문별 선언 규칙의 요지입니다.
| 문 | 선언하는 시간 |
|---|---|
Http | (timeoutMs 없으면 30초) × (1 + retry) |
EmailSend | timeoutMs, 없으면 10초 |
Loop | body 문들의 합 × (maxIterations, 없으면 10,000) |
ResourceForEach | onEach 문들의 합 × (limit, 없으면 10,000) |
If | then 쪽과 else 쪽 중 큰 값 |
Parallel | 각 분기 중 큰 값 |
- 반복은 곱셈입니다.
Loop와ResourceForEach는 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 }
]
}ResourceCreate로 Content를 만들고 결과를post라는 이름에 바인딩합니다.Return이{ "id": <새 Content id> }를201로 돌려줍니다.- Content의
fields값이 로케일 맵({ "en-US": ... })인 이유는 값 표현식의 로케일 맵에서 다룹니다.
더 다양한 시나리오는 쿡북에 있습니다.
이 그룹의 문서
- 값 표현식:
{ /pointer }참조, 리터럴, JsonLogic 연산과 조건, 컨텍스트 루트, 로케일 맵을 다룹니다. 문법의 핵심입니다. - Statement 카탈로그: 25종 문(리소스 CRUD와 읽기,
Http,EmailSend,SetVar,Cache,ParseJson,Signature,Hash,Regex,If,Loop,Parallel,Try,Return)의 필드와 결과를 다룹니다. - 실행 시맨틱, 제약, 보안: 실행 순서, guard, 보상, 낙관적 잠금, 에러, 정적 제약과 플랜 한도, 보안 모델을 다룹니다.
- 쿡북: upsert, 크레딧 guard, LLM 프록시, 페이지네이션, 병렬, 결제 사가, 웹훅 서명 검증 등 완결된 예시를 다룹니다.
- Script 리소스와 엔드포인트:
Script리소스의sys구조와 저작, 실행(/execute) HTTP 엔드포인트 명세, 실행 로그 ScriptLog를 다룹니다.
처음이라면 이 페이지에서 값 표현식, Statement 카탈로그 순서로 읽는 것을 권합니다. 쿡북은 통째로 훑어도 좋습니다.
