Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using versioning in conjunction with yarp reverse proxy #930

Open
1 task done
rezabashiri opened this issue Dec 1, 2022 · 7 comments
Open
1 task done

Using versioning in conjunction with yarp reverse proxy #930

rezabashiri opened this issue Dec 1, 2022 · 7 comments

Comments

@rezabashiri
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

We have a legacy .net framework and configured YARP to do a reverse proxy between the legacy one and the .net 6 migration one.

Those are working smoothly together but when I added a versioning library to implement API versioning inside .net 6 project for future developments, the reverse proxy didn't work anymore for the legacy API URLs.

Dotnet frameworks working under /v2 version and .net 6 would work in /v3 and uppers, but requests won't be redirected to /v2 anymore as APIVersioning assumes it as an invalid version.

I was looking for a way to override APIversioning middleware in some way but it seems it's not possible.

Describe the solution you'd like

I think its really needed to have a way to override middleware or something else to implement such scenarios

Additional context

No response

@commonsensesoftware
Copy link
Collaborator

Just to clarify and make sure I understand, you have two app:

  1. .NET Framework (4.x?) under ~/v2
  2. .NET 6.0 with API Versioning under ~/v3

Then you're using YARP to handle mapping between /v2 or /v3.

If that's the case, this might be the first time I'm aware of someone using this capability, but it is a supported feature. In this case, you're looking to advertise the API versions. This will not affect routing in /v3, but it will advertise to clients that other versions exist - somewhere. YARP or some other component handles the frontdoor.

Let's say that you have ASP.NET Web API on .NET 4.6.2 for /v2. It might look like:

[ApiVersion( 2.0 )]
[AdvertisesApiVersion( 3.0 )]
[RoutePrefix( "v{version:apiVersion}/demo" )]
public class DemoController : ApiController
{
    [HttpGet]
    [Route]
    public IHttpActionResult Get() => Ok();
}

Then in .NET 6.0 on the ASP.NET Core side, you have:

[ApiVersion( 3.0 )]
[AdvertisesApiVersion( 2.0 )]
[Route( "v{version:apiVersion}/[controller]" )]
public class DemoController : ControllerBase
{
    [HttpGet]
    public IActionResult Get() => Ok();
}

If both sides enable ReportApiVersions = true, then both /v2/demo and /v3/demo should both return api-supported-versions: 2.0, 3.0 even though it's not possible to route to both versions directly in the app (because they're different app). This also applies to deprecated versions and sunset policies.

Ultimately, API Versioning is hosted in an application so it's not possible to have contact with or route to external endpoints (the same as ASP.NET Core itself cannot). You can, however, loosely stitch things together so that it appears as one application to the outside world. Choosing which way to go is exactly the type of job a reverse proxy is supposed to do.

Hopefully that helps or perhaps I've missed something.

@rezabashiri
Copy link
Author

rezabashiri commented Dec 2, 2022

Thanks for your response, your understanding of structure is fine we are trying to migrate from .net legacy to.net 6 incrementally

I have no problem with API versioning itself and even with YARP itself, but since the YARP and API versioning is installed and configured in a single app in .net core side, when the request comes into the .net 6 pipelines API versioning service takes the control before YARP reverse /v2 versions to .net framework, hence API versioning throw error that /v2 is not a valid version while its valid version (URL) for .net framework.

I came across creating another project and hosting YARP services inside and put in front of both but this push us to host 3 different projects when ideally we'd like to host only 2 projects.

It's not client problem, it should totally handle by backend (seems advertising is not solution)

@commonsensesoftware
Copy link
Collaborator

Gotcha. I think we are largely on the same page.

API Versioning doesn't have any middleware. I'm not sure how it could be in front of YARP. I realize this is a bit of a complex setup, but if you have, or can produce, the most basic of repro, it would go long away. I think I have enough information to do it myself, but I've not used this setup myself. Ensuring I use the same setup as you is also helpful.

@rezabashiri
Copy link
Author

Sure, gonna make a sample repo, and it's not that complicated setup and would be needed in migration scenarios a lot I think.

You need to find a way to give YARP more precedence than versioning apis

@commonsensesoftware
Copy link
Collaborator

I'm not sure where the touch points are yet, but I did take a peek at some of the source. It looks like there is some involvement of ASP.NET Core routing system. Since 6.0, API Versioning has had to go lower into the routing stack. If it doesn't get in front of some of the basic routing behaviors, then 405, 406, and 415 responses don't work as expected or have to be reimplemented.

I'm sure there is a path forward here - somewhere. This is a scenario that was intended to be supported from the very beginning. However, in until something like YARP, this was pretty complicated and subjective to setup. I only would I like to see this scenario work, I'd like to able to add it as an example application.

@commonsensesoftware
Copy link
Collaborator

I've looked a little bit more at their code. I don't think the issue is necessarily precedence. Currently, there is a way to advertise that an API version exists elsewhere, but there isn't a way to tell the routing system "Yeah, this is a valid API version, but it doesn't exist here." If I had a repro to work backward from, then I have some ideas about how it might be enabled.

@commonsensesoftware
Copy link
Collaborator

Circling back around. I think that the issue here was that YARP and the versioned APIs were in the same project. The reverse proxy should be its own project. API Versioning with YARP is now configured in the eShop reference application for Aspire. Specifically, you are looking for the YARP configuration here.

I'll leave this open until I've had time to create an example or two here, but this should get you on your way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants