Highly configurable implementation of DelegatingHandler that can be used for mocking the behavior of requests sent to specific routes.
In order to use the interceptor all you need to do is register in using the DI of your choice, below example uses Microsoft built in DI:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Collection<HttpInterceptorOptions>>(Configuration.GetSection("HttpInterceptorOptions"));
services.AddTransient<InterceptingHandler>();
services.AddHttpClient("GitHubClient", client =>
{
client.BaseAddress = new Uri("https://api.github.com/");
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
client.DefaultRequestHeaders.Add("User-Agent", "HttpRequestInterceptor-Test");
})
.AddHttpMessageHandler<InterceptingHandler>();
services.AddMvc();
}
Configuration for the interceptor is provider via appsetting.json through the usage of options pattern.
This class represent a configuration entry that belong to a specific route or path. Configuration entry consist of:
- MethdoName: represents one of the standard HTTP methods and it is a required value
- Path: represents a route or a specific path that's going to be intercepted. Allows usage of wildecards "*". The parameter is required.
- ReturnStatusCode: represent response status code. The parameter is required and it must belong to one of standard status codes that can be found in HttpStatusCode enum.
- ReturnJsonContent: represents the serializes response content. It's an optional parameter.
This simplest example is when we want to intercept a specific request for example: /api/product/2 Intercepting this request can be achieved by providing this configuration in appsettings.json
"HttpInterceptorOptions": [
{
"MethodName": "GET",
"Path": "api/product/2",
"ReturnStatusCode": 200,
"ReturnJsonContent": "{ "Id": 1, "Name": "Product_1" }"
}
The above configuration will intercept only GET request that belong to "/api/product/2"
"HttpInterceptorOptions": [
{
"MethodName": "GET",
"Path": "api/product/59",
"ReturnStatusCode": 404,
"ReturnJsonContent": "{}"
}
The above configuration will return not found for the path: "api/product/59"
If we want to make the above example more generic, so that all the GET requests that belong to a route: /api/product got intercepted than we ca use this:
"HttpInterceptorOptions": [
{
"MethodName": "GET",
"Path": "api/product/*",
"ReturnStatusCode": 200,
"ReturnJsonContent": "{ "Id": 1, "Name": "Product_1" }"
}
The above configuration will intercept any GET request that is submitted on "/api/product/{id}", so "api/product/2" and "api/product/3" will get intercepted.
You can use more than one "*" sign if you need to:
"HttpInterceptorOptions": [
{
"MethodName": "GET",
"Path": "api/product/*/locations/*",
"ReturnStatusCode": 200,
"ReturnJsonContent": "{ "Id": 1, "Name": "Product_1" }"
}
The above configuratio will intercept GET request that belong to routes similar to "api/product/2/locations/london" or "api/product/2/locations/42"