dapr / dotnet-sdk

Dapr SDK for .NET
Apache License 2.0
1.11k stars 334 forks source link

[Topic] Attribute doesn't support dynamic routes #1130

Open fabistb opened 1 year ago

fabistb commented 1 year ago

Currently the [Topic] cant be used if the route contains a dynamic part. A example here is a version in the route.

Example dynamic route:

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{v:apiVersion}/example]
public class ExampleController : ControllerBase
{
  [HttpPost()]
  [Topic("messagebus", "topic")
  public async Task<IActionResult> PubSub([FromBody] object message)
  {
  ...
  }
}

Example static route:

[ApiController]
[Route("api/v1.0/example]
public class ExampleController : ControllerBase
{
  [HttpPost()]
  [Topic("messagebus", "topic")
  public async Task<IActionResult> PubSub([FromBody] object message)
  {
  ...
  }
}

Is their a specific reason why the dynamic routes aren't supported?

halspang commented 1 year ago

As far as I'm aware, there is no direct reason for it not working. We just parse the attributes and add them to an endpoint collection.

I'm not super familiar with this space though, does this work for other attributes that are nested like this? I'm worried the reason it wouldn't work is because we're taking the literal and don't have the information to interpret the path when we read the attributes.

fabistb commented 1 year ago

Thanks for the explanation.

Not sure here since I also can't think about an attribute currently which is as nested as this one.

philliphoff commented 1 year ago

It looks like the Dapr route building logic doesn't support routes with parameters (i.e. the logic assumes the parts are all literals):

https://github.com/dapr/dotnet-sdk/blob/99d874a2b138af020df099a0fc0a09a7d0597fae/src/Dapr.AspNetCore/DaprEndpointRouteBuilderExtensions.cs#L201

As @halspang suggests, we'd need to investigate whether we can get the resolved values out of ASP.NET in order to build the route strings.

philliphoff commented 1 year ago

I believe this is the same issue as #791 and #882. As was mentioned in those issues, there is a fundamental question of how Dapr subscriptions should work in a multi-versioned API (the likely reason for having dynamic routes). For example, if two controllers representing two versions of the same API have the same topics (i.e. what's the likelihood of these changing between API versions), how should messages be delivered?