Telligenti

Serving up fresh ideas every day, Telligent style
Welcome to Telligenti Sign in | Join | Help
in Search

Jayme Davis

I will think of something for here later

April 2008 - Posts

  • RestLess - A Simple REST Framework Part 2

    Some cool changes have come along for RestLess. Instead of blabbering on, I'll dive right into the changes.

    Small naming changes

    Based on Dave Donaldson's recommendation, IRESTReadable, RESTProperty, etc have their case changed. They are now IRestReadable, RestProperty, etc. Just do a rename all on REST to Rest if you already have implemented the framework.

    No More Default.aspx, pretty urls!

    A problem with the first version, was default.aspx was specified in the Url. This is ugly and not very RESTful. There is a new key you can add to web.config appSettings:

    <add key="RestLess::GeneratePlaceholderDirs" value="true" />

    When this value is set to true, RestLess will generate placeholder folders with an empty default.aspx document. This way you can specify the url as http://mysite.com/api/products/ (notice no default.aspx). Your web application directory will look something like below:

    IRestWritable

    IRestReadable, in the first version, allowed you to send an xml document down to a user submitting a GET request at the resource url. IRestWritable exposes one method void GetRestPostedObject(object obj). When a POST is submitted to the url/resource, this method will be called. The best thing about GetPostedObject(object obj) is that it will populate the object from querystring for you based on your RestProperty's. If the attribute is specified as IOType.Input or IOType.InputOutput, RestLess will look in the url for you to see if these values were passed by the user, then send you a populated object.

    For example (copied the example object from the first version for clarity, new additions in orange)

        // decorate the class as a RestResource, the first parameter is the url of the resource appended to
        // the root url (defined in web.config). In this case /api/products/
        // the second parameter specifies if this resource is discoverable (more on this later)
       
    [RestResource("products", true)]
        public class Product : IRestReadable, IRestWritable
        {
            private string _name;
            private string _description;
            private double _amount;

            // render this property as xmlelement "productname"
            // IOType.InputOutput specifies that this property will be rendered
            // to the outputted xml, and can also be inputted via querystring
           
    [RestProperty("productname", IOType.InputOutput)]
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }

            // render this property as xmlelement "productdescription"
            // IOType.Output specifies this property is rendered to the user,
            // but it is not allowed in querystring for input
           
    [RestProperty("productdescription", IOType.Output)]
            public string Description
            {
                get { return _description; }
                set { _description = value; }
            }

            // render this property as xmlelement "amount" (output only again)
           
    [RestProperty("amount", IOType.InputOutput)
            public object GetRESTObject()
            {

                // this is where you could go access your data access layer or whatever other method you choose.
                // this is also where you could request an API key via querystring for security etc
                // since productname is specified inputoutput, you should check for
                // Request.QueryString["productname"] to get any data the user sends

                // for the purposes of this demo, lets just make an object and pass it back
                Product p = new Product();
                p.Name = "Super Fly Ink Pen";
                p.Description = "This is the most super fly ink pen ever";
                p.Amount = 10.00;

                return p;
            }

            #endregion

            #region IRestWritable Members

            public void GetRestPostedObject(object obj)
            {
                Product product = obj as Product;

                // product will be populated here based on anything provided in QueryString, you do not
                // need to retrieve it manually. for example, if the POSTed url is
                // http://mysite.com/api/products/?productname=InkPen&amount=2.50

                product.Name // will equal InkPen
                product.Amount // will equal 2.50
            }
          
            #endregion

        }

    Right now, IRestWritable only supports getting values from querystring. That will change later to support xml documents being posted, etc.

    Grab the new dll here. (as of now, the plan is to open-source the framework when it's a little further along)

    Enjoy!

    Jayme

    Posted Apr 23 2008, 11:20 PM by ndepth.net
    Filed under:
  • RestLess - A Simple REST Framework

    I have been disappointed with the amount of legwork involved with setting up a simple REST API, so I decided to write a small attribute-based framework. The goal was to make it as simple as possible and be discoverable. Right now, the framework only supports GETting objects from your api, but that will change very soon.

    Setting up RestLess

    1. Add a reference to RestLess.dll
    2. In web.config under <system.web>, add
      <httpModules>
          <add type="RestLess.RESTHttpModule, RestLess" name="RestLess" />
      </httpModules>
    3. To tell RestLess where your API root directory is, in web.config under the <configuration> section add this key (you can make this whatever path you want)
      <appSettings>
          <add key="RestLess::BaseUrl" value="api/" />
      </appSettings>

    That's it!

    Exposing an object via the api

    You may have a Product object in your application with the properties Name, Description, and Amount. If you want to expose this via the api, you would simply decorate this class as follows. (RestLess code in blue, Comments in green)

        // decorate the class as a RESTResource, the first parameter is the url of the resource appended to
        // the root url (defined in web.config). In this case /api/products/
        // the second parameter specifies if this resource is discoverable (more on this later)
       
    [RESTResource("products", true)]
        public class Product : IRESTReadable
        {
            private string _name;
            private string _description;
            private double _amount;

            // render this property as xmlelement "productname"
            // IOType.InputOutput specifies that this property will be rendered
            // to the outputted xml, and can also be inputted via querystring
           
    [RESTProperty("productname", IOType.InputOutput)]
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }

            // render this property as xmlelement "productdescription"
            // IOType.Output specifies this property is rendered to the user,
            // but it is not allowed in querystring for input
           
    [RESTProperty("productdescription", IOType.Output)]
            public string Description
            {
                get { return _description; }
                set { _description = value; }
            }

            // render this property as xmlelement "amount" (output only again)
           
    [RESTProperty("amount", IOType.Output)]
            public double Amount
            {
                get { return _amount; }
                set { _amount = value; }
            }

            #region IRESTReadable Members

            public object GetRESTObject()
            {

                // this is where you could go access your data access layer or whatever other method you choose.
                // this is also where you could request an API key via querystring for security etc
                // since productname is specified inputoutput, you should check for
                // Request.QueryString["productname"] to get any data the user sends

                // for the purposes of this demo, lets just make an object and pass it back
                Product p = new Product();
                p.Name = "Super Fly Ink Pen";
                p.Description = "This is the most super fly ink pen ever";
                p.Amount = 10.00;

                return p;
            }

            #endregion

        }

    Done - that's all you have to do! You can add these attributes to as many of your classes as you want to expose through your api.

    If you request the url http://yoursite.com/api/products/default.aspx, the output will look like below

    Discovering The API

    As I mentioned earlier, the second parameter of the RESTResource attribute specifies if the resource is discoverable. If this parameter is set to true, you can visit http://yoursite.com/api/discover.aspx to see what the available resources are. The output of http://yoursite.com/api/discover.aspx will look something like below (notice another Customer object - I did not include this class for brevity).

    I plan on making lots of updates and changes to the framework as needed (I am VERY open to suggestions!!). This is a rough-rough draft, but seems to work well.

    ... now go and add an API to your .NET application in a few minutes. :)

    Jayme

     

    Posted Apr 19 2008, 11:04 PM by ndepth.net
    Filed under:
  • Usability is not what everyone else does

    The more sites I've tried in the past few years, the more I've noticed who cares about usability and who uses it in their marketing slogans. Some of the biggest players on the web define usability as doing what everyone else does. That is NOT usability.

    I will pick on my own application to demonstrate:

    Let's say you are creating an invoice for your customer in Meiraware Business. You fill out all of the relevant fields, then it's time to put in the invoice date.

    Not bad! Pretty easy to use. Standard calendar picker....  can't get much better. This is what everyone does, so it's usable!

    or so I thought....

    Now lets looks at Remember The Milk's date picker for their calendar

    (that right button is not a calendar control)

    At first impression, I was thinking "No calendar? What kind of shit is that?" ... then I realized you can type damn near anything in this box. You could type Next Tuesday, May 15 (assumes this year), Tomorrow, Next Thursday. Take a look at a brief example from their site that you can type in this box:

    That is attention to detail that ALL OF US could use more of. They took the concept of "choosing a date" and truly made it 'usable'.

    In my opinion, there should be a calendar added to Remember The Milk's control, some people do prefer to choose from a calendar. But besides that, it's brilliant.

    Jayme

    (p.s. I'm sure there are other companies with methods such as these, this is just the first i've seen)

    Posted Apr 17 2008, 04:21 PM by ndepth.net
    Filed under:
  • Say it with a one-click live demo

    Today, I launched a one-click live demo of Meiraware Business (a simple and easy invoicing application). Why a live demo? In my opinion, screencasts and/or screenshots is a distant second to actually using an application. Screencasts - I don't want to be guided through by someone who knows what they're doing. I want to get in there and click where I want to click. If I truly believe my application is easy, why do I need to guide you through it? Screenshots - make the page look nice, but never show what the application is really about.

    Here are the steps to check out Meiraware Business:

    1. Go to http://meiraware.com
    2. Click try a demo account

    That's it. No email address, no personal information. When you are finished, close your browser.

    In some situations, it may be difficult or impossible (not web-based) to provide a live demo. However, if you have the option to offer a one-click live demo, do so. People will hang around longer to see what your application is about.

    Jayme

    Posted Apr 07 2008, 12:42 AM by ndepth.net
    Filed under:
Powered by Community Server (Commercial Edition), by Telligent Systems