
Webiny Use Case Pattern
UseCase implementation pattern, DI, Result handling, error types, decorators, CMS...
Install
npx skills add webiny/webiny-js --skill webiny-use-case-pattern -g -a claude-code -y- Repository
- webiny/webiny-js8.1k
- Category
- Engineering
- Updated
- 5d ago
- License
- See repository
- Context cost
- Mediumabout 3,000 tokens
- Runs scripts
- No, instructions only
What it does
UseCase implementation pattern, DI, Result handling, error types, decorators, CMS repositories, entry mappers, and schema-based permissions. Use this skill to implement, inject, override, or decorate any Webiny UseCase, or to build repositories that persist data via CMS.
UseCase Pattern
What It Is
A UseCase is a single-method orchestrator that encapsulates one business operation (e.g., CreateTenantUseCase, PublishEntryUseCase). Each UseCase is a DI abstraction with an execute method that returns Result<T, E>.
Interface Shape
interface SomeUseCase.Interface {
execute(input: Input): Promise<Result<ReturnType, ErrorType>>;
}
- Input, a typed object specific to the use case
- Result, always returns
Result<T, E>fromwebiny/api - Error, extends
BaseErrorwith a uniquecode
How to Use a UseCase
UseCases are injected as dependencies into EventHandlers, other UseCases, or GraphQL resolvers via DI.
import { SomeUseCase } from "webiny/api/<category>";
import { SomeEventHandler } from "webiny/api/<category>";
class MyHandler implements SomeEventHandler.Interface {
constructor(private someUseCase: SomeUseCase.Interface) {}
async handle(event: SomeEventHandler.Event) {
const result = await this.someUseCase.execute({/* input */});
if (result.isFail()) {
console.error(result.error.message);
return;
}
const value = result.value;
// ... use value
}
}
export default SomeEventHandler.createImplementation({
implementation: MyHandler,
dependencies: [SomeUseCase]
});
How to Override a UseCase
To replace the default implementation, register your own:
import { SomeUseCase } from "webiny/api/<category>";
class CustomImplementation implements SomeUseCase.Interface {
async execute(input) {
// Custom logic
return Result.ok(/* ... */);
}
}
export default SomeUseCase.createImplementation({
implementation: CustomImplementation,
dependencies: []
});
Registration
YOU MUST include the full file path with the .ts extension in the src prop. For example, use src={"@/extensions/my-extension.ts"}, NOT src={"@/extensions/my-extension"}. Omitting the file extension will cause a build failure.
