Use .provide(tag, fn) when a service depends on the current request.
Providers can be generator callbacks, Effect.fn(...) callbacks, or functions that return an Effect.
Common examples:
- current user
- request ID
- tenant ID
- authorization scope
- locale
Provide from context
import { Context, Effect } from "effect";
class CurrentUser extends Context.Service<
CurrentUser,
{ readonly id: string; readonly role: "admin" | "member" }
>()("CurrentUser") {}
const authedProcedure = eos
.provide(AppLive)
.$context<{ user: { id: string; role: "admin" | "member" } }>()
.provide(CurrentUser, ({ context }) => Effect.succeed(context.user));
const me = authedProcedure.effect(function* () {
return yield* CurrentUser;
});
Providers can also use parsed input.
class TenantId extends Context.Service<TenantId, string>()("TenantId") {}
const tenantProcedure = eos
.provide(AppLive)
.input(z.object({ tenantId: z.string() }))
.provide(TenantId, ({ input }) => Effect.succeed(input.tenantId))
.effect(function* () {
const tenantId = yield* TenantId;
const projectsRepo = yield* ProjectsRepo;
return yield* projectsRepo.listForTenant(tenantId);
});
Provider callback shapes
Request-scoped providers can be generator callbacks, Effect.fn(...) callbacks, or functions that return an Effect.
const authedProcedure = eos.$context<{ user: User }>().provide(
CurrentUser,
Effect.fn("current-user.resolve")(function* ({ context }) {
yield* Effect.logDebug("resolving current user");
return context.user;
}),
);
Optional providers
Use .provideOptional(...) when a service may be absent. The provider returns an Option and does not satisfy required service access. Optional providers support the same generator and Effect-returning callback shapes.
import { Option } from "effect";
const maybeAuthed = eos
.$context<{ user?: { id: string } }>()
.provideOptional(CurrentUser, ({ context }) =>
Effect.succeed(Option.fromNullishOr(context.user)),
)
.effect(function* () {
return yield* Effect.serviceOption(CurrentUser);
});
Optional providers are useful for anonymous-or-authenticated routes. If a
handler requires the service, use .provide(...) instead.
Next step
Add client-visible failures with Typed errors.