Contratos
Contratos
Sección titulada «Contratos»Invocar servicios a traves de contratos tipados. Llamar APIs remotas, flujos de trabajo y funciones con validacion de esquema y soporte de ejecución asincrona.
local contract = require("contract")Abrir un Binding
Sección titulada «Abrir un Binding»Abrir un binding directamente por ID:
local greeter, err = contract.open("app.services:greeter")if err then return nil, errend
local result, err = greeter:say_hello("Alice")Con contexto de alcance o parametros de consulta:
-- Con tabla de alcancelocal svc, err = contract.open("app.services:user", { tenant_id = "acme", region = "us-east"})
-- Con parametros de consulta (auto-convertidos: "true"->bool, numeros->int/float)local api, err = contract.open("app.services:api?debug=true&timeout=5000")
-- Con opciones de llamada (tercer argumento)local inst, err = contract.open("app.services:flaky", nil, { retry = { max_attempts = 5, initial_delay = 100 }})| Parámetro | Tipo | Descripción |
|---|---|---|
binding_id | string | ID de binding, soporta parametros de consulta |
scope | table | Valores de contexto (opcional, sobrescribe parametros de consulta) |
options | table | Opciones de llamada (opcional) — ej. retry.max_attempts, retry.initial_delay |
Devuelve: Instance, error
Obtener un Contrato
Sección titulada «Obtener un Contrato»Recuperar definicion de contrato para introspeccion:
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")Definicion de Método
Sección titulada «Definicion de Método»| Campo | Tipo | Descripción |
|---|---|---|
name | string | Nombre del método |
description | string | Descripción del método |
input_schemas | table[] | Definiciones de esquema de entrada |
output_schemas | table[] | Definiciones de esquema de salida |
Encontrar Implementaciones
Sección titulada «Encontrar Implementaciones»Listar todos los bindings que implementan un contrato:
local bindings, err = contract.find_implementations("app.services:greeter")
for _, binding_id in ipairs(bindings) do print(binding_id)endO via objeto de contrato:
local c, err = contract.get("app.services:greeter")local bindings, err = c:implementations()Verificar Implementacion
Sección titulada «Verificar Implementacion»Verificar si una instancia implementa un contrato:
if contract.is(instance, "app.services:greeter") then instance:say_hello("World")endLlamar Metodos
Sección titulada «Llamar Metodos»Llamada sincrona - bloquea hasta completar:
local calc, err = contract.open("app.services:calculator")
local sum, err = calc:add(10, 20)local product, err = calc:multiply(5, 6)Llamadas Asincronas
Sección titulada «Llamadas Asincronas»Agregar sufijo _async para ejecución asincrona:
local processor, err = contract.open("app.services:processor")
local future, err = processor:process_async(large_dataset)
-- Hacer otro trabajo...
-- Esperar resultadolocal ch = future:response()local payload, ok = ch:receive()if ok then local result = payload:data()endConsulte Futures para metodos de future.
Abrir via Contrato
Sección titulada «Abrir via Contrato»Abrir binding a traves de objeto de contrato:
local c, err = contract.get("app.services:user")
-- Binding por defectolocal instance, err = c:open()
-- Binding específicolocal instance, err = c:open("app.services:user_impl")
-- Con alcancelocal instance, err = c:open(nil, {user_id = 123})local instance, err = c:open("app.services:user_impl", {user_id = 123})Agregar Contexto
Sección titulada «Agregar Contexto»Crear envoltorio con contexto preconfigurado:
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()Opciones de Llamada
Sección titulada «Opciones de Llamada»Configura reintentos y otro comportamiento de llamada vía with_options:
local c, err = contract.get("app.services:flaky")
local inst, err = c :with_options({ retry = { max_attempts = 5, initial_delay = 100 } }) :open("app.services:flaky_impl")
local result, err = inst:call()Las opciones se aplican a cada llamada de método en la instancia devuelta. Solo errores reintentables disparan reintentos; los errores no reintentables aparecen inmediatamente. Encadenable con with_context, with_actor, with_scope.
| Opción | Tipo | Descripción |
|---|---|---|
retry.max_attempts | int | Intentos máximos incluyendo el primero (1 desactiva reintentos) |
retry.initial_delay | int/duration | Retardo antes del primer reintento (ms o cadena de duración) |
Contexto de Seguridad
Sección titulada «Contexto de Seguridad»Establecer actor y alcance para autorizacion:
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()Permisos
Sección titulada «Permisos»| Permiso | Recurso | Funciones |
|---|---|---|
contract.get | id de contrato | get() |
contract.open | id de binding | open(), Contract:open() |
contract.implementations | id de contrato | find_implementations(), Contract:implementations() |
contract.call | nombre de método | llamadas de método sync y async |
contract.context | ”context” | Contract:with_context() |
contract.security | ”security” | Contract:with_actor(), Contract:with_scope() |
Errores
Sección titulada «Errores»| Condición | Tipo |
|---|---|
| Formato de ID de binding invalido | errors.INVALID |
| Contrato no encontrado | errors.NOT_FOUND |
| Binding no encontrado | errors.NOT_FOUND |
| Método no encontrado | errors.NOT_FOUND |
| Sin binding por defecto | errors.NOT_FOUND |
| Permiso denegado | errors.PERMISSION_DENIED |
| Llamada fallida | errors.INTERNAL |