Skip to main content
HTTP-invoked functions are deprecated (iii-http-functions) and will be removed in an upcoming release. Behavior is unchanged for now. This page is the migration guide.
Use this page to move every function registered with an HttpInvocationConfig to a regular handler that makes the same HTTP call from your worker. Callers do not change: the function keeps its id, and callers, observers and traces see the same function.

Why they are deprecated

An HTTP-invoked function makes the engine itself send an HTTP request to a URL that a connected worker chose. That puts an outbound HTTP client, its URL policy and its secrets inside the engine process:
  • Any worker allowed to register functions can make the engine reach any address its network position allows. The engine has to defend that boundary with security.url_allowlist, block_private_ips and require_https.
  • The auth fields name environment variables of the engine process, so a registering worker decides which engine secrets are sent, and to which URL.
  • Retries, timeouts, response mapping and signing are fixed by the engine instead of the worker that owns the integration.
A handler in your worker does the same job with the worker’s own network access and secrets, and the engine goes back to routing calls. Incoming HTTP is unaffected: the http worker keeps exposing functions as HTTP endpoints.

Timeline and support window

What the warnings look like:
  • Engine: a warn log with target iii::deprecation once per process when iii-http-functions starts, and when a worker registers a function with an HTTP invocation, at most once every 10 minutes per registering worker. The log names the entry point (HttpInvocationConfig), the worker when known and this guide. It never contains URLs, headers or payloads.
  • Node SDK: @deprecated JSDoc on HttpInvocationConfig, so editors strike it through. No runtime change.
  • Python SDK: register_function with an HttpInvocationConfig emits a FutureWarning pointing at your call site. Nothing is raised and behavior is unchanged.
  • Rust SDK: #[deprecated] on RegisterFunction::http.
  • Go SDK: Deprecated: doc comments on Client.RegisterHTTPFunction, HTTPInvocationRef and http.InvocationConfig.

What is deprecated and what is not

Deprecated:
  • The iii-http-functions engine worker and its security block (url_allowlist, block_private_ips, require_https).
  • Registering a function with an HTTP invocation: Node and Python HttpInvocationConfig passed to registerFunction or register_function, Rust RegisterFunction::http, and Go Client.RegisterHTTPFunction.
  • The engine-side request signing (x-iii-Signature) and the auth types that name engine environment variables (hmac, bearer, api_key).
Not deprecated, keep using them:
  • Function registration with a handler, calls and observers in every SDK.
  • The http worker, which exposes functions as HTTP endpoints (incoming HTTP).
  • The web worker and its web::fetch function for outbound requests from a worker.
  • Alert webhooks of iii-observability.

Replace an HTTP-invoked function with a handler

The function below was registered with an HttpInvocationConfig. The engine sent the input as the JSON body, added the bearer token read from its own MATH_API_TOKEN variable, and returned the JSON response:
Register the same id with a handler that makes the call. Set MATH_API_TOKEN in the worker’s environment instead of the engine’s.
Rust and Go follow the same pattern: register the id with RegisterFunction::new_async or Client.RegisterFunction and make the request with the HTTP client your worker already uses. Keep the details the engine handled for you:
  • Errors: the engine treated a status of 400 or more as a failure and passed the error.code and error.message of a JSON error body to the caller. An error that a handler throws or raises reaches the caller as invocation_failed with your message, so the service’s code is not kept. The examples put the code in the message. Update callers and observer filters that match on service codes such as LIMIT_EXCEEDED.
  • Redirects: the engine never followed redirects, and returned a 1xx or 3xx response as a success with no result unless its body was JSON. The examples do the same. Following a redirect can also send the Authorization header to another host, so keep redirects off unless the target needs them.
  • Timeouts: timeout_ms defaulted to 30 seconds. Set an explicit timeout on the request.
  • Headers: the engine sent x-iii-Function-Path, x-iii-Invocation-ID and x-iii-Timestamp with every request. Add them only if the target reads them.

Request signing

If the target verifies x-iii-Signature (the hmac auth type), compute the same signature in the handler, or move the target to bearer or API key authentication. The engine computed HMAC-SHA256 with the secret over {timestamp}:{base64 of the body}, sent the hex digest as sha256={digest} in x-iii-Signature, and sent the Unix timestamp in seconds in x-iii-Timestamp:

URLs that come from input

The examples above call a fixed URL, so the worker decides where requests go. If the URL comes from the function input, call web::fetch from the handler instead of your own client. It rejects private, link-local and reserved addresses and pins the connection to the address it validated. Loopback addresses are allowed by default. Set web.allow_loopback: false to reject them.

Remove iii-http-functions from the engine

After every function is a handler, delete the iii-http-functions entry and its security block:
An engine that a supervisor runs from config.yaml drops the same entry from its workers list. Once no worker registers an HTTP invocation and the entry is gone, the engine logs no iii-http-functions deprecation warnings.