Skip to content

Issue when express instance is shared between Dapr sever and another express application (Nest in my case) #718

@stperin

Description

@stperin

Expected Behavior

Dapr server and other application share express instance seamlessly

Actual Behavior

Express routing all request to the other application causing Dapr server not making subscription

Steps to Reproduce the Problem

import { NestFactory } from '@nestjs/core';
import { Module, Controller, Get } from '@nestjs/common';
import { DaprServer } from '@dapr/dapr';
import * as express from 'express';
import { ExpressAdapter } from '@nestjs/platform-express';

@Controller('hello')
class HelloController {
  @Get()
  getHello() {
    return { message: 'Hello from Nest + Dapr!' };
  }
}

@Module({
  controllers: [HelloController],
})
class AppModule {}

async function bootstrap() {
  const port = '3002';
  const server = express();
  const pubsubName = 'pubsub-name';
  // I'using JetStream as queue
  const topic1 = 'xxx.>';
  const topic2 = 'yyy.>';
  //
  //
  // Comment this and requests will only routed to Nest
  server.use((req, res, next) => {
    if (req.path.startsWith('/dapr') || req.path.startsWith('/events/'))
      return next();
    return next();
  });
  //
  //
  //
  const daprServer = new DaprServer({
    serverHost: 'localhost',
    serverPort: port,
    serverHttp: server,
    clientOptions: {
      daprHost: 'localhost',
      daprPort: '3500',
    },
  });
  await daprServer.pubsub.subscribe(
    pubsubName,
    topic1,
    async (data) => console.log(topic1),
    undefined,
    { rawPayload: true },
  );
  await daprServer.start();

  const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
  await app.init();
}

bootstrap();


Run and publish to topic with and without those lines commented.

Why is working with with middleware enabled

Before adding this middleware, some other Nest middleware or a catch-all route was intercepting POST /dapr/... or POST /events/... and returning 404.

When added this middleware, Express slightly changed the order in which middlewares/adapters were mounted. As a result, the routes registered by DaprServer ended up above Nest’s handlers and became reachable.

In other words, it’s not the actual if/else logic that fixed the problem — both branches just call next(). It only works because adding the middleware affected the mounting order, not because of the middleware’s content.

Proposed fix

Implement documentation and notify to use an express middleware to route dapr request to Dapr server and leave others to other application

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions