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개 이상) */ ],
"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는 동시에 나오지 않습니다.ReturnStatement의isError가 어느 쪽인지 결정합니다.ReturnStatement에 도달하지 못한 채 끝까지 실행됐다면return과error가 둘 다 없고statusCode는 기본값(200)입니다.- 실행이 실패하면
Return없이도error가 담깁니다. 잘못된 payload처럼 호출 쪽 원인으로 실패하고Try가 잡지 않으면,error에 실패 사유가 들어가고statusCode는 그 실패에 해당하는 코드가 됩니다(잘못된 payload는 4xx, 외부 호출이나 메일 발송이 실패하면502). 실제로 가장 자주 만나는 에러 응답이 이 모양입니다. 시간 예산을 넘긴 실행은 봉투가 아니라408로 응답합니다. - 값이
null이면 해당 필드는 빈 문자열""로 나옵니다.
Return의 value, isError, statusCode로 응답 본문과 상태 코드를 제어합니다. 자세한 내용은 Statement 카탈로그의 Return에서 다룹니다.
한 번의 실행에 주어지는 시간
Script는 호출 요청을 처리하는 경로에서 인라인으로 실행됩니다. 백그라운드로 넘기거나 접수 응답을 먼저 돌려주는 흐름은 없고, 호출의 응답 본문이 곧 실행 결과입니다. 결과를 나중에 받아 가는 폴링 경로도 없습니다.
한 번의 실행에 허용되는 시간은 최대 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 프록시, 페이지네이션, 병렬, 결제 사가, 웹훅 서명 검증 등 완결된 예시를 다룹니다.
- Script 리소스와 엔드포인트:
Script리소스의sys구조와 저작, 실행(/execute) HTTP 엔드포인트 명세, 실행 로그 ScriptLog를 다룹니다.
처음이라면 이 페이지에서 값 표현식, Statement 카탈로그 순서로 읽는 것을 권합니다. 쿡북은 통째로 훑어도 좋습니다.
