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

Question: Can I use HttpContext to dynamically map to a remote API endpoint? #1510

Closed
krispenner opened this issue Dec 7, 2024 · 7 comments
Labels

Comments

@krispenner
Copy link

Which version of Duende BFF are you using?
2.2.0

Which version of .NET are you using?
8.0

Describe the question

I'd like to use the HttpContext to dynamically decide the remote API endpoint to use at runtime.
Maybe this is exposed via some other means and you can point me there.

To Reproduce

The only thing I can seem to do is statically map the remote API endpoint.

endpoints.MapRemoteBffApiEndpoint("api/localpath", "https://api.domain.com/remote");

Expected behavior

I'd like to dynamically chose the remote API endpoint based on the request.

endpoints.MapRemoteBffApiEndpoint("api/localpath",
    ctx => ctx.RequestHeaders["XXX] == "1" ? 
        "https://new.domain.com/new-remote" : 
        "https://api.domain.com/default-remote");
@krispenner krispenner added the BFF label Dec 7, 2024
@amiriltd
Copy link

I believe you can just use the MapPost method and then attach the AsBffApiEndpoint() to accomplish what you are looking for.

app.MapPost("api/localpath", ctx => { ctx.RequestHeaders["XXX] == "1" ? 
        "https://new.domain.com/new-remote" : 
        "https://api.domain.com/default-remote"; })
    .RequireAuthorization()  // no anonymous access
    .AsBffApiEndpoint();     // BFF pre/post processing

@RolandGuijt
Copy link

@krispenner Did the above comment do the trick for you?

@krispenner
Copy link
Author

Thank you @RolandGuijt, I didn’t realize I could do this.

It would be helpful if you added overloads to your MapRemoteBffApiEndpoint that does this internally for us. Just to keep it simple and consistent.

@krispenner
Copy link
Author

@RolandGuijt I am trying your suggestion but I can't find any Map() method that allows a simple string to be returned and it's not obvious to me what to do with the remote address selected based on the HttpContext.

public static void MapRemoteEndpoints(this IEndpointRouteBuilder endpoints)
{
    ArgCheck.NotNull(nameof(endpoints), endpoints);

    var remoteEndpoints = endpoints.ServiceProvider.GetServices<RemoteApiEndpoint>();

    foreach (var remoteEndpoint in remoteEndpoints)
    {
        var localPath = remoteEndpoint.LocalPath;
        IEndpointConventionBuilder remoteEndpointBuilder;

        if (remoteEndpoint.RemoteAddressSelector != null)
        {
            remoteEndpointBuilder = endpoints.Map(localPath, ctx =>
            {
                var remoteAddress = remoteEndpoint.RemoteAddressSelector(ctx);  // Func<HttpContext, string>
                return remoteAddress; // This does not work and it's not obvious what to do with this remote address string here.
            }).AsBffApiEndpoint();
        }
        else
        {
            var remoteAddress = remoteEndpoint.RemoteAddress;
            remoteEndpointBuilder = endpoints.MapRemoteBffApiEndpoint(localPath, remoteAddress);
        }

       // Configure BFF endpoint....
    }
}

@krispenner krispenner reopened this Jan 7, 2025
@AndersAbel
Copy link
Member

The BFF has two configuration models for working with YARP:

  1. Our simple MapRemoteBffApiEndpoint() that is as simple as possible to use, but only covers basic scenarios.
  2. Attaching BFF behaviour to an existing YARP config.

We are not planning to add more features to the MapRemoteBffApiEndpoint() model - it's only meant for simple scenarios. If you want to do anything more complex, YARP is very powerful and can most likely do what you want. You would have to create the YARP config yourself to resolve the remote API endpoint. Then you would apply our BFF extensions to the YARP configuration, please see https://docs.duendesoftware.com/identityserver/v7/bff/apis/yarp/.

@RolandGuijt
Copy link

@krispenner Do you have additional questions around this issue or can we close it?

@RolandGuijt
Copy link

Closing the issue for now but feel free to reopen if needed.

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

No branches or pull requests

4 participants