계약

타입화된 계약을 통해 서비스를 호출합니다. 스키마 검증과 비동기 실행 지원으로 원격 API, 워크플로우, 함수를 호출합니다.

로딩

local contract = require("contract")

바인딩 열기

ID로 바인딩을 직접 엽니다:

local greeter, err = contract.open("app.services:greeter")
if err then
    return nil, err
end

local result, err = greeter:say_hello("Alice")

스코프 컨텍스트 또는 쿼리 파라미터와 함께:

-- 스코프 테이블과 함께
local svc, err = contract.open("app.services:user", {
    tenant_id = "acme",
    region = "us-east"
})

-- 쿼리 파라미터와 함께 (자동 변환: "true"->bool, 숫자->int/float)
local api, err = contract.open("app.services:api?debug=true&timeout=5000")
파라미터 타입 설명
binding_id string 바인딩 ID, 쿼리 파라미터 지원
scope table 컨텍스트 값 (선택적, 쿼리 파라미터 재정의)

반환: Instance, error

계약 가져오기

인트로스펙션을 위해 계약 정의를 검색합니다:

local c, err = contract.get("app.services:greeter")

print(c:id())  -- "app.services:greeter"

local methods = c:methods()
for _, m in ipairs(methods) do
    print(m.name, m.description)
end

local method, err = c:method("say_hello")

메서드 정의

필드 타입 설명
name string 메서드 이름
description string 메서드 설명
input_schemas table[] 입력 스키마 정의
output_schemas table[] 출력 스키마 정의

구현 찾기

계약을 구현하는 모든 바인딩을 나열합니다:

local bindings, err = contract.find_implementations("app.services:greeter")

for _, binding_id in ipairs(bindings) do
    print(binding_id)
end

또는 계약 객체를 통해:

local c, err = contract.get("app.services:greeter")
local bindings, err = c:implementations()

구현 확인

인스턴스가 계약을 구현하는지 확인합니다:

if contract.is(instance, "app.services:greeter") then
    instance:say_hello("World")
end

메서드 호출

동기 호출 - 완료까지 블록:

local calc, err = contract.open("app.services:calculator")

local sum, err = calc:add(10, 20)
local product, err = calc:multiply(5, 6)

비동기 호출

비동기 실행을 위해 _async 접미사 추가:

local processor, err = contract.open("app.services:processor")

local future, err = processor:process_async(large_dataset)

-- 다른 작업 수행...

-- 결과 대기
local ch = future:response()
local payload, ok = ch:receive()
if ok then
    local result = payload:data()
end

Future 메서드는 Futures를 참조하세요.

계약을 통해 열기

계약 객체를 통해 바인딩을 엽니다:

local c, err = contract.get("app.services:user")

-- 기본 바인딩
local instance, err = c:open()

-- 특정 바인딩
local instance, err = c:open("app.services:user_impl")

-- 스코프와 함께
local instance, err = c:open(nil, {user_id = 123})
local instance, err = c:open("app.services:user_impl", {user_id = 123})

컨텍스트 추가

미리 구성된 컨텍스트로 래퍼를 생성합니다:

local c, err = contract.get("app.services:user")

local wrapped = c:with_context({
    request_id = ctx.get("request_id"),
    user_id = current_user.id
})

local instance, err = wrapped:open()

보안 컨텍스트

인가를 위해 액터와 스코프를 설정합니다:

local security = require("security")
local c, err = contract.get("app.services:admin")

local secured = c:with_actor(security.actor()):with_scope(security.scope())

local admin, err = secured:open()

권한

권한 리소스 함수
contract.get 계약 id get()
contract.open 바인딩 id open(), Contract:open()
contract.implementations 계약 id find_implementations(), Contract:implementations()
contract.call 메서드 이름 동기 및 비동기 메서드 호출
contract.context "context" Contract:with_context()
contract.security "security" Contract:with_actor(), Contract:with_scope()

에러

조건 종류
잘못된 바인딩 ID 형식 errors.INVALID
계약을 찾을 수 없음 errors.NOT_FOUND
바인딩을 찾을 수 없음 errors.NOT_FOUND
메서드를 찾을 수 없음 errors.NOT_FOUND
기본 바인딩 없음 errors.NOT_FOUND
권한 거부됨 errors.PERMISSION_DENIED
호출 실패 errors.INTERNAL