Wednesday, July 29, 2015

Ingredients for well-designed OWIN middleware components - Part 7

In the sixth post of this series I talked about how you can use Swagger to create real useful documentation for your API. In this seventh and probably last post, I'd like to present some spices to make that OWIN middleware component extra special.

Spice 1: Automate your entire build process using PSake
So you've completed the first version of your component and you're ready to ship it as a NuGet package. Manually creating that .nuspec file, running nuget.exe and publishing it to nuget.org is not that difficult to do. But now what? Are you going to do it like that forever? Of course not. That's why we have the power of PowerShell to our disposal, something that I already demonstrated with ingredient 6.

Spice 2: Choose the right release strategy
Now that you have your first release out of the door, you'll have to start thinking about when and how you're going to release feature versions of your component. Is any change you make that good that you can ship right away? Or do you first want to stabilize upcoming releases by shipping alpha or beta packages to be tested by your consumers. Within the git open-source world, two strategies have become kind of ad-hoc standards. There's a lot of documentation available, but the gist of it is that you should GitHubFlow if every change you do is production ready and GitFlow if you work on multiple features in parallel and get released after a period of testing. In both scenarios, GitVersion will help you automatically generate version numbers, just like I do in Piercer.

Spice 3: Decoupling through delegates
In ingredient 6 I talked about the example of having your component support an extension point in the form of the IPlugin interface. I suggested to put that interface in a separate NuGet package so that your extension point doesn't need to take a dependency on the middleware component package. An alternative approach for using an interface is to define the contract in the form of a delegate. So instead of taking the (simplified) interface definition…

public interface IPlugin
{
  bool IsMatch(Assembly assembly);
}

…you can have the middleware component also take a delegate like this:

public delegate bool AssemblyMatcher(Assembly assemby);

By doing so, any method that matches that signature can be passed in place of the delegate, thereby removing the need for the plugin to implement an interface or taking a dependency at all. Delegates exist since .NET 1.0, but somehow they didn't get the love they deserved.

Spice 4: Logging like a master
Now suppose your middleware component needs some kind of logging feature to help diagnosing production issues. You could take a dependency on Log4Net, Serilog or any other popular logging library. But then you have to think of a way to expose its configuration to consumers. But what if the host is hosting multiple components, all using different logging libraries? How would it manage to get all that logging to the same log file?

This is where LibLog by Damian Hickey comes into play. It's a sophisticated little NuGet package that just adds a single source file (so no public dependencies!) and auto-detects the logging library loaded in the AppDomain at run-time. It supports NLog, Log4Net, Enterprise Library, Serilog and Loupe. So from inside your component, you just use the logging API provided by LibLog. As long as the host uses one of the supported libraries, your logging statements will automatically forwarded. Personally, I prefer the structured logging magic provided by Serilog.

Spice 5: Dependency injection without dependencies
Just like you don't want to have an extra dependency for that logging library, you don’t want to expose your prefered dependency injection container to leak into your public API. Fortunately, my favorite DI container Autofac does not rely on any static state and can be used within your container perfectly fine. However, we've observed lots of problems internalizing Autofac within your main assembly with both ILRepack as well as ILMerge. So if you can live with a thinner feature set, I can highly recommend TinyIoc. Just like LibLog, its NuGet package will just add a single source file to your solution, which means no dependencies, nada, niente.


Well, that's all folks. After seven posts I think I've completed my recipe for building professional middleware components. What do you think? Does this all make sense? Comment below or tweet me at @ddoomen.

Monday, July 27, 2015

Ingredients for well-designed OWIN middleware components - Part 6

In the fifth post of this series I talked about some PowerShell tips to align the versions of all NuGet packages. In this sixth post, I'd like to show you how you can make your HTTP API much easier to use.

Ingredient 7: Swagger-enabled documentation
If your component exposes an HTTP API based on WebAPI, I would suggest you add support for Swagger documentation. Swagger has become the ad-hoc WSDL equivalent for HTTP-based API. Adding this to your WebAPI controllers is as easy as referencing the Swashbuckle NuGet package and attaching the following lines of code to your HttpConfiguration.

private static void EnableSwagger(HttpConfiguration configuration)
{
  configuration.EnableSwagger(c =>
  {
    c.SingleApiVersion("v1", "Piercer; easily diagnose run-time assemblies and threads");
    c.RootUrl(req => SwaggerDocsConfig.DefaultRootUrlResolver(req) + "/api");
    c.IncludeXmlComments(GetXmlCommentsPath());
  }).EnableSwaggerUi();
}

private static string GetXmlCommentsPath()
{
  return Assembly.GetExecutingAssembly().CodeBase.ToLower().Replace(".dll", ".xml");
}

In the case of Piercer, starting the Test Host and browsing to http://localhost:12345/api/swagger/docs/v1 returns the following JSON that you can use directly to generate code using swagger-codegen.

{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "Piercer; easily diagnose run-time assemblies and threads"
},
"host": "localhost:12345",
"basePath": "/api",
"schemes": ["http"],
"paths": {
"/piercer/assemblies": {
"get": {
"tags": ["Piercer"],
"summary": "Returns all the run-time assemblies of the host process.",
"operationId": "Piercer_GetAssemblies",
"consumes": [],
"produces": ["application/json",
"text/json",
"application/xml",
"text/xml"],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"deprecated": false
}
}
},
"definitions": {

}
}

On the other hand, if you would browse to http://localhost:12345/api/swagger/ui/index, you'll get this nice UI:

Customizing how your component exposes its HTTP APIs or tweaking the look and feel of the documentation page is all documented at the Swashbuckle landing page

Wednesday, July 22, 2015

Ingredients for well-designed OWIN middleware components - Part 5

In the fourth installment of this series I proposed a pattern for postponing expensive operations from inside your middleware component until the OWIN pipeline has been constructed. In this post, I'm going to talk about aligning package dependency versions. Why? Well, in my experience a well-designed middleware component may end up resulting in more than a single NuGet package. 

Ingredient 6: Automatic package version alignment
I'm not talking about its public dependencies (which you've obviously internalized), but about other output from the same solution. For instance, imagine your middleware component supports extension points or external services in the form of an IPlugin or IWhateverDependency that you can pass through your component's settings:

public class MyPlugin : IPlugin
{
}

appBuilder.UsePiercer(new PiercerSettings().Using(new MyPlugin());

Now, you could include the contract of those extensions, the IExtension interface, as part of the NuGet package that brings in the middleware component. But as an extension developer, that would require you to directly reference the middleware component. If you carefully design your component, I would put that extension interface in a dedicated NuGet package post-fixed with Extensions or something alike.

Assuming you use automatic versioning through GitVersion like I did in Piercer, you then have the problem of NuGet dependencies to solve. Since your middleware needs to take an implementation of the extension interface, it needs a dependency on the NuGet package that exposes the dependency. In Piercer I already demonstrated how to automatically version the assemblies using GitVersion, but that doesn't adopt the versions of the extensions package in the .nupec of the middleware package. As I assume you don't want to update the .nuspec manually, I wrote a little PSake task you can use in your build script.

task ConsolidateNuspecDeps {

  Write-Host "Updating all NuGet dependencies on $NuGetPackageBaseName.* to version ""$NuGetVersion""" {
    Get-ChildItem $SrcDir -Recurse -Include *.nuspec | % {

      $nuspecFile = $_.fullName;
      Write-Host "    $nuspecFile updated"
                
      $tmpFile = $nuspecFile + ".tmp"
              
      Get-Content $nuspecFile | `
          %{$_ -replace "(", "`${1} version=""$NuGetVersion""/>" } | `
      Out-File -Encoding UTF8 $tmpFile
      Move-Item $tmpFile $nuspecFile -force
   }
}


It will take two Powershell variables; $NuGetPackageBaseName to identity the items from the .nuspec's element that are part of the same set, and the $NuGetVersion to use for the final version. Notice that if you don't want to use specific versions, you're free to use a range like [1.0, 2.0) instead. 

Ingredients for well-designed OWIN middleware components - Part 4

In my last post I talked about unit testing your OWIN pipeline and briefly mentioned that you shouldn't do any heavy lifting from inside your UseWhatever method. Examples of that include starting background tasks or connecting to other services (through that HttpMessageHandler). If you're lucky, those tasks can be initiated in a laziness fashion. For instance, your component could use the first incoming request as a trigger to start that thread. However, some components might want to start processing some data as early as possible just to make sure that data is ready when the first request comes in. So how do you initiate those things instead?

Ingredient 5: Postpone the heavily lifting using startable components
Well, there's no real best practice, but what worked well for us is to return an object from the UseXXX extension method that implements IStartable and exposes a single asynchronous Start method.

    public class Startable : IStartable
    {
        private readonly Func<Task> starterFunc;

        public Startable(Func<Task> starterFunc)
        {
            this.starterFunc = starterFunc;
        }

        public Task Start()
        {
            return starterFunc();
        }
    }

Within your middleware extension method you can use it like this:

  public static IStartable UseMyComponent(this IAppBuilder appBuilder)
  {
    // Add whatever nested middleware or WebAPI stuff you need to the appBuilder

    return new Startable(() => async {
      // Do the heavy lifting such as creating threads, etc.
      await …
    })

  }

Tuesday, July 21, 2015

Ingredients for well-designed OWIN middleware components - Part 3

In my last post, I talked about decoupling the construction of the OWIN pipeline from the definition of the OWIN middleware component. In this post, I'm going to talk about the next ingredient, the testing story.

Ingredient 4: Testing your entire HTTP pipeline In most projects that are building ASP.NET MVC or WebAPI controllers, I've observed two testing strategies:
  1. Test the controller class directly by passing in strongly typed message objects and analyzing the resulting objects.
  2. Keep the controller code as thin as possible and test the underlying service code.

There used to be a WebAPI self-host that you could use from inside your unit test, but it still requires an actual network port. Although slow, it can work, provided that you don't run your unit tests in parallel (the default for XUnit 2).

The beauty of OWIN is that it doesn't have a direct dependency on an actual network stack. It just defines an abstraction based on simple types like dictionaries, tasks and funcs. It's Microsoft's Katana that provides an IIS host, a console host and even a Windows Service host. So ideally, your unit test could cover the entire OWIN pipeline without the need of real network ports, nor has any restrictions when they run in parallel with other unit tests. If you use OWIN, I wrote a unit test that asserts that Piercer returns its own assemblies when run from inside the unit test runner AppDomain like this.

[Fact]
public async Task When_specifying_an_explicit_route_it_should_be_reachable_through_that_route()
{
    var appBuilder = new AppBuilder();
    appBuilder.UsePiercer(new PiercerSettings().AtRoute("/myroute"));
    AppFunc app = appBuilder.Build();

    var httpClient = new HttpClient(new OwinHttpMessageHandler(appFunc));

    var result = await httpClient
      .GetStringAsync("http://localhost/myroute/piercer/assemblies");

    result.Should().Contain("Piercer.Middleware");
}

Using an independent AppBuilder allows you to build an in-memory OWIN pipeline accessible through an AppFunc. To send actual HTTP requests into that pipeline from a typical HttpClient object, you can use a nifty little library created by Damian Hickey, the OwinHttpMessageHandler. It will convert the HttpRequestMessage objects that the HttpClient client sends into the dictionary that the AppFunc expects, all without ever touching a network stack. You can check out its implementation here.

So imagine you're writing a middleware component that needs to communicate with the outside world. I assume you would probably add a property or method to your middleware's settings class (like PiercerSettings) taking the URL to communicate with. Well, don't do that. Instead, either take an HttpClient or a Uri and an optional HttpMessageHandler instance. If you take that optional HttpMessageHandler, callers can either pass in the actual URL to connect to or the aforementioned OwinHttpMessageHandler like this:

appBuilder.UsePiercer(new PiercerSettings()
.ConnectingTo(new Uri("http://localhost"));

Or within unit tests:

appBuilder.UsePiercer(new PiercerSettings()
.ConnectingTo(new Uri("http://localhost", new OwinHttpMessageHandler(appFunc))
);

The definition of the ConnectingTo method might look like this:

public PiercerSettings ConnectingTo(Uri uri, HttpMessageHandler handler = null)
{
httpClient = new HttpClient(handler ?? new HttpClientHandler())
{
BaseAddress = uri
};

return this;
}

Now assume that within your unit test, the component that you're connecting to should also be hosted on the same AppBuilder. You can't pass in the AppFunc until you've completed building the pipeline, so we're at a kind of stand-off here. You can fix that by relying on the delayed execution of lambda expressions. Just redefine the ConnectingTo method so that it takes a Func:

public PiercerSettings ConnectingTo(Uri uri, Func handlerFunc = null) { }

Then, you can do this:

AppFunc appFunc = null;

appBuilder.UsePiercer(new PiercerSettings()
.ConnectingTo(() => new OwinHttpMessageHandler(appFunc));

appBuilder.UseOtherService();

appFunc = appBuilder.Build();

The only caveat is that your middleware component shouldn't try to access the other service until the OWIN pipeline has been fully build. If that doesn't happen until your component is receiving its first HTTP request, you'll be fine. But if your component is doing some kind of background processing, you'll have to delay that explicitly, something I'll discuss in the next ingredient.