Skip to content

Context (StrataContext)

The StrataContext class is a logical grouping of related operations -- analogous to an Express Router. You create contexts, register operation handlers on them, then register the context with the service.

For conceptual background, see Architecture.

typescript
import { StrataContext } from '@strata-js/strata';

// Also exported as `Context` for convenience
import { Context } from '@strata-js/strata';

Constructor

typescript
new StrataContext(contextName ?: string)

Creates a new context. The name is optional here -- you can provide it when registering with the service instead.

typescript
const users = new StrataContext('users');
const orders = new StrataContext(); // name provided at registration time

Properties

PropertyTypeDescription
contextNamestring | undefinedThe name set in the constructor, if any.
contextMiddlewareListOperationMiddleware[]All middleware registered at the context level.
operationsMiddlewareListOperationMiddleware[]All middleware registered at the operation level (deduplicated).

Methods

registerOperation()

typescript
context.registerOperation<ReturnPayloadType>(
    opName : string,
    opFunc : OperationHandler<ReturnPayloadType>,
    opFuncParams : string[] = [],
    middleware : OperationMiddleware[] = []
) : void

Registers a function as a named operation on this context. Throws AlreadyRegisteredError if the name is taken.

Parameters:

ParameterTypeDefaultDescription
opNamestring--The operation name clients will use to call this handler.
opFunc(...args) => Promise<PayloadType>--The async handler function.
opFuncParamsstring[][]Property paths to extract from the request and pass as arguments.
middlewareOperationMiddleware[][]Middleware to apply to this operation only.

Parameter Order

The third argument is opFuncParams (request property extraction), not middleware. Middleware is the fourth argument.

Basic Usage

By default, the handler receives the full StrataRequest object:

typescript
context.registerOperation('get', async (request) =>
{
    const { userId } = request.payload;
    const user = await db.findUser(userId);
    return { user };
});

If the handler returns a value and hasn't called request.succeed() or request.fail(), the return value is automatically used as the success payload.

With opFuncParams

The opFuncParams array lets you extract specific properties from the request and pass them as individual arguments. This is useful for keeping your handlers clean and decoupled from the request object. Each string is a lodash-style property path evaluated against the request.

typescript
// Handler receives (payload, auth) instead of (request)
context.registerOperation('get', async (payload, auth) =>
{
    const user = await db.findUser(payload.userId);
    return { user };
}, [ 'payload', 'auth' ]);
typescript
// Handler receives individual payload fields
context.registerOperation('update', async (userId, updates) =>
{
    const user = await db.updateUser(userId, updates);
    return { user };
}, [ 'payload.userId', 'payload.updates' ]);

When opFuncParams is empty (the default), the full StrataRequest is passed as the only argument.

With Operation-Level Middleware

typescript
context.registerOperation('get', async (request) =>
{
    return { user: await db.findUser(request.payload.userId) };
}, [], [ new CacheMiddleware({ ttl: 60000 }) ]);

registerOperationsForInstance()

typescript
context.registerOperationsForInstance<T>(
    instance : T,
    opFuncParams : string[] = [],
    middleware : OperationMiddleware[] = [],
    opModifiers : { include ?: string[], exclude ?: string[] } = {}
) : void

Convenience method that registers all public methods of an object as operations. Each method becomes an operation with a matching name.

Excluded automatically: the constructor, and any methods starting with _ or $.

Parameters:

ParameterTypeDefaultDescription
instanceT--The object whose methods become operations.
opFuncParamsstring[][]Property paths extracted from the request, applied to all methods.
middlewareOperationMiddleware[][]Middleware applied to all registered operations.
opModifiers{ include?: string[], exclude?: string[] }{}Filter which methods to register. exclude takes precedence.
typescript
class UserManager
{
    async get(payload : { userId : string })
    {
        return { user: await db.findUser(payload.userId) };
    }

    async list()
    {
        return { users: await db.listUsers() };
    }

    // Excluded automatically (starts with _)
    async _internalMethod() { /* ... */ }
}

const manager = new UserManager();
const users = new StrataContext('users');

// Register all public methods as operations, passing `payload` to each
users.registerOperationsForInstance(manager, [ 'payload' ]);

// Cherry-pick methods
users.registerOperationsForInstance(manager, [ 'payload' ], [], {
    include: [ 'get' ],
});

// Exclude specific methods
users.registerOperationsForInstance(manager, [ 'payload' ], [], {
    exclude: [ 'list' ],
});

useMiddleware()

typescript
context.useMiddleware(middleware : OperationMiddleware | OperationMiddleware[]) : void

Registers context-level middleware that runs on every operation in this context. Accepts a single middleware or an array.

For how middleware ordering works across service, context, and operation levels, see Middleware Model.

typescript
const users = new StrataContext('users');
users.useMiddleware(new RateLimitMiddleware());

getOperationNames()

typescript
context.getOperationNames() : string[]

Returns a list of all registered operation names.

typescript
const names = users.getOperationNames();
// [ 'get', 'create', 'delete' ]

Registering with the Service

A context does nothing until it's registered with a StrataService. Registration must happen before calling service.start().

typescript
import { StrataService, StrataContext } from '@strata-js/strata';

const service = new StrataService(config);

const users = new StrataContext('users');
users.registerOperation('get', async (request) =>
{
    return { user: await db.findUser(request.payload.userId) };
});

// Register with service (uses context's name)
service.registerContext(users);

// Or register under a different name
service.registerContext('accounts', users);

await service.start();

TIP

You can register the same context instance under multiple names. Both names will route to the same context. This is valid, but be aware they share the same state and middleware.