Simple WCF and REST 1

I’ll show in this short post how to implement WCF REST services. As a developper I use WCF on a daily basis, playing with bindings, adresses and contracts. So first the context !

Restaurant menu

I want to allow people to request my restaurant menu from a web service. Specs are quite easy, I want JSON messages and the address will be something like http://localhost/MyRestaurant.svc/.

There’s 2 differents method I want to give access to :

  • GetMenus : Send the menus, this method must be accessible with this URL : http://localhost/MyRestaurant.svc/Menus
  • GetDish : Send the information about a specific dish, the parameter will be the dish code. This method must be accessible with this URL :http://localhost/MyRestaurant.svc/Dishes/{dishCode}

Interface

So first thing to do (and I think we should always begin that way) is to create the interface for our services. We’ll describe the contract our services will implement and also set them to use REST.

    [ServiceContract]
    public interface IMyRestaurant
    {
        [OperationContract]
        [WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="Menus")]
        public Menu[] GetMenus();

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json,   UriTemplate="Dishes/{dishCode}")]
        public Dish GetDish(string dishCode);
    }

So, it looks like a lot a classic WCF service contract definition except for the WebGet attribute. It is the one allowing our service to be accessed via HTTP VERBS like GET or POST. The ResponseFormat parameter describe how the service will encode the response, you have the choice between JSON et XML. I’ll use JSON. The second parameter, named UriTemplate, indicates the URI client will have to call in order to access our service.

Model

Ok let’s be quick, we need a Menu and a Dish classes, that’s an easy job, no need to specify the DataContract and DataMember attributes here.

public class Menu
    {
        public string Name;
        public IList<Dish> Dishes;
        public decimal Price;
    }
public class Dish
    {
        public string Code;
        public string Description;
    }

We also need to simulate datas, so I made a false repository with some menus and dishes

public class MenuRepository
    {
        public static IList<Dish> Dishes = new List<Dish>
        {
            new Dish(){Code="FRIK", Description="Fries with ketchup"},
            new Dish(){Code="FRIM", Description="Fries with mayonnaise"},
            new Dish(){Code="CHOB", Description="Black chocolate mousse"},
            new Dish(){Code="CHOW", Description="White chocolate mousse"},
            new Dish(){Code="SALM", Description="Salmon"},
            new Dish(){Code="SALO", Description="Salad with olives"},

        };

        public static IList<Menu> Menus = new List<Menu>
        {
            new Menu(){Name="Menu 1", Price=12.5M, Dishes = new List<Dish>{Dishes[0],Dishes[2],Dishes[4]}},
            new Menu(){Name="Menu 2", Price=15M, Dishes = new List<Dish>{Dishes[1],Dishes[3],Dishes[5]}},
        };

    }

Final step with the plumbing part, I’ll implement the IMyRestaurant interface in the file MyRestaurant.svc.cs. Very straightforward, it just return results from the fake repository

public class MyRestaurant : IMyRestaurant
    {
        public Menu[] GetMenus()
        {
            return MenuRepository.Menus.ToArray();
        }

        public Dish GetDish(string dishCode)
        {
            Dish result;

            result = MenuRepository.Dishes.FirstOrDefault(d => d.Code.Equals(dishCode));

            return result;
        }
    }

WCF Configuration

We’re almost done here, we just need to slightly modify the Web.config file of our service project to enable WCF WebHttpBinding. By defaut WCF use BasicHttpBinding which respond to SOAP messages. As we’ll send HTTP request we need to allow it. Basically we just need to add an endpoint behavior like this :

		<endpointBehaviors>
			<behavior>
				<webHttp helpEnabled="true"/>
			</behavior>
		</endpointBehaviors>

Now we juts have to change the protocolMapping from basciHttpBinding to webHttpBinding :

<protocolMapping>
   <add binding="webHttpBinding" scheme="http" />
</protocolMapping>

Here we go, we can now test it ! Just open an internet navigator and call http://localhost:/MyRestaurant.svc/Menus.

The result is JSON formatted :

[{"Dishes":[{"Code":"FRIK","Description":"Fries with ketchup"},{"Code":"CHOB","Description":"Black chocolate mousse"},{"Code":"SALM","Description":"Salmon"}],"Name":"Menu 1","Price":12.5},{"Dishes":[{"Code":"FRIM","Description":"Fries with mayonnaise"},{"Code":"CHOW","Description":"White chocolate mousse"},{"Code":"SALO","Description":"Salad with olives"}],"Name":"Menu 2","Price":15}]

I’ll also call http://localhost:/MyRestaurant.svc/Dishes/FRIK to retrieve information on this particular dish.

So we just saw how easy it is to create and run a WCF REST service. Now our service can easily being called from any clients regardless of its own coding language.

One comment on “Simple WCF and REST

  1. Pingback: POST and WCF REST Service | Le Chat Codé

Leave a Reply