The simplest Owin AppFunc that works

When learning new frameworks and libraries I always like to find the simplest thing that works.  It helps me to separate in my mind what is core and what is helper stuff.  When it comes to debugging it is always nice to be able to strip away the helper stuff.

No frameworks allowed!

hammer While working on my OwinServiceHost (blog post in progress!) I needed to have a sample OWIN application that I could test with.  I could have pulled in one of the compatible frameworks like WebAPI, Nancy, Simple.Web, or Katana to create a minimal web application, but I was curious if I could create an OWIN application with just .net framework classes.  I know I should be able to because one of the mantras of the OWIN specification is to avoid taking dependencies on anything that is not part of the .net framework.

What does an OWIN application look like

In order to create an OWIN application you need to create a function that is compatible with this,

Func<IDictionary<string, object>, Task>

So, that’s a function that accepts a dictionary of objects, keyed by a string, and it returns a task.  This signature is what the OWIN people call the AppFunc, and the dictionary is called the OWIN environment.  The dictionary contains information passed from the HTTP Server down to the HTTP application and provides everything that is necessary to process the request.  The dictionary keys and what the array should contain is defined by the OWIN specification

The naked truth

And now for the simplest (I didn’t say easiest) OWIN compatible application that actually works.

(env) => {
    var sw = new StreamWriter((Stream) env["owin.ResponseBody"]);
    var headers = (IDictionary<string, string[]>)env["owin.ResponseHeaders"];
    var content = "Hello World";
    headers["Content-Length"] = new string[] {content.Length.ToString()};
    headers["Content-Type"] = new string[] {"text/plain"};
    var task =  sw.WriteAsync(content);
    sw.Flush();
               
    return task;

}

In order to return a response, we need access to the response body stream, which we is stored in the dictionary using the owin.ResponseBody key. At minimum we need to set the Content-Length header and I also set the Content-Type header so that a browser will happily render the result.

So what do I do with that

Having an AppFunc without an OWIN compatible host is fairly useless.  Bear with me, I am currently in the middle of writing a post on how to host and deploy these kind of HTTP applications in as easy as possible way.  Watch this space!

Image credit:  Hammer https://flic.kr/p/da8dLo

No Comments

Add a Comment

comments powered by Disqus