temporalio / temporalio/sdk-typescript

[Feature Request] NestJS Transport / Integration?

Open
#483 37 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ecosystem-and-integrations enhancement
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 🥳

image

exporting an async function works too:

image

To do

  • Discuss desired API
  • If worfklowsPath exports a function as its default, 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
  1. 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
  2. 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.
  3. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.