Revisiting Microsoft Forms: WebForms

This is the first of several reflections on Microsoft’s original forms solutions for .NET. In this post, I want to look back at ASP.NET WebForms, or more specifically System.Web and the Page life cycle. In hindsight, I think there were some really good ideas that were just hard to understand clearly given the dominance of OO, TDD, and DDD that were at the rising to the height of popularity while WebForms was the primary ASP.NET solution.

Continue reading
Advertisement

Immutable PUTs and Web Linking

This past Friday, Michael Perry of Improving presented on ACID 2.0, where the acronym stands for Associative, Commutative, Idempotent, and Distributed rather than Atomic, Consistent, Isolated, and Durable. I enjoyed the presentation and Michael’s use of an HTTP API to simplify the discussion rather than bring in topics like CRDTs, which easily could have confused things further. I confirmed he has those ideas in mind both through the Q&A discussion and by means of the website for his upcoming book on The Art of Immutable Architecture. This got me thinking about how I would go about supporting immutable HTTP PUT requests in an API.

Continue reading

Yet Another F# Web Framework

Update Jan 1, 2019

I spent some time splitting the projects and updating to ASP.NET Core 3.0 alpha (preview targets netcoreapp3.0 only). The Endpoint Routing feature is really, really nice. You can see the updated version here (diff).

Original Post

While evaluating the state of F# web frameworks over the holidays, I managed to create yet another lightweight framework prototype. You’re welcome. The prototype is based on ASP.NET Core Routing and some posts by Filip Wojcieszyn, specifically Building microservices with ASP.NET Core (without MVC) and Running ASP.NET Core content negotiation by hand. The prototype currently consists of a ContentNegotiation module and a Builder module containing a RouterBuilder and a ResourceBuilder, where the two builder types are computation expressions using CustomOperationAttributes.

let helloName =
    resource app.ApplicationServices "hello/{name}" {
        name "Hello Name"

        get (fun ctx ->
            let name = ctx.GetRouteValue("name") |> string
            ctx.Response.WriteAsync(sprintf "Hi, %s!" name))

        put (fun ctx ->
            let name = ctx.GetRouteValue("name") |> string
            ContentNegotiation.negotiate 201 name ctx)
    }
Continue reading

Server MVC and Solving the Wrong Problem

TL;DR MVC frameworks provide infrastructure to solve make believe problems. They complicate what should be simple.

Update (Feb 4, 2016): While writing this post focused on server-side MVC, I came across a somewhat related post, Why I No Longer Use MVC Frameworks, discussing problems with MVC on the client-side. It follows a slightly different direction and is well worth your time.

Continue reading

New Names for Old Things

[This is the third in a series started long ago on the use of MVC for building web “applications”.]

I’m glad I’m only getting back to this series now. I’ve had an opportunity to build many more web applications and have a much better appreciation for the poor terminology used to define web applications. For starters, this MV? business silly. We’ll get to that.

I know I’m a bit of an extremist in some things. Specifically, I like things to mean what they mean. When we abuse terms, we don’t communicate well. REST. There, I said it. I feel better. Stop using the term. Most people have a wrong idea of what it means b/c of all the silliness that has been done in its name. I don’t claim to know exactly myself. I don’t think it’s possible to rescue the term from the abuses heaped upon it. There, you see? I’m an extremist.

Now that we’ve covered that, on to MVC. I’m not sure who decided this was an accurate description for what happens on the server-side of the web, but it’s just flat wrong. As noted previously, HTTP uses a functional interface. It’s an IO-bound Request -> Response function. Can you use patterns on either side to help maintainability? Certainly! Just don’t confuse things. Let’s start with Views.

Views

What is a view?

The [view or viewport] is responsible for mapping graphics onto a device.
A viewport typically has a one to one correspondence with a display surface
and knows how to render to it. A viewport attaches to a model and renders
its contents to the display surface. In addition, when the model changes,
the viewport automatically redraws the affected part of the image to reflect
those changes. […] there can be multiple viewports onto the same model and
each of these viewports can render the contents of the model to a different
display surface.

If a view was merely a serialization of a model, this would make sense for building web applications. Unfortunately, there’s a problem. The definition suggests that the view automatically updates whenever the model changes. How do you do that with HTTP? HTTP doesn’t define any mechanism for hooking up observation of a server model. Before you say JavaScript, consider first the current use of View, or even UI. People commonly mean HTML. HTML is not a UI. HTML is a serialization format. The client (normally a browser) must interpret that HTML. Many of you will remember when that wasn’t so standard.

Can we achieve MVC today? Possibly. You might be able to leverage web sockets to reach across a client/server architecture such as that presented by HTTP. However, you are more likely to find that “MVC” on the server is just limiting. You are typically better off building a sort of restricted data access service, a.k.a Web API (subtle hint). There’s really no point in trying to enrich a serialization format to make it work more like true MVC across the client and server.

Controllers

This is no different than routing. Instead of calling your Router a Controller, you split them up. However, most frameworks really just use the router as a top level dispatcher and the controller as a lower-level dispatcher. Otherwise, I’d say web frameworks stay a lot closer to the original meaning than a lot of the other MV? patterns. (Hence the ?, of course.)

Models

This really is the crux. HTML is a model. I noted this last time. It’s just a serialization of data you want displayed. It happens to be a lot richer, but it’s still just a data model. HTML is a great way to bootstrap an application that otherwise uses JavaScript as a model serialization format. If you want to disagree, ask why HTML5 removes the presentation elements. Why has layout and style moved to CSS? CSS and the browser define the actual rendering. In a no-script web application, you don’t have to build a view. You get it for free.

Conclusion

So what? Am I just ranting that I don’t like how people abuse terms? Possibly. However, I think this goes deeper. When you allow the slippery slope, you get caught on it, as well. It’s inevitable. The bigger, lurking danger is that we start to confuse useful patterns and use them in the wrong places. Many people use MVC frameworks today to build web APIs. However, that’s not MVC. So if you then switch to a desktop app to write MVC applications, you are either confused or delighted to find that it’s so much richer.

I don’t know what I would call what we build for the web; I know I wouldn’t call it MVC. In my experiments with Frank, I’ve found that writing simple functions and nesting them with rules makes a very easy mechanism for building web APIs. I think that would essentially just be a Command pattern. Simple, elegant, and very easy to understand. YMMV.

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.

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.

Summary

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

Discussion

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).

Conclusion

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.

Web Architecture Done Right

I’ll go ahead and confess that a single right way to design for the web doesn’t exist. If someone wants you to believe otherwise, they are just wrong. That said, I do think that you’ll have a hard time going wrong by starting with one simple rule: start with a web api.

Why should you start with a web api rather than just building a web site/app that has HTML and JavaScript all working together? Frankly it’s because you can’t properly decouple the api from the serialization format well enough. When you are designing an api for the web, you (should be) thinking in terms of resources and representations. That’s representations in the plural form. You may not know exactly what forms you’ll need, but you should consider that you will eventually have many. When you start with a web site/app with HTML in mind, you’ve coupled yourself to a single format, and extracting that out later could (will) be difficult. Don’t just take my word for it. Mike Amundsen has an excellent post on the right way to think about these things.

There are certainly some instances where this may be overkill, but I hate rewriting software unless it really is a prototype or just an exploratory attempt to get something up. In those cases, go for the quick and dirty. If you are working on something you want to last a long time, however, you owe it to yourself to consider the evolvability of your app by focusing on api design. You’ll then be able to take advantage of a number of client options. Certainly, supporting the growing number of clients is one of the biggest challenges continuing to face developers as we head into 2012.

Let’s suppose you agree with me on this point. How do you go about building a really solid api design? I don’t think I could articulate it better than Darrel Miller already has. His goals for good apis are suitable both for internal teams and external customers. Who wouldn’t love gaining visibility b/c a customer was able to accelerate their business by using your api in an unforeseen way that drives additional business for your own company? How nice is it to knock out not just one project but several b/c you are able to leverage existing platforms for new projects? We’re doing that at Logos, in large part because we moved to MVC and took a more service-oriented approach to building our apps. The number of new projects has grown tremendously, but we are also able to respond much more quickly b/c the services are ready for consumption.

I’ll be continuing to discuss this topic in future posts. In the meantime, check out Mike’s book,
Building Hypermedia APIs with HTML5 and Node. It uses HTML5 and Node to illustrate, but the concepts are excellent and portable to other platforms. I also highly recommend REST in Practice as an excellent resource for understanding the fullness of what HTTP offers for building apis. Enjoy!