Friday, July 22, 2011

Functional Patterns in our Everyday Code

Modern Programming
During the advent of modern programming, which I think of as post 2005 code base, we have received many enhancements to our programming toolsets.  Much ado has been made about these enhancements, often these are the frameworks that Web 2.0 has been built on.
The modern programming tools are very aware of the upcoming Mobile Application Flood,  but they also own a considerable amount to older programming techniques first developed in LISP as early back as the 1960's.  Python popularized much of the functional programming style, and was incorporated into ECMAScript. 

Functional Programming
Javascript and its adopted parent ECMAScript were developed with functional capabilities from the very beginning. Methods in JavaScript are first class and can be passed as around as arguments. Consider the following Native Javascript Code:


<script language="ecmascript" type="text/ecmascript">
    Array.prototype.AlertOnce = function () { alert('A') };
    [1, 2, 3].AlertOnce();
script>


The script applies an anonymous function to the array object as an extension method, via the prototype pattern.

In the script below, the anonymous function iterates the array, and runs once per primary object occurrence in the array.


<script language="ecmascript" type="text/ecmascript">
    var IEnum = [1, 2, 3];
    IEnum.forEach(function (ele, i) {
        alert(i + ':' + ele)
    });
script>


Contrasted with the JQuery Method, below. The methods are almost identical.


<script language="ecmascript" type="text/ecmascript">
    var IEnum = [1, 2, 3];
    $(IEnum).each(function (i, ele) {
        alert(i + ':' + ele)
    });
script>


As compared to a Lambda expression in VB.Net


Dim IEnum = New List(Of Integer)(New Integer() {1, 2, 3})
IEnum.ForEach(Function(i) System.Diagnostics.Debug.Print( i ) )

or in C#

List<int> IEnum = new List<int>(new int[] { 1, 2, 3 });
IEnum.ForEach(i => i.ToString());


These scripts demonstrate multiple ideas. To wit, JavaScript natively supports the sort of iterating across collections pattern that we usually think of JQuery for. And .net now supports a wide set of functional programming, this now includes anonymous methods, JavaScript like prototyping via extension methods (and on those extension methods, even method chaining).

Conclusion:
Instead of thinking about JQuery, or .Net extension methods, we should be seeing these new pieces as functional programming patterns and getting used to thinking in terms of delegates, callbacks and prototypes.

Monday, July 11, 2011

Rest Service Implementation


WCF Rest-like Service
Proto-type implementation

Vocabulary

Representational State Transfer:  Low level stateless software architecture approach that uses the structure of URI's (uniform resource locator) and HTTP 1.0 verbs to define resultant service data displays. REST outlines how to define, access and address data sources without the need for additional messaging layers or session tracking.
Windows Communication Foundation: WCF is a platform that supports a multitude of different methods to expose data services, in a service-oriented methodology. It is request agnostic, meaning it is not tied to a single request method like REST, or SOAP.
Http Client: Object to initiate a Http Request, previously known as XHR or XMLHttpRequest. This safe for scripting object was used to initiate AJAX calls.

Document

This document is meant to detail the top level technological decisions that were made in the proto-type WCF Rest-like Service implementation. This document, based on proto-type implementation is meant to postulate possible guidelines, as such this document will remain in draft format in perpetuity, and will be superseded by any and all Guidance Documents or White Pages on the technologies in this document.

References - Prerequisites

      WCF Rest Service Template 4.0 for Visual Basic
      WCF Rest Starter Kit (http client)
      Visual Studios 2010, .Net Framework 4.0
      IIS 7.0

Http Verbs

It seems appropriate to start any discussion of restful(like) solutions with a conversation about HTTP Request Methods. These are often referred to as "verbs."  Most of us are familiar with "Get" and "Post" but have failed up to now to notice the other request methods that the http protocol supports. For now, let it be sufficient (until we begin our discussion on routing masks) to say that restful services respond to not only the URI of a request, but also route based on the action that is described via the Request Method. WCF commonly responds to GET, POST, PUT and DELETE for crud operations, there are more Verbs in the HTTP Protocol Specification, but they are not in common usage in Restful services.

Routes

Guideline: Configure your routes in the virtual route table, accessed in code in the Global.asax file in a custom Procedure called RegisterRoutes.  This behavior is similar to the routing mechanism employed by MVC.Net web sites.
fig. 1

Private Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
  RegisterRoutes()
End Sub

Private Sub RegisterRoutes()
  RouteTable.Routes.Add(New ServiceRoute("RouteName", New WebServiceHostFactory(), GetType(MyApplication.MyClass)))
End Sub


Application Start

Creating a response to a request in a virtual location (there is no physical file to respond to the request), means that a listener will have to be created.  WCF supplies a factory method to create this listener, with the WebServiceHostFactory class. This factory class should be called at application start,  and added as a Route to the application's RouteTable object.
fig. 2

RouteTable.Routes.Add(New ServiceRoute("RouteName", New WebServiceHostFactory(), GetType(MyApplication.MyClass)))


Routing

Incoming request are passed from IIS to the WebServiceHostFactory, where they are routed according to the RouteTable rules into the class specified in the Routes.Add type argument. The request is then picked up by the Class, and is handled by a method of the class based on the "verbs" and the arguments specified by the request.

 

Route Masks, (HTTP Method and UriTemplates)

The WCF Rest Template offers Common Routing, and templates for the most common scenerios. These are mostly self defining, based on the HTTP method, and also the existance of an id or name argument. It is worth noting, that all arguments passed via a URI will be of type string.
fig. 3

      <WebGet(UriTemplate := "")>
        Public Function GetCollection() As List(Of SampleItem)
            Throw New NotImplementedException()
        End Function
       
        <WebInvoke(UriTemplate := "", Method := "POST")>
        Public Function Create(ByVal instance As SampleItem) As SampleItem
            Throw New NotImplementedException()
        End Function
       
        <WebGet(UriTemplate := "{id}")>
        Public Function [Get](ByVal id As String) As SampleItem
            Throw New NotImplementedException()
        End Function
       
        <WebInvoke(UriTemplate := "{id}", Method := "PUT")>
        Public Function Update(ByVal id As String, ByVal instance As SampleItem) As SampleItem
            Throw New NotImplementedException()
        End Function
       
        <WebInvoke(UriTemplate := "{id}", Method := "DELETE")>
        Public Sub Delete(ByVal id As String)
            Throw New NotImplementedException()
        End Sub

 
Restful services have some common practices, which govern there usage, and these should be adhered to as long as they do not create odiously architected solutions. There is an expectation that reaching the root a Restful Object (in a URL Get), that object will return an unfiltered list of objects of that type.  When an "id" or "name" is specified in a Get on a Restful Object then the expectation is that the Restful Service will return a single instance of the item in question.  Using the HTTP Method, "Delete" means that the requesting caller would like to see that item removed from the underling persistence store.  This is clear, but the Delete could be requested using either a "id" as in "please remove the item with this id from the persistence store" or the object could be sent in a http form, meaning "please remove the item in the persistence store that resembles this item." The Put and Post methods have similar problems, as the user community is not 100% decided on a usage for these items. For the purposes of our discussion, we will assume that POST is equal to a form post in which the requestor desires that we insert the item into the persistence store, and that a PUT is when the requestor desires us to perform an update on an item in the persistence store.

            A Note of Caution: It is incumbent on me to offer a note of caution on POST and PUT, the   Restful service creator should handle PUTs in POSTs and POSTs in PUTs, or send back an    explanation on why the desired result was not achieved.


Complex Routes

Routes that specify multiple filtering items at different levels of the Restful Portion of the Resource Locator, are complex routes.

Complex routes need to be specified on the top hierarchical level. For instance, there is a parent-child relationship and the service should list a collection of children, filtered by the parent id, then the handler method will be created on the parent level.

fig. 4

      <WebGet(UriTemplate := "{id}/Child")>
        Public Function GetChildCollection() As List(Of SampleItem)
            Throw New NotImplementedException()
        End Function
       

Introducing the HtHttpClient

The WCF Rest starter kit comes with a new and improved HttpClient Utility. This new client, like the old XMLHttpRequest Utility allows a thread to programmatically access the web resources without the overhead of a user-interface. The new HttpClient is a major update of functionality, since the XHR methodologies of early 2000 contained no support for Http Request Methods beyond GET and POST and also were not concerned about serialization. Modern Service Architectures have significant enhancements to serialization and do not stop at POX (Plain Old XML, simply returning a document of XML data). The WCF service and the HttpClient come together in serialization of strongly typed data, you may expose your data from the WCF as "exact type" and consume it in your interface as the same "exact type" that you exposed it as. This methodology means that a WSDL data contract is not only unnecessary, but also undesirable, in so far as the WSDL creates a new type that the client consumes.
Additionally the new HttpClient has built in support for "DELETE" and "PUT" Http Verbs, as well as the more common, "GET" and "POST" of XHR.

Usage

The HttpClient is located in the Microsoft.Http.dll, which is included in the WCF Rest Starter Kit. Adding Headers is simple in the
 fig. 5

        Using client As New HttpClient("http://localhost:8080/Route/")
            Using response As HttpResponseMessage = client.[Get]("Action?id=3")
                response.EnsureStatusIsSuccessful()
                Dim anon = response.Content.ReadAsDataContract(Of List(Of ContractLibrary.Interfaces.IItem))()
            End Using
        End Using


Custom Headers

Adding Headers is simple in the HttpClient. Access the DefaultHeaders Collection of your instantiated client and then call the Add method.
fig. 6

        client.DefaultHeaders.Add("CustomHeader", HeaderValue)


Security/Authentication

The Restful service site is secured through the usual Microsoft Web Security Provider, and needs no configuration beyond what is usually contained in a .net web site. Accessing the resources in a secure manner usually means that you will be sending a set of credentials (as system.net.icredentials) in the Http Request of the HttpClient Utility.
fig. 7

        client.TransportSettings.Credentials = Credentials


Configuration

The options specified in the web.config file of the Rest service are fairly straight forward.  Though please note the last WCF section, and in particular the attribute HelpEnabled, which automatically creates an operation description page for each route when the route action is "/help."

Authentication:

    <roleManager defaultProvider=".." enabled="true">
      <providers>
        <add name=".." connectionStringName=".." applicationName=".." type="System.Web.Security.SqlRoleProvider, .."/>
      providers>
    roleManager>
    <authorization>
      <deny users="?" />
    authorization>

Routing :

    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    modules>

WCF:

  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
     
    serviceHostingEnvironment>
    <standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      webHttpEndpoint>
    standardEndpoints>
  system.serviceModel>