Zum Inhalt springen

Contracts

Rufen Sie Services über typisierte Contracts auf. Rufen Sie Remote-APIs, Workflows und Funktionen mit Schema-Validierung und Unterstützung für asynchrone Ausführung auf.

local contract = require("contract")

Öffnen Sie ein Binding direkt per ID:

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

Mit Scope-Kontext oder Query-Parametern:

-- Mit Scope-Tabelle
local svc, err = contract.open("app.services:user", {
tenant_id = "acme",
region = "us-east"
})
-- Mit Query-Parametern (automatisch konvertiert: "true"→bool, Zahlen→int/float)
local api, err = contract.open("app.services:api?debug=true&timeout=5000")
-- Mit Aufrufoptionen (drittes Argument)
local inst, err = contract.open("app.services:flaky", nil, {
retry = { max_attempts = 5, initial_delay = 100 }
})
ParameterTypBeschreibung
binding_idstringBinding-ID, unterstützt Query-Parameter
scopetableKontextwerte (optional, überschreibt Query-Parameter)
optionstableAufrufoptionen (optional) — z.B. retry.max_attempts, retry.initial_delay

Gibt zurück: Instance, error

Rufen Sie die Contract-Definition zur Introspektion ab:

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")
FeldTypBeschreibung
namestringMethodenname
descriptionstringMethodenbeschreibung
input_schemastable[]Eingabe-Schema-Definitionen
output_schemastable[]Ausgabe-Schema-Definitionen

Listen Sie alle Bindings auf, die einen Contract implementieren:

local bindings, err = contract.find_implementations("app.services:greeter")
for _, binding_id in ipairs(bindings) do
print(binding_id)
end

Oder über das Contract-Objekt:

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

Prüfen Sie, ob eine Instanz einen Contract implementiert:

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

Synchroner Aufruf - blockiert bis zum Abschluss:

local calc, err = contract.open("app.services:calculator")
local sum, err = calc:add(10, 20)
local product, err = calc:multiply(5, 6)

Fügen Sie das Suffix _async für asynchrone Ausführung hinzu:

local processor, err = contract.open("app.services:processor")
local future, err = processor:process_async(large_dataset)
-- Andere Arbeit erledigen...
-- Auf Ergebnis warten
local ch = future:response()
local payload, ok = ch:receive()
if ok then
local result = payload:data()
end

Siehe Futures für Future-Methoden.

Öffnen Sie ein Binding über das Contract-Objekt:

local c, err = contract.get("app.services:user")
-- Standard-Binding
local instance, err = c:open()
-- Spezifisches Binding
local instance, err = c:open("app.services:user_impl")
-- Mit Scope
local instance, err = c:open(nil, {user_id = 123})
local instance, err = c:open("app.services:user_impl", {user_id = 123})

Erstellen Sie einen Wrapper mit vorkonfiguriertem Kontext:

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()

Konfigurieren Sie Retry und anderes Aufrufverhalten ueber 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()

Optionen gelten fuer jeden Methodenaufruf der zurueckgegebenen Instanz. Nur retry-faehige Fehler loesen Wiederholungen aus; nicht retry-faehige Fehler erscheinen sofort. Verkettbar mit with_context, with_actor, with_scope.

OptionTypBeschreibung
retry.max_attemptsintMaximale Versuche inkl. dem ersten (1 deaktiviert Retry)
retry.initial_delayint/durationVerzoegerung vor erstem Retry (ms oder Duration-String)

Setzen Sie Actor und Scope für die Autorisierung:

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()
BerechtigungRessourceFunktionen
contract.getContract-IDget()
contract.openBinding-IDopen(), Contract:open()
contract.implementationsContract-IDfind_implementations(), Contract:implementations()
contract.callMethodennamesynchrone und asynchrone Methodenaufrufe
contract.context”context”Contract:with_context()
contract.security”security”Contract:with_actor(), Contract:with_scope()
BedingungArt
Ungültiges Binding-ID-Formaterrors.INVALID
Contract nicht gefundenerrors.NOT_FOUND
Binding nicht gefundenerrors.NOT_FOUND
Methode nicht gefundenerrors.NOT_FOUND
Kein Standard-Bindingerrors.NOT_FOUND
Berechtigung verweigerterrors.PERMISSION_DENIED
Aufruf fehlgeschlagenerrors.INTERNAL