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 fpish.net 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.

Advertisements

A New Web for .NET: FubuMVC and Chad’s Response to AR Considered Harmful

I caught a few interesting posts this week that reminded me of an unfinished series on .NET web frameworks I started in 2009. The series, as it was initially planned, ties in very well with a recent post from Chad Myers, who responded to another post claiming the ActiveRecord (and Rails) Considered Harmful.

Before I go any further, I want to make very clear that I’m a fan of Rails and think that it is an incredibly useful framework for building certain applications. I think the same is true of ASP.NET MVC. I’ve used and use both. However, I don’t think that means these are the best approach for tackling HTTP.

Chad’s post was very good. I agree with almost all of his points. In particular, I think he hit several very important points, the biggest of which was his emphatic quote:

INHERITANCE IS FAIL FOR MOST DESIGNS, BUT NEVER MORE SO THAN IN WEB/MVC FRAMEWORKS!

Then from his list of criteria for a “perfect” web framework:

  • Completely compositional: 100% agree
  • [Resource]-based: I take a slightly different direction here. We talk about “models”, but if you are really thinking about HTTP, you should be thinking in terms of resources. They are similar in many ways, notably in the sorts of “behaviors” (in FubuMVC terms) that should be composed with the “model.” Honestly, it’s the “model” term itself that seems totally overloaded or at least at the wrong layer when talking about a framework. If you have a model, you’re probably really dealing with something more like DDD than the HTTP application layer.
  • Not have any notion of controllers: Agree. In MVC-style frameworks, they are sort of necessary, but if you break away from MVC, you’ll find there are better alternatives.
  • Action-based: I’m all about using functions, or delegates, as 'Request -> 'Response handlers. I also agree that these should generally be kept simple, relying on compositional helpers, middlewares, or whatever you want to call them to perform model-binding and response generation. Granted, this is slightly different than what Chad is talking about, and I’ll cover my thoughts on this in more detail below.
  • Minimized code-in-view: templates are helpful, but the ability to add a lot of logic is just asking for trouble. I really like the tags-as-code approach taken by WebSharper and Wing Beats.
  • Independent of other frameworks: Definitely limit other dependencies and play nice with others.
  • Testing as a first-class citizen: At least allow whatever the consumer writes to easily write real unit tests. Generally, the only reason you can’t do this is related to hosting, so make sure the hosting model is not necessary to test the application.

Okay, so I obviously skipped some items. I don’t think the other items are bad; I just don’t think they are necessary for a “perfect” web framework.

  • Total adherence to principles: This sounds really good. I don’t disagree, really, but exactly which principles? Principles sometimes change. Some make sense in one approach to software development and are sort of non-issues in others. Look at the description of SOLID and its relevance to F#. You’ll note that many of the principles are sort of non-issues.
  • Statically typed: I don’t really see this as a requirement. HTTP is inherently dynamic. You could build a useful, fairly complex HTTP application using only dictionaries. Reliance upon type serialization is misguided. How do you generate accurate Atom or HTML from a static type? You don’t. You need a template or some other custom output. At the same time, I have grown to like static type-checking, espeically in F#, and F# 3.0’s Type Providers prove you can do a lot, even type check regular expressions. I just don’t see this as a strict requirement.
  • Based on IoC: I love IoC in C# applications. I can’t imagine life without it. However, I’ve found that I don’t even think about IoC when writing F# applications. It’s just not a concern. Higher-order functions, computation expressions, and other functional-style approaches generally render IoC a non-issue. So again, I don’t really see this as a requirement but a case of “use the right tool for the job.”
  • Mostly model-based conventional routing: This is a totally fine solution. I take issue with having any single prescription for routing. There are so many ways to handle this, and in the end it doesn’t matter. If you stick to a resource-oriented approach, which perhaps is the goal Chad is getting at, then your routing should be pretty straightforward and simple. One thing many routers miss is the connection between different methods assigned to a single uri. So far as I know, OpenRasta and Web Api are the only frameworks that return the appropriate HTTP status codes for missing methods on an uri or unmatched Accept header, among other things. FubuMVC may allow this through a convention.
  • One Model In, One Model Out: When using MVC, I generally like this approach. However, I again don’t see this as a requirement. I’m not convinced a model is always necessary. Again, HTTP is quite dynamic, and it’s sometimes easier to work directly with a request or pull out several different “objects” from a request to help generate a response. Though perhaps 'Request and 'Response are models and the point is moot. 🙂

Now for the biggest divergence: I generally prefer to be explicit rather than lean on conventions. In C#, I typically go for conventions because of the amount of noise required by the C# syntax. With F#, I’m able to be explicit without suffering syntax noise overload. The same is true for many dyanmic languages like Ruby and Python. So I disagree with both the Conventional top-to-bottom and Zero touch points. Again, I’m not fully opposed, but I definitely don’t see these as requirements at the framework level. Sure, include it as an option, especially if, as in FubuMVC, you can redefine the conventions to suit your needs. This could just mean use the right tool for the job, or it could mean you should take a simpler approach and build your own conventions as wrapper functions.

If you think this sounds like a prescription to write a lot more code, I’ll show a comparison:

Two extra lines (in this instance) and it’s likely with a more complex example you wouldn’t see much of a difference in terms of line count. I doubt this is true with C#, so don’t take this as a statement that this is the “one, true way.” I like conventions when using C#, just as I like IoC in C#.

In any case, definitely check out FubuMVC as an alternative to MVC. There’s a lot to like, and the FubuMVC team has done an incredible job building a terrific platform. I’ll try to highlight a few others in the upcoming weeks, but while you’re looking at Fubu, also checkout OpenRasta and ServiceStack.

A New Web for .NET: FubuMVC and Chad's Response to AR Considered Harmful

I caught a few interesting posts this week that reminded me of an unfinished series on .NET web frameworks I started in 2009. The series, as it was initially planned, ties in very well with a recent post from Chad Myers, who responded to another post claiming the ActiveRecord (and Rails) Considered Harmful.

Before I go any further, I want to make very clear that I’m a fan of Rails and think that it is an incredibly useful framework for building certain applications. I think the same is true of ASP.NET MVC. I’ve used and use both. However, I don’t think that means these are the best approach for tackling HTTP.

Chad’s post was very good. I agree with almost all of his points. In particular, I think he hit several very important points, the biggest of which was his emphatic quote:

INHERITANCE IS FAIL FOR MOST DESIGNS, BUT NEVER MORE SO THAN IN WEB/MVC FRAMEWORKS!

Then from his list of criteria for a “perfect” web framework:

  • Completely compositional: 100% agree
  • [Resource]-based: I take a slightly different direction here. We talk about “models”, but if you are really thinking about HTTP, you should be thinking in terms of resources. They are similar in many ways, notably in the sorts of “behaviors” (in FubuMVC terms) that should be composed with the “model.” Honestly, it’s the “model” term itself that seems totally overloaded or at least at the wrong layer when talking about a framework. If you have a model, you’re probably really dealing with something more like DDD than the HTTP application layer.
  • Not have any notion of controllers: Agree. In MVC-style frameworks, they are sort of necessary, but if you break away from MVC, you’ll find there are better alternatives.
  • Action-based: I’m all about using functions, or delegates, as 'Request -> 'Response handlers. I also agree that these should generally be kept simple, relying on compositional helpers, middlewares, or whatever you want to call them to perform model-binding and response generation. Granted, this is slightly different than what Chad is talking about, and I’ll cover my thoughts on this in more detail below.
  • Minimized code-in-view: templates are helpful, but the ability to add a lot of logic is just asking for trouble. I really like the tags-as-code approach taken by WebSharper and Wing Beats.
  • Independent of other frameworks: Definitely limit other dependencies and play nice with others.
  • Testing as a first-class citizen: At least allow whatever the consumer writes to easily write real unit tests. Generally, the only reason you can’t do this is related to hosting, so make sure the hosting model is not necessary to test the application.

Okay, so I obviously skipped some items. I don’t think the other items are bad; I just don’t think they are necessary for a “perfect” web framework.

  • Total adherence to principles: This sounds really good. I don’t disagree, really, but exactly which principles? Principles sometimes change. Some make sense in one approach to software development and are sort of non-issues in others. Look at the description of SOLID and its relevance to F#. You’ll note that many of the principles are sort of non-issues.
  • Statically typed: I don’t really see this as a requirement. HTTP is inherently dynamic. You could build a useful, fairly complex HTTP application using only dictionaries. Reliance upon type serialization is misguided. How do you generate accurate Atom or HTML from a static type? You don’t. You need a template or some other custom output. At the same time, I have grown to like static type-checking, espeically in F#, and F# 3.0’s Type Providers prove you can do a lot, even type check regular expressions. I just don’t see this as a strict requirement.
  • Based on IoC: I love IoC in C# applications. I can’t imagine life without it. However, I’ve found that I don’t even think about IoC when writing F# applications. It’s just not a concern. Higher-order functions, computation expressions, and other functional-style approaches generally render IoC a non-issue. So again, I don’t really see this as a requirement but a case of “use the right tool for the job.”
  • Mostly model-based conventional routing: This is a totally fine solution. I take issue with having any single prescription for routing. There are so many ways to handle this, and in the end it doesn’t matter. If you stick to a resource-oriented approach, which perhaps is the goal Chad is getting at, then your routing should be pretty straightforward and simple. One thing many routers miss is the connection between different methods assigned to a single uri. So far as I know, OpenRasta and Web Api are the only frameworks that return the appropriate HTTP status codes for missing methods on an uri or unmatched Accept header, among other things. FubuMVC may allow this through a convention.
  • One Model In, One Model Out: When using MVC, I generally like this approach. However, I again don’t see this as a requirement. I’m not convinced a model is always necessary. Again, HTTP is quite dynamic, and it’s sometimes easier to work directly with a request or pull out several different “objects” from a request to help generate a response. Though perhaps 'Request and 'Response are models and the point is moot. 🙂

Now for the biggest divergence: I generally prefer to be explicit rather than lean on conventions. In C#, I typically go for conventions because of the amount of noise required by the C# syntax. With F#, I’m able to be explicit without suffering syntax noise overload. The same is true for many dyanmic languages like Ruby and Python. So I disagree with both the Conventional top-to-bottom and Zero touch points. Again, I’m not fully opposed, but I definitely don’t see these as requirements at the framework level. Sure, include it as an option, especially if, as in FubuMVC, you can redefine the conventions to suit your needs. This could just mean use the right tool for the job, or it could mean you should take a simpler approach and build your own conventions as wrapper functions.

If you think this sounds like a prescription to write a lot more code, I’ll show a comparison:

Two extra lines (in this instance) and it’s likely with a more complex example you wouldn’t see much of a difference in terms of line count. I doubt this is true with C#, so don’t take this as a statement that this is the “one, true way.” I like conventions when using C#, just as I like IoC in C#.

In any case, definitely check out FubuMVC as an alternative to MVC. There’s a lot to like, and the FubuMVC team has done an incredible job building a terrific platform. I’ll try to highlight a few others in the upcoming weeks, but while you’re looking at Fubu, also checkout OpenRasta and ServiceStack.

Tutorial D in F#

Does anyone know of a project to implement Tutorial D in F#, similar to the Dee project for Python? I’m currently trying to get Dee working on IronPython, which would get me closer to my goal of using a true relational model for data access. I would like to stick with a .NET implementation, so that leaves out Rel. I have tried Dataphor, but I find it trying to be too much a complete platform and not easy to use as just a utility. I think either a good C# or F# implementation would be both excellent to have and a fun project on which to work. Anyone interested?

Anders Hejlsberg on the Future of C# (PDC 2008)

In case you are missing PDC like me, you can find some great videos of the sessions on Channel 9. I found Anders’ comments on the future of C# to be incredibly exciting. You can watch it here. I’d love to hear feedback on whether you to are excited about the new features he points out for C# 4.0:

  • Dynamically Typed Objects
  • Optional and Named Parameters
  • Improved COM Interoperability
  • Co- and Contra-variance

Update: You can now download and try out the CTP for Visual Studio 2010 and the .NET Framework 4.0 from Microsoft Connect!