Archive | WCF RSS for this section

Implementing RESTiful WCF service

This post will give some simple insight on how to implement a RESTiful service with WCF.

REST stands for Representational State Transfer. Its an architectural style that focusses on accessing resources through a universal interface URI. An architectural style of software is something that describes the features that can be used to build a software. And REST is actually one way to implement client server architecture style and infact it builds on client-server archicture style. So a service that uses rest architectural style is usually reffered as RESTiful service or endpoint

Rest constraints are based on underlying principles that govern the web  which includes:

  1. User agents interacts with resources and resources are anything that can be named and represented. Each resource can be addressed via unique URI
  2. The interaction with resouces is accomplished using uniform interface http stardand verbs.  There is also declaration of the resource’s media type via http content-type header
  3. Resources are descriptive
  4. Resources contains links to other resources. (HATEOAS)

Even though WCF geared towards RPC (Remote Process Call) using SOAP, there is the capability to expose and consume REST services. The REST programming is around two attributes WebInvokeAttribute and WebGetAttribute and URI template mechanism that enable us to declare the URI and method verb.

WebHttpBinding binding and WebHttpBehavior provides the correct networking stack for using REST with WCF. The hosting infrastructure used to host RESTiful service are WebServiceHost and WebServiceHostFactory which extends ServiceHost and ServiceHostFactory respectively.

The WebGetAttribute tells the dispatcher that the method should only respond to HTTP GET request while WebInvokeAttribute which is mapped to HTTP POST by default, can be set to support any other HTTP VERB e.g PUT,DELETE

UriTemplate is used to enable customization of the URI for each method and verb combination.

So lets dive into some code to see this in action. The sample we are using is not a stardand just used to pass the concept of how to implement a RESTiful WCF service. Our data contract looks like

[DataContract]
public class Person
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public int Age { get; set; }
}

And here is the contract declaration, and to note here is the usage of the WebGet and WebInvoke attributes. I would like to point out that if you look at the UriTemplate for GetPerson and DeletePerson looks the same, but they have the different HTTP VERB.

[ServiceContract(Namespace = "https://piusnjoka.wordpress.com/v1/2013/07/20")]
public interface IPerson
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "save")]
void AddPerson(Person person);

[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "update")]
void UpdatePerson(Person person);

[OperationContract]
[WebInvoke(Method = "DELETE", UriTemplate = "person/{id}")]
void DeletePerson(string id);

[OperationContract]
[WebGet(UriTemplate = "persons")]
List<Person> GetAllPerson();

[OperationContract]
[WebGet(UriTemplate = "person/{id}")]
Person GetPerson(string id);
}

This is our service implementation, which is a singleton service.

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PersonService : IPerson
{
private static List<Person> persons = new List<Person>();

public void AddPerson(Person person)
{
persons.Add(person);
}

public void UpdatePerson(Person person)
{
//TODO: Implement bette update here
DeletePerson(person.Id.ToString());
persons.Add(person);
//do some update here
}

public void DeletePerson(string id)
{
persons.RemoveAll(x => x.Id == int.Parse(id));
}

public List<Person> GetAllPerson()
{
return persons;
}

public Person GetPerson(string id)
{
return persons.FirstOrDefault(x => x.Id == int.Parse(id));
}
}

And remember we said that we use WebHttpBinding to support REST and there in our app.config in host project you will find this

<system.serviceModel>
<services>
<service name="WCFRestSample.Service.PersonService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8082"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="WCFRestSample.Service.IPerson"></endpoint>
</service>
</services>
</system.serviceModel>

For simplicity, we will use a self hosting in a console application. Of importance to note here is the “WebServiceHost” which we are using to host our service. If in case it find that there is no endpoint configured in the service description it creates one at the service base address i.e for http/https. The WebServiceHost also add WebHttpBehavior to endpoint that do not have the behavior configured.

WebServiceHost host = new WebServiceHost(typeof(PersonService));
try
{

host.Open();
Console.WriteLine("Host Running");
Console.ReadKey();
host.Close();
}
catch (Exception)
{
host.Abort();
}
}

Thats it we have our service ready for hosting. Any client can call the RESTiful service and in our case we are going to use a simple console application which looks as below. And of importance to note is the “WebChannelFactory<IPerson>”. This adds WebHttpBehavior to endpoints if it does not already exist.

WebChannelFactory<IPerson> factory = new WebChannelFactory<IPerson>(new Uri("http://localhost:8082"));
var channel = factory.CreateChannel();

//Add three persons
Console.WriteLine("***Adding three initial persons**");
channel.AddPerson(new Person { Age = 12, Email = "testone@gmail.com", Id = 0, Name = "test user one" });
channel.AddPerson(new Person { Age = 12, Email = "testtwo@gmail.com", Id = 1, Name = "test user two" });
channel.AddPerson(new Person { Age = 12, Email = "testthree@gmail.com", Id = 2, Name = "test user three" });

Console.WriteLine("There {0} persons", channel.GetAllPerson().Count());
//Delete one
Console.WriteLine("Deleting person with id on 0");
channel.DeletePerson("0");
Console.WriteLine("There {0} persons", channel.GetAllPerson().Count());
Console.Read();

Console.WriteLine("Updating person with Id of 1");
var toUpdate = channel.GetPerson("1");
channel.UpdatePerson(toUpdate);
Console.WriteLine("Update done");

//Display to account
Console.WriteLine(channel.GetAllPerson().Count());

Console.ReadKey();

To finish lets look at some of the advantages which come with REST.

Caching:  When RESTful endpoints are asked for data using HTTP, the HTTP verb used is GET. Resources returned in response to a GET request can be cached in many different ways. Conditional GET, which is a way that a client can check with the service if his version of the data is still the current version, is an optional implementation detail a RESTful endpoint can implement that can further improve speed and scalability.
Scale-Out: REST encourages each resource to contain all of the states necessary to process a particular request. RESTful services are much easier to scale out when they fulfill this constraint and can be stateless.
Side Effects: RESTful services should have no side effects when you ask for a resource using GET (unfortunately, this constraint is easier to break than some of the other REST constraints).
Idempotent :The other two main HTTP verbs typically used as part of the uniform interface are PUT and DELETE. PUT is most often used when a user agent wants to modify a resource, and DELETE is self-descriptive. The important bit (and what the word idempotent describes) is that you can use these two verbs on a particular resource more than once, and the effect will be the same as the first time you used them—or at least there won’t be any further effect. This is reassuring when building reliable distributed systems in which errors, network failures, or latency might cause code to execute multiple times.
Interoperability: Many people tout SOAP as being the most interoperable way to implement client-server programs. But some languages and environments still don’t have SOAP toolkits. And some that do have toolkits are based on older standards that can’t always communicate with toolkits that implement newer standards. REST only requires an HTTP library to be available for most operations (an XML library, of course, is often useful as well), and it is certainly more interoperable than any RCP technology (including SOAP).
Simplicity: This advantage is more subjective than the others and can mean different things to different people. To me, the simplicity of using REST relates to URIs representing resources and the uniform interface.

Hope you enjoyed. Happy coding 🙂

Advertisements
%d bloggers like this: