'Handling $filter query parameters when setting up MapGet method on WebApplication class
As part of an integration test, I am using the WebApplication class to simulate the response of an external api call. I have a lot of setup code that ensures that when my code under test makes an http request, it is routed towards my WebApplication class instead of towards the internet.
To illustrate with an example: the following code snippet is setup such that I can control the response to any request made to https:api.example.com/products:
public class Product
{
public int Id { get; set; }
public string? Name { get; set; }
}
private void ConfigureProductsEndpoint(WebApplication testWebApi)
{
var products = new []
{
new Product { Id = 1, Name = "A Product" },
new Product { Id = 2, Name = "Another Product" }
};
testWebApi.MapGet("/products", () =>
{
return Results.Content(JsonSerializer.Serialize(products));
});
}
This works well, I can put a breakpoint on the return statement and it gets hit every time the endpoint is called. Http calls to the endpoint return the response with the 2 products as expected.
I can further customise the setup to take into account any query string parameters that have been used in the http request like so:
private void ConfigureProductsEndpoint(WebApplication testWebApi)
{
testWebApi.MapGet("/products", (int page, int size) =>
{
var products = new[]
{
new Product { Id = 1, Name = $"{page}" },
new Product { Id = 2, Name = $"{size}" }
};
return Results.Content(JsonSerializer.Serialize(products));
});
}
This also works in that when my code makes api calls to
https:api.example.com/products?page=2&size=10
the response contains products with name "2" and "10" as expected
What I'm actually trying to do is test requests to an api that follows the filtering syntax defined in the Microsoft REST API guidelines, so the endpoint I'm requesting actually contains query parameters that like this:
https:api.example.com/products?$filter=something
The C# language specification does not allow for variable names (or anything else for that matter) to contain the dollar symbol so that setup code like this does not compile
private void ConfigureProductsEndpoint(WebApplication testWebApi)
{
testWebApi.MapGet("/products", (string $filter) =>
{
var products = new[] { new Product { Id = 1, Name = "A Product" } };
return Results.Content(JsonSerializer.Serialize(products));
});
}
Dropping the dollar symbol, unsurprisingly, results in the WebApplication instance returning a 400 response as it has only been setup for a request without the dollar symbol.
I'm not aware of any way I can decorate the lambda expression's input parameters to add a dollar symbol at run time (like you could with the [JsonProperty] attribute). I have tried changing the type in the lambda expression. This also doesn't work as this is obviously designed to bind to the query parameters' field names, not value type.
The MS documentation page I have linked at the start of my question is light on example usages of this functionality, as is the rest of the internet
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
