N NezamDocumentation

Services and APIs#

Services and APIs define explicit integration boundaries. Keep business policy in tables and resolver functions; services should orchestrate configured behavior.

Services#

bl
public service InvoiceService implements Approver, Notifier {
  inject repo: InvoiceRepository;

  config {
    retries: 3;
    timeout_ms: 5000;
  }

  on startup {
    repo.connect();
  }

  function approve(invoice_id: InvoiceId): bool {
    return true;
  }
}

Service members include injected dependencies, config or configuration blocks, lifecycle hooks, and functions. Inject declarations and config properties may end with semicolons. Lifecycle hooks use on <identifier> { ... }.

Service functions#

Service functions may include an access modifier and function modifiers before function. They use typed parameters with optional default expressions. Return types may use : or ->, and may be prefixed with async. Bodies can be blocks or abstract semicolon declarations.

bl
public service InvoiceService {
  public async function refresh_invoice(invoice_id: InvoiceId): Invoice;

  private inline function normalize_invoice(invoice: Invoice): Invoice {
    return invoice;
  }
}

HTTP APIs#

API declarations group HTTP endpoints. Endpoint parameters are optional: an endpoint may omit parentheses entirely when it has no parameters. Endpoint return types use : Type; route-local functions may use : or ->.

API declarations do not take annotations or access modifiers in the current grammar. Endpoint return types use only : Type; route-local functions may use : or ->, but route-local functions do not take access modifiers.

bl
api VendorApi {
  get "/vendors" list_vendors(): Json {
    return {};
  }

  post "/vendors" create_vendor(payload: Json): Json {
    return payload;
  }

  head "/vendors" ping;
}

Supported methods are get, post, put, delete, patch, head, and options.

Route blocks#

Route blocks group a method/path with route-local functions.

bl
api InvoiceApi {
  route post "/invoices" {
    function create(input: Json) -> async Json {
      return input;
    }
  }
}

Route-local functions support function modifiers, typed parameters with defaults, : or -> return types, and block or semicolon bodies.

bl
api InvoiceApi {
  route get "/invoices" {
    async function list(company_code: CompanyCode = current_company()) -> Json;
  }
}

Subscriptions#

Subscriptions bind code to table events.

bl
@audited
subscribe InvoiceChanged on table Invoice after update async (
  old_row: Invoice,
  new_row: Invoice
) {
  handle_invoice_change(old_row, new_row);
}

The grammar supports after insert, after update, and after delete. Dispatch mode is currently async.

Source: packages/business/language/services-apis.md