---
title: Invocation context
description: Use invocation metadata, cancellation, time, logging, environment, and declared clients without globals.
sidebar:
  icon: workflow
---

A function's second parameter, `context`, gives that invocation access to logging, time, cancellation, and its declared resources. RELKIT builds it from the checked graph, so a function
receives common runtime capabilities plus typed clients for only the resources it declares. Never store context
in a module variable or reuse it after the invocation completes.

## Use declared clients

> **Before you begin**
>
> This larger commerce reference assumes its selected cache is installed and bound. When adapting it
> to a minimal app, complete [cache setup](/guides/caching/cache-product-prices) first. Declaring a
> context edge does not install an adapter or native SDK.

```ts title="examples/commerce/src/services/orders/functions/create-order.function.ts"
/** Prices validated order input through the declared cache, records request tracing and derives its receipt key. */
import { defineFunction } from "@relkit/app/functions";
import prices from "../cache/prices.cache.js";
import { receiptObjectName } from "../../../platform/receipt-object.js";
import { createOrderOutput, orderInput } from "../../../platform/schemas.js";

const createOrder = defineFunction({
  // RELKIT validates these schemas before the handler runs.
  input: orderInput,
  output: createOrderOutput,
  dependencies: {
    cache: { prices },
  },
  timeoutMs: 10_000,
  concurrency: 100,
  handler: async (input, context) => {
    // Dependencies are accessed through the checked execution context.
    const unitPrice = await context.trace.span(
      "pricing.calculate",
      { attributes: { "pricing.strategy": "catalog" } },
      () => context.cache.prices.getOrSet({ sku: input.sku }, async () => 1_000),
    );
    context.trace.event("pricing.calculated", { "pricing.unit_cents": unitPrice });
    context.trace.setAttributes({ "pricing.quantity": input.quantity });
    const totalCents = unitPrice * input.quantity;
    return {
      orderId: input.orderId,
      receiptKey: receiptObjectName(input.orderId),
      totalCents,
    };
  },
});

export default createOrder;
```

This function declares the `prices` cache, so its handler receives `context.cache.prices`. Merely importing a
cache or putting it in the same domain does not grant access.

Event publication uses an explicit `publishes` list rather than `dependencies`:

```ts title="apps/docs/examples/events/create-order.function.ts"
import { defineFunction } from "@relkit/app/functions";
import { z } from "@relkit/app/schema";

const createOrder = defineFunction({
  input: z.object({
    orderId: z.string().min(1),
    sku: z.string().min(1),
    quantity: z.number().int().positive(),
  }),
  output: z.object({
    orderId: z.string(),
    sku: z.string(),
    totalCents: z.number().int().nonnegative(),
  }),
  publishes: ["orders.created"],
  handler: async (input, context) => {
    const order = { orderId: input.orderId, sku: input.sku, totalCents: input.quantity * 100 };
    await context.events["orders.created"].publish(order);
    return order;
  },
});

export default createOrder;
```

The exact event ID becomes available under `context.events`; publishing any undeclared ID fails the checked edge.

## Know the common context

| Value                                          | Use it for                                                                      |
| ---------------------------------------------- | ------------------------------------------------------------------------------- |
| `invocation`                                   | ID, trace, correlation, source, attempt, timing, deadline, and service metadata |
| `signal`                                       | Cancelling work and passing cancellation to lower-level calls                   |
| `env`                                          | Values resolved by the application's typed environment contract                 |
| `log`                                          | Structured, invocation-correlated records                                       |
| `trace`                                        | Child spans, point-in-time events, and attributes on the active span            |
| `time`                                         | Testable `now()` and abort-aware `sleep()` behavior                             |
| `jobs`, `events`, `buckets`, `cache`, `agents` | Clients authorized by declarations on the function                              |
| `database`, `auth`, `constants`, `prompts`     | Registered application context supplied by specialized integrations             |

There is no service middleware or `context.service`. A service exposes public functions and events; it does not
inject handler state. Database and Auth are specialized application context integrations, documented in
[Database](/docs/modules/database) and [Auth sessions](/docs/modules/auth/sessions).

RELKIT traces routes, functions, declared clients, jobs, events, tools, and agents automatically. Use
`context.trace` only for application work the runtime cannot infer. See [Observability](/docs/modules/operations/observability#add-application-trace-detail)
for the three tracing operations and an executable example.

## Add access safely

1. ### Define and bind the capability

    Follow its guide and choose the integration profile in `relkit.config.ts`.

2. ### Declare the graph edge

    Add the descriptor under the matching `dependencies` key. For publication, add the exact event ID to
    `publishes`.

3. ### Verify the edge and fake

    ```sh title="Terminal — relkit-orders"
    bun run check
    bun run test
    ```

    Provider-backed unit and application tests should receive explicit deterministic fakes.

{/* Generated by apps/docs/scripts/generate.ts. Do not edit. */}

**Reference and source**

- [`@relkit/functions` API](/docs/api/functions)

- [`examples/commerce/src/services/orders/functions/create-order.function.ts`](https://github.com/rel-kit/relkit/blob/main/examples/commerce/src/services/orders/functions/create-order.function.ts)
