temporalio / temporalio/sdk-typescript
[Feature Request] NestJS Transport / Integration?
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 917
- Forks
- 224
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 43
Description
Is your feature request related to a problem? Please describe.
It's more of a question: Temporal's Typescript SDK seems like it would maybe be a good fit as a NestJS Module, is this something there'd be interest in exploring? I'd need to spend a little bit of time on it but I'd love to validate whether it would work with a PoC, and see what kind of API we'd end up with.
Describe the solution you'd like
I'd just like to understand whether there's interest at this point, so I can invest some of my own time in exploring this.
Additional context
I would imagine an API to look something like (based on the Java Example):
@Workflow()
export class TripBookingWorkflow implements Workflow {
@InjectActivities({
startToCloseTimeout: ms("1hr"),
retryOptions: {
maxAttempts: 1,
},
})
activities: TripBookingActivities;
public async execute(name: string): Promise<void> {
const saga = new Saga({
parallelCompensation: true,
});
try {
const carReservationId = this.activities.reserveCar(name);
saga.addCompensation(this.activities.cancelCar, carReservationId);
const hotelReservationId = this.activities.bookHotel(name);
saga.addCompensation(this.activities.cancelHotel, hotelReservationId);
const flightReservationId = this.activities.bookFlight(name);
saga.addCompensation(this.activities.cancelFlight, flightReservationId);
} catch (err) {
saga.compensate();
throw err;
}
}
}
Supporting arbitrary frameworks
By testing whether the module loaded from workflowsPath exports a function as its default export, we can run & potentially await that function, (should be fine without this, given that it's an async function we can just return the promise) and then return it. This would put a contract on the return value though (Record<WorkflowName, WorkflowFn>), we should document that.
api.setImportFuncs({
importWorkflows: async () => {
let workflows = await import(/* webpackMode: "eager" */ ${JSON.stringify(this.workflowsPath)});
if (typeof workflows.default === 'function') {
workflows = workflows.default();
}
return workflows;
},
});
update: ☝️ this works 🥳
exporting an async function works too:

To do
- Discuss desired API
- If
worfklowsPathexports a function as itsdefault, await & return the result of that function. - Develop proof of concept
- Test out third-party Nest plugins that depends on custom file formats
- ???
- Profit
Design
Principles
- NestJS supports both monolithical applications, as well as smaller "microservices" (I don't mean the alternative transport layers Nest supports, I just mean smaller more focussed, independently deployable applications), and we should not make assumptions about this
- Registering Workflows & Workers through Nest's module system will, in the majority of cases, lead to undesirable outcomes; i.e., unintentionally doing things that have side effects or non-determinism and will break in subtle and hard to find ways.
- The APIs we design should feel familiar to NestJS developers, without incorrectly implying compatibility. We should warn users when they make mistakes, and document tradeoffs front and centre.
Operations
If you follow NestJS's design recommendations, your codebase should be split, roughly speaking, among domain lines by way of NestJS's module system. However, a single NestJS module might correlate to many Workers. [WIP]
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed NestJS API, the Supporting arbitrary frameworks section, and the Design principles in this issue. Build the requested proof of concept around workflowsPath and assess third-party Nest plugins with custom file formats. Done means the API and tradeoffs are validated, the proof of concept works, and the remaining design questions have clear answers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100