The Functional Nature of Web API

Since my last post on the functional nature of the web, I’ve given two presentations describing this idea in more detail. Unfortunately, circumstances have conspired against me such that I have been unable to build any good sample apps. That’s about to change, as I’ve started working on screencasts on Web API that I’ll be posting here and on as I complete them.

As a preview, In this post I’ll describe the inherent functional nature of Web API. You have looked into Web API at all, you’ve probably seen the Contact Manager sample application, originally created by the infamous “2C”. (Kudos to Dan Roth on the Web API team for keeping it alive!) The controller-based goodness baked into Web API hides a lot of the functional nature, so I will understand if you think I’m a little crazy for my statement above.

See? Not so much? Okay, how about in F#?

type MyMessageHandler() =
    inherit System.Net.Http.HttpMessageHandler()
    override x.SendAsync(request, cancellationToken) =
        (* Implementation ... *)

Eh, let’s try again.

val app : HttpRequestMessage -> Async<HttpResponseMessage>
let app request = async { return response }

let makeHandler app =
    { new System.Net.Http.HttpMessageHandler() with
        override x.SendAsync(request, cancellationToken) =
            Async.StartAsTask <| app request }

Here I use several unique features of F# to emphasize the point. The type signature should be familiar from my last post. I then create a handler using F#’s object initialization syntax, which creates an instance from a base class using the app from above. I think I’ve made my point that, at its heart, the HttpMessageHandler is functional in its core.

Okay, let’s translate back to C#-land. We don’t have object initialization syntax, but we can create pure, functional approaches for C#. Also, we’ll use DelegatingHandler, as that’s the actual type you’ll need to inherit in order to use it in Web API. (I apologize now for making your eyes bleed with the type signatures.)

Why is this core?

I’ve mentioned this is core, but if you’ve only used Web API with controllers, you may never have interacted with HttpMessageHandlers. HttpMessageHandlers are at the root of everything. HttpClient, HttpServer, and everything else that uses these types all inherit HttpMessageHandler. If you look deep into Web API, you find this consistency of HttpMessageHandler at the core. What does that mean? It means “it’s [functions] all the way down.”

A quick example

You can see this in action in the AspNetWebApi.Conneg sample application.

Okay, so now we have our “function.” How would you hook this up? That’s also quite simple. HttpApplication now has a GlobalConfiguration courtesy System.Web.Http. This provides you access to an instance of HttpConfiguration, which provides you all the extensibility points for managing your Web API. The Self Host option let’s you create your own. Attaching a handler is dead simple:

The point

By no means am I trying to convince you to give up all the ease of built-in model binding and conneg. I only want to drive home the point that the core of Web API is really just functions. As I mentioned previously, HTTP exhibits a very strong functional side. Web API really addresses this head on and provides a very solid core for building web applicaitons, whether using a more MVC-style or functions directly.

Try it out. For really simple applications, you are likely to find that these are all you need. You may also appreciate that you can implement your own routing and other mechanisms directly within a composed set of functions. We’ll explore this more as we continue in this series, so stay tuned.

HTTP and Functional Programming

I made what some might consider a bold claim on Twitter this past Friday, that HTTP holds to the functional programming paradigm. For the purposes of demonstration, I’ll be using F# as a means of declaring function and type signatures, though you can use any language in a functional style. I’ll further use type names from Microsoft’s new Web API library. (Actually, I’ll be sticking to the System.Net.Http types, which are already generally available in the HttpClient NuGet package and will be part of .NET 4.5.)

The Basics

At the bare minimum, HTTP supports an interface in which a client submits an HttpRequestMessage and responds with an HttpResponseMessage. This contract can be represented as a function with the following signature:

HttpRequestMessage -> HttpResponseMessage

I could try to just leave it here and say, “See, it’s a function!” but that would be cheating a bit. Nevertheless, the essential contract for HTTP is a simple function. That’s at least something.


Let’s dive a bit deeper. What precisely might one mean by “functional programming paradigm”? Typically, you’ll see some variation on the following list (which is by no means exhaustive):

  • Declarative – what not how
  • Pure functions – a function with no side-effects such as I/O or mutating global state
  • First-class and higher-order functions – functions can be created and passed as parameters just like other values
  • Referential transparency – an expression can be replaced with its value without changing program behavior
  • Memoization – a performance enhancing technique made possible by referential transparency

Aligning the above items with ideas found in HTTP, we get:

  • Declarative -> HttpRequestMessage headers
  • Pure functions -> Safe, idempotent HTTP methods such GET and HEAD
  • First-class and higher-order functions -> Hypermedia controls and content negotiation
  • Referential transparency and Memoization -> Cache control mechanisms


Declarative HTTP

This is the easiest to demonstrate. Request headers are nothing other than a means to declare what you want (e.g. Request Line) and set expectations (e.g. Accept). The entire HttpRequestMessage exists as a means of expressing intent. As a client, you have absolutely no chance of instructing the server on how to process your request. Even RPC-style calls must abide by this constraint, at least as it concerns the request message.

Pure Functions

Some may argue this point due to the prevalence of non-conforming web applications that allow side effects on safe, idempotent methods. Nevertheless, HTTP as it is defined specifies that GET and HEAD methods should be safe. This is quite important for other attributes of HTTP, such as the ability to cache representations, which I’ll discuss a bit further down.

First-class and Higher-order Functions

I will acknowledge that this is my weakest point. However, the fact that both the client and server are able to communicate “callable” options appears very close to the very mechanism used when supplying callbacks or continuations in functional programming. It’s close enough for me. You are free to disagree.

Referential Transparency and Memoization

Referential transparency, which is supported by the presence of pure functions (see above), allows us to safely support caching, known as memoization in functional programming. In functional programming languages, memoization allows us to offset the cost of immutability by calling a function once and then re-using the original value rather than continuously invoking the function over and over. It’s especially useful for expensive operations. In much the same way, HTTP provides the ability to cache representations at intermediaries to speed the process of returning a response.

What About Non-Safe-Idempotent and Non-Idempotent Methods?

Very few functional languages are considered pure, Haskell arguably the most popular. F#, OCaml, Lisp, Scala, JavaScript and others all support mutation. Truly, you would be unable to do very much without the ability to change state somewhere. Thus, these other methods are both useful and in no way against the idea that HTTP supports the functional style. Much as even Haskell can eventually persist data in mutable storage such as a database, HTTP supports controlled mutation (albeit without explicit monads; count your blessings).


I think the above arguments support my original idea pretty well, but I’m curious what you think. Also, I certainly am using this as a means of drawing attention to a project I’ve been working and churning on, related to both F# and Web API. In upcoming posts, I’ll introduce Frank, which is finally approaching a fairly stable api.

Here’s another question related to Frank What should…

Here’s another question related to Frank: What should I do about converting existing platforms’ request and response types? I had originally planned on creating my own Request and Response types, but the cost to convert back and forth may or may not be worth it. I either have to create the conversions or a different set of operators per platform.

Functional programming really lends itself to the either, but the latter is a bit more exciting. Why? Take a look at Mauricio’s latest post on Figment. He’s refactored to the Reader monad. Let’s say Frank uses the Reader and Writer monads as a public API for managing web applications. I could then allow developers to use Figment as their implementation on top of ASP.NET and build additional adapters for WebSharper, WCF, OWIN, etc. Frank would then provide a simple, functional, DSL for routing and composing web applications, even using components built on different platforms… which has been the goal all along.

The best benefit, imho, is that developers already familiar with various request/response abstractions can continue using those abstractions. I don’t provide you with yet another HTTP abstraction. This is a significant departure from all other web frameworks of which I know. I suppose the benefit is balanced against the ease of building the adapter using the monad. Time to put functional programming to the test. I am quite certain that functional programming will win.

Functional Programming in C#

For those interested, I found this article and related tutorial from Eric White to be quite fascinating. I went through the tutorial this weekend and thought some of you might also be interested. Eric gives reasons for using functional programming (fp) over conventional object-oriented programming (oop); his most common reason is for performing transformations of data from one sort to another. Other highlights are more in-depth looks at extension methods, Linq and Office Open XML. (While you might wonder why you’d use fp instead of XSLT, the concepts can also apply to transforming objects/collections to other objects/collections using lazy evaluation and deferred execution).