Apizr – Part 3: More advanced features

apizr3

This article is part of a series called Apizr:

After Part 1 with general presentation and Part 2 with core features walk-through, this time we’ll go deeper into some advanced scenarios.

ADVANCED CORE FEATURES
The options builder provide you some advanced core features.
BASE ADDRESS
The WebApi attribute let you define the base address with a simple attribute decoration over your api interface.
But sometime, we need to change the endpoint, targeting dev, test or production server uri.
To deal with it, the builder expose a method called WithBaseAddress to let you set it by code, like:
// For both ways
builder.WithBaseAddress(Constants.MyConfigurationAwareAddress)

// Or for static way
builder.WithBaseAddress(() => GetMyConfigurationAwareAddress())

// Or for extended way:
builder.WithBaseAddress(serviceProvider => serviceProvider.GetService<MySettingsService>().MyConfigurationAwareAddress)
DELEGATING HANDLER
You can register your own DelegatingHandler , it will be integrated with all others by Apizr:
// For both ways
builder => builder.AddDelegatingHandler(new MyCustomDelegatingHandler())

// Or for static way (with a logHandler instance to log all from your handler)
builder => builder.AddDelegatingHandler(logHandler => new MyCustomDelegatingHandler(logHandler))

// Or for extended way
builder => builder.AddDelegatingHandler(serviceProvider => new MyCustomDelegatingHandler(serviceProvider.GetService<ILogHandler>()))
This is what Apizr use to manage authentication, prioritization, policies and network traces.
If there’re some custom scenarios you want to cover while sending the request, just provide your own DelegatingHandler.
HTTP CLIENT HANDLER
You can provide your own HttpClientHandler  to Apizr:
// For static way
builder => builder.WithHttpClientHandler(new MyCustomHttpClientHandler())

// Or extended way
builder => builder.WithHttpClientHandler(serviceProvider => new MyCustomHttpClientHandler())

This one gives you access to several deep settings.

This is where you can deal with cookies, decompression, proxy, certificate validation and many more…

Something like this dummy example:

        builder => builder.WithHttpClientHandler(serviceProvider => new HttpClientHandler
        {
            CookieContainer = serviceProvider.GetRequiredService<ISessionService>().Cookies,
#if DEBUG
            ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => true
#endif
        })
HTTP CLIENT BUILDER

The extended way let you adjust more and more HttpClient settings with the HttpClientBuilder:

// For extended way only
builder => builder.ConfigureHttpClientBuilder(httpClientBuilder => httpClientBuilder.WhateverSettings)

Use this one with caution as Apizr makes use of it, so you could override things that could leads to unstable experience.

This is where you can configure complexe policies for example, like:

var timeout = Policy.TimeoutAsync<HttpResponseMessage>(
    TimeSpan.FromSeconds(10));
var longTimeout = Policy.TimeoutAsync<HttpResponseMessage>(
    TimeSpan.FromSeconds(30));

builder => builder.ConfigureHttpClientBuilder(httpCientBuilder => 
    httpCientBuilder.AddPolicyHandler(request => 
        request.Method == HttpMethod.Get ? timeout : longTimeout))
REFIT SETTINGS

You can provide your own RefitSettings:

// For both ways
builder.WithRefitSettings(new RefitSettings())

// Or for static way
builder.WithRefitSettings(() => new RefitSettings())

// Or for extended way:
builder.WithRefitSettings(serviceProvider => new RefitSettings())

RefitSettings let you adjust some Refit parameters like the ContentSerializer, the UrlParameterFormatter or the FormUrlEncodedParameterFormatter.

Something like:

builder => builder.WithRefitSettings(new RefitSettings(new NewtonsoftJsonContentSerializer(new JsonSerializerSettings
    {
        Error = delegate(object sender, ErrorEventArgs args)
        {
            Logger.Write(args.ErrorContext.Error)();
            args.ErrorContext.Handled = true;
        },
        Converters = {new IsoDateTimeConverter()}
    })))

Please refer to Refit official documentation to know more about it.

OVERRIDING
Almost everything could be overridden with Apizr.
You found everything you need and ready to play? Pleased to hear that!
You’d like to adjust some behaviors while requesting?
Well you can provide your own handlers as we’ve seen it (http, logging, caching, networking).
But guess what? You also can provide your own implementation of the heart of the beast aka IApzrManager<TWebApi>.
When you think you’re done designing your own ApizrManager, just provide it while initializing Apizr, like:
AddApizrFor<IMyAwesomeApi, MyAwsomeManager<IMyAwesomeApi>>>()
CONCLUSION
In this short article we talked about advanced Apizr core features. But we still can get extended features thanks to some integrations NuGet packages.
In the next one, I’ll talk about requesting with Mediator pattern to keep all things loosely coupled, simple and unified.
You’ll find all sources and samples on GitHub.

JeremyBP

Specialized since 2013 in cross-platform applications development for iOS, Android and Windows, using technologies such as Microsoft Xamarin and Microsoft Azure. Initially focused, since 2005, on development, then administration of Customer Relationship Management systems, mainly around solutions such as Microsoft SharePoint and Microsoft Dynamics CRM.

Related Posts

Leave a comment

four × 2 =