Dec 15 2009

Cross-platform C# REST with MindTouch Dream

Category: ali @ 23:38

.NET asmx webservices were ok, then WCF came along and added a boatload of obscure configuration complexity with a few more features, but the future of webservice architecture seems to be REST (Representational State Transfer).  Amazon, Yahoo, Beanstalk and other public APIs commonly use REST and it is fast becoming the norm.  The only Microsoft-based C# framework that yet facilitates this means of service creation and consumption is based on WCF and is its infancy - see more details on that initiative here - the first beta bits just out a couple of months ago...  However, the developers over at MindTouch have thankfully created a REST service engine and client consumption framework that runs on mono.  Even better, they have exposed their framework, named Dream, as open source.  An overview of its capabilities, in the creator's own words, can be found here.

The first step in leveraging their considerable efforts in making REST easy from C# is getting your Dream server running to host your services.  That first step is the focus of this post.

As explained on the MindTouch Dream community page there are several possible configurations for a Dream server setup.  We are going to focus on IIS6 and IIS7 on Windows but there are options to run the Dream server from the command line, as a Windows service or on mono/Linux among others.

The following will take you through configuration of your Dream server, creation of your first service and verification that your service is working as expected.

  1. Create a new directory on your workstation that will host the Dream source code, right click and execute a subversion checkout (using tortoise svn) from the following location:
    https://svn.mindtouch.com/source/public/dream/
  2. Open <dreamSrcRoot>\trunk\src\MindTouchDream.sln using Visual Studio and build a release version of the code.
  3. Create a directory to be used as the IIS root for Dream services (c:\inetpub\wwwroot\dream if you have a default IIS installation and you use such paths)
  4. Create a directory structure under this newly established <IISDreamRoot> directory as depicted here dreamDirectories
  5. Define a new IIS website to serve port 8081.  This can be any available port but this is the Dream default.  Also, you can just as easily setup a virtual directory off port 80's defined website if you prefer.
    • Be sure to grant execute access to Scripts and Executables.
    • (REQUIRED FOR IIS6 ONLY) Create a wildcard script map by clicking the Configuration button on the Virtual Directory/Home Directory tab of the IIS properties dialog, clicking the Insert button and referencing C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll. As exhibited here, be sure to uncheck the "Verify that file exists" checkbox.
    • wildcardIIS6MapGrant Modify access to the data subdirectory and its children to IUSR_<machinename>, your Internet Guest Account (on IIS7) and NETWORK SERVICE (on IIS6)

  6. Copy and rename the IIS6.web.config file from <dreamSrcRoot>\trunk\src to <IISDreamRoot>\web.config
    *NOTE: For IIS7 (Windows 7/Windows Server 2008) copy and paste the IIS7.web.config file instead.  Also, on 7 place your dream.startup.xml file in your <IISDreamRoot> directory and change your web.config path appropriately.
  7. Create a new XML file using notepad or your XML editor of choice that contains the following.  This will be your Dream server startup script.  Save the file to <IISDreamRoot>\bin\dream.startup.xml 

    <script> 
    <!-- TODO: repeat the following line for each assembly that needs to be explicitly loaded --> 
    <action verb="POST" path="/host/load?name=DreamTestAssembly.EchoSvc" />  
    <!-- TODO: repeat for each service that needs to be started -->  
    <action verb="POST" path="/host/services">    
    <config>      
    <path>echo</path>      
    <sid>sid://sightsource.net/svc/echo</sid>
    <!-- TODO: add custom <config> elements -->
    </config>
    </action>
    </script>

  8. Open the web.config file in Visual Studio and edit the following entries to these values:
    • Set the Dream Server API key (think of this value as the password to your dream server installation)
      <add value="YourNewValueHere" key="apikey" />
    • Set the path to your Dream startup script (no bin subdirectory recommended for IIS7)
      <add key="script" value="bin\dream.startup.xml" />
    • Under the Log4Net settings section
      <file value="data\logs\dream.log" />
  9. Copy the contents of <dreamSrcRoot>\trunk\src\bin to <IISDreamRoot>\bin
  10. Create and publish your first Dream service
    • Open Visual Studio and create a new project of type Class Library, name it DreamTestAssembly
    • Set a reference to MindTouch Dream for your project by browsing to the <IISDreamRoot>\bin\mindtouch.dream.dll file
    • Change the name of the default class to be EchoSvc. Your code should look like the below. **Be sure that the sid value (sid://your/company/url/goes/here/svc/echo) matches EXACTLY to what you entered into the dream startup xml file above.
      using System;
      using MindTouch.Dream;
      using MindTouch.Tasking;
      
      namespace DreamTestAssembly {
          using Yield = System.Collections.Generic.IEnumerator<iyield>;
      
          [DreamService("Echo Service", "Copyright (c) 2010 Sightsource, LLC",
              Info = "http://sightsource.net/svc/catalog/test",
              SID = new string[] { "sid://sightsource.net/svc/echo" })]
          public class EchoSvc : DreamService {
      
              [DreamFeature("GET:{input}", "Simple response feedback test (GET ONLY) (testing installation success)")]
              public Yield Echo(DreamContext context, DreamMessage request, Result<dreammessage> response) {
                  string input = context.GetParam("input");
                  response.Return(DreamMessage.Ok(MimeType.TEXT,
                      String.Format("{0} - length of {1}", input, input.Length)));
                  yield break;
              }
      
              [DreamFeature("POST:{input}", "Simple response feedback test (POST ONLY) (testing installation success)")]
              public Yield TestPost(DreamContext context, DreamMessage request, Result<dreammessage> response) {
                  string input = context.GetParam("input");
                  response.Return(DreamMessage.Ok(MimeType.TEXT,
                      String.Format("POSTED DATA=[{0}] - length of {1}", input, input.Length)));
                  yield break;
              }
          }
      }
    • Copy your newly minted assembly dll from your Visual Studio /bin/release directory to <IISDreamRoot>\bin\services (it should be named DreamTestAssembly.dll)
  11. Open a browser and navigate to the following url, making use of your paste command.  You should receive an list of the known services (4 services should be running, the last being Echo).
    http://localhost:8081/host/services?apikey=YOURAPIKEYHERE
    *NOTE: If you setup a virtual directory rather than a website service listening on port 8081 your url should look more like the following:
    http://localhost/dream/host/services?apikey=YOURAPIKEYHERE
  12. Test your service. It will be accessible through the following URL for a GET (if you have configured a website on port 8081), followed by any parameter patterns you choose.
    http://localhost:8081/echo/test
    You should receive test - length of 4 as your successful response.

The good news is that all that must be done to add to your service repertoire from now on is a simple add to the configuration entries in the dream.startup.xml file appropriate to your additional service sid and to copy the relevant assemblies into the services subdirectory.

Get additional details regarding alternative setups directly from the official MindTouch dream page.  It also offers a couple of additional tutorials to try out on your new installation.

Since Microsoft does have REST support on the way you may be conflicted.  Should you go Dream or WCF REST?

Two reasons have led us to go with Dream.  It runs on Mono so isn't tied to Windows and it's been around for a couple of years, not a couple of months so it should be more mature, at this point at least, than the new shim on top of WCF.

Happy Coding!

Tags:

Comments

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading