Alik Levin's

Clarity, Technology, and Solving Problems | PracticeThis.com 

June, 2010

  • Alik Levin's

    Notes On RESTful Architecture - I

    • 0 Comments

    This post is a summary of notes I am taking while reading a book RESTful .NET: Build and Consume RESTful Web Services with .NET 3.5.

    Resources and URI’s

    • RESTful services model the interaction with user agents based on resource.
    • The first thing to do is to determine which resources you’re going to expose.
    • A resource is any information that you want to make available to others.
    • Some resources are static…, and some resources are dynamic.
    • Once you’ve identified the resources you’ll map then to URI’s.

    URI design

    • All resources are uniquely identified by a URI.
    • The idea behind REST is to design your URIs in a way that makes logical sense based on your resource set (vs. GUIDS or/and funky query strings)
    • When designing the associations between resources and URI’s, it may be useful to map them as if you were designing a browsable website.

    Uniform Interface

    • User agents only interact with resources using the prescribed HTTP verbs.
    • The four main verbs are:
      • GET
        • Retrieves a resource.
        • Guaranteed not to cause side-effects (SAFE).
        • Cacheable.
      • POST
        • Creates a new resource.
        • Unsafe, effect of this verb isn’t defined by HTTP.
      • PUT
        • Updates an existing resource.
        • Used for resource creating when client knows URI.
        • Can call N times, same thing will always happen (idempotent).
      • DELETE
        • Removes a resource.
        • Can call N times, same thing will always happen (idempotent).

    Checklist for building RESTFul architecture:

    • Decide what your recourses are.
    • Map the resources to URIs.
    • For each URI define it’s media types [HTTP Content-Type]:
      • XML [application/xml, text/xml - deprecated].
      • RSS/Atom [atom more recent, devs like it, APP or AtomPub protocol].
      • XHTML [application/xhtml+xml].
      • JSON [application/json]
      • More at www.microformats.org

    Related Books

  • Alik Levin's

    Notes on RESTful Architecture – II. Read Only RESTful Services

    • 0 Comments

    From the book RESTful .NET: Build and Consume RESTful Web Services with .NET 3.5.

    RESTful binding, behavior, hosting, and contracts

    WebHttpBinding – uses http transport and text encoder.

    WebBehavior – end point behavior to dispatch messages based on URIs and HTTP verbs.

    WebSericeHost – provides RSTful services hosting configuration [WebServuceHostFactory for IIS/WAS].

    WebOperationContext – contains state of the incoming request and outgoing response.

    • QueryParameters – holds the collections of query string parameters. Available in IncomdingRequest of WebOperationContext.

    WebGetAttribute – applied to methods to handle GET requests

    WebInvokeAttribute – applied to methods to handle POST, PUT, DELETE.

    • Method - a property that specifies what HTTP method to use [POST – default, PUT, or DELETE]

    UriTemplate – specifies the template, mapping between the URI and a method

    • “/{Variable}/{Variable}/{Variable}”
    • “*”
    • “/”
    • “{/{Variable}/*}”
    • “/Literal/{Variable}”
    • “/Literal/NestedLiteralSpecialCase”
    • “/Search?q={query}” – for passing parametrs via query string and collecting it using QueryParamenters object.

    Serialization methods

    Message - represents return value for RESTful service

    • Not usually used with non-RESTful WCF [strong type are used instead]
    • More complex coding to process the message
    • Complete control of the XML

    DataContract 

    • Preferred method non-RESTful regular WCF
    • Cannot create attributes, elements only

    XnkSerializer

    • Better for RESTful WCF
    • [XmlSerialization()] for [OperationContract]
    • Can create attributes vs. elements [XmlAttribute(Attribute=”name”)] instead [DataMemeber]

    Hybrid (DataContract + Message)

    • Use DataContract for serialization.
    • Use Message.CreateMessage for return type.
    Related Books
  • Alik Levin's

    Walkthrough: Build, Host, and Test Simple RESTful WCF Service

    • 0 Comments

    This post summarizes the steps needed to create basic self hosted RESTful WCF service based on the book RESTful .NET: Build and Consume RESTful Web Services with .NET 3.5.

    Summary of steps

    Following are the summary of steps needed to be taken to create and test self hosted RESTful WCF services.

    • Step1 - Create a class that represent resource – user.
    • Step2 - Create a service that expose functionality to manipulate the resource
    • Step3 - Create self-host to host the service
    • Step4 - Use fiddler to test the solution – get all users
    • Step5 - Use fiddler to test the solution  - get specific user
    • Step6 - Use fiddler to test the solution  - update user

    Rest of the post is the details for each step. Create new console project in Visual Studio.

    Step1 - Create a class that represent resource – user.

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.Runtime.Serialization;

    namespace ReadWriteREST
    {
        //SINCE I USE DATA CONTRACT THE SERIALIZED XML WILL BE 
        //BUILT BASED ON ELEMENTS vs. ATTRIBUTES
        [CollectionDataContract(Name="users",Namespace="")]
        public class Users: List<User>
        {
        }
        [DataContract(Name = "user", Namespace = "")]
        public class User
        {
            [DataMember(Name = "id", Order = 1)]
            public string UserId;
            [DataMember(Name = "firstname", Order = 2)]
            public string FirstName;
            [DataMember(Name = "lastname", Order = 3)]
            public string LastName;
            [DataMember(Name = "email", Order = 4)]
            public string Email;
        }
    }

     

    Step 2 - Create a service that exposes functionality to manipulate the resource

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Web;

    namespace
    ReadWriteREST
    {
        [ServiceContract]
        public class UserService
        {
            static Users _users = new Users();

            [WebGet(UriTemplate = "/users")]
            [OperationContract]
            public Users GetAllUsers()
            {
                GenerateFakeUsers();
                return _users;
            }

            [WebInvoke(UriTemplate = "/users", Method = "POST")]
            [OperationContract]
            public User AddNewUser(User u)
            {
                u.UserId = Guid.NewGuid().ToString();
                _users.Add(u);
                return u;
            }

     

            [WebGet(UriTemplate = "/users/{user_id}")]
            [OperationContract]
            public User GetUser(string user_id)
            {
                var u = FindUser(user_id);
                return u;
            }

            private User FindUser(string user_id)
            {
                return new User() { FirstName = "alik"
                                    LastName = "levin",
                                    Email = "alikl@microsoft.com",
                                    UserId = "1" };
            }

            private void GenerateFakeUsers()
            {

                _users.Add(new User() { FirstName = "alik",
                                        LastName = "levin",
                                        Email = "alikl@microsoft.com",
                                        UserId = "1" });
            }
        }
    }

    Step 3 - Create self-host to host the service

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Description;

    namespace ReadWriteREST
    {
        class Program
        {
            static void Main(string[] args)
            {
                ServiceHost sh = new ServiceHost(typeof(UserService),
                                                 new Uri("http://localhost:8089/"));
                bool openSucceeded = false;
                //TRY OPENINNG, IF FAILS THE HOST WILL BE ABORTED
                try
                {
                    ServiceEndpoint sep = sh.AddServiceEndpoint(typeof(UserService),
                                                                new WebHttpBinding(),
                                                                "Hosting");
                    sep.Behaviors.Add(new WebHttpBehavior());
                    sh.Open();
                    openSucceeded = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Service host failed to open {)}"
                                      ex.ToString());
                }
                finally
                {
                    if (!openSucceeded)
                    {
                        sh.Abort();
                    }
                }
                if (sh.State == CommunicationState.Opened)
                {
                    Console.WriteLine("The Service is running. Press Enter to stop.");
                    Console.ReadLine();
                }
                else
                {
                    Console.WriteLine("Server failed to open");
                }
                //TRY CLOSING, IF FAILS THE HOST WILL BE ABORTED
                bool closeSucceed = false;
                try
                {
                    sh.Close();
                    closeSucceed = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Service failed to close. Exception {0}",
                                      ex.ToString());
                }
                finally
                {
                    if (!closeSucceed)
                    {
                        sh.Abort();
                    }
                }
            }
        }
    }

    Step 4 - Use fiddler to test the solution – get all users

    This functionality is handled by the following method:

    [WebGet(UriTemplate = "/users")]
    [OperationContract]
    public Users GetAllUsers()

    Run your service. Use Fiddler’s Request Builder to issue a request similar to the following

    RESTful WCF

    Use Inspectors tab to review the response.

    Step 5 - Use fiddler to test the solution  - get specific user

    The functionality is handled by the following method

    [WebGet(UriTemplate = "/users/{user_id}")]
    [OperationContract]
    public User GetUser(string user_id)

    RESTful WCF

    Use Inspectors tab to verify the response.

    Step 6 - Use fiddler to test the solution  - update user

    The functionality is handled by the following method:

    [WebInvoke(UriTemplate = "/users", Method = "POST")]
    [OperationContract]
    public User AddNewUser(User u)

    RESTful WCF

    Notice three main attributes of this request:

    • the method is POST although submitted to the same URL.
    • Content-Type is text/xml.
    • Request body contains serialized User object as the method expects.

    Related Books

Page 1 of 2 (5 items) 12