Browse Tag: rest

How to create a RESTful web service using WCF (Part 3 of 3)

RESTful (Representational State Transfer) web services use HTTP verbs to map CRUD operations to HTTP methods.  RESTful web services expose either a collection resource (representational of a list) or an element resource (representational of a single item in the list).

Other parts in this series:
How to create a RESTful web service using WCF (Part 1 of 3)
How to create a RESTful web service using WCF (Part 2 of 3)

Testing the WCF service using Fiddler

If you haven’t come across Fiddler before, its a very helpful tool for capturing HTTP traffic.  Fiddler lets us create HTTP messages and send them to our WCF service, it also shows us the response to our message.

HTTP GET

We will start by testing the HTTP GET method that we wrote a little earlier (we know for sure that already works).

execute_thumb2

getresponse_thumb2

Open Fiddler, click the Composer tab and enter the Url to the web service (the same Url you entered into your web browser earlier).  Once done, ensure that GET is selected, and click the Execute button (above).

The web service should respond after a couple of seconds, and you can see that response by clicking the Inspectors tab and clicking JSON (shown on the left)

HTTP POST/PUT

Testing the other HTTP verbs takes a little bit more effort, but not much.  Flip back to the Composer tab and take the following steps;

  1. Change the HTTP verb from GET to POST.
  2. Add a Content-Type: application/json header
  3. Change the service Url to /BlogService/Post
  4. Add the following response body;
{
    "id": "0",
    "title": "This is a test",
    "url": "http://www.developerhandbook.com"
}

The web service should respond with HTTP status code 200 (OK).  Also the web service will return the new blog post, with its Id property set to a proper value (6 in this case).

To update the entity, switch the HTTP verb from POST to PUT (which is Update in RESTful speak)Change the title property, and the Id property to 6 and click Execute again.  Again the web service should return a 200 status code and the entity in JSON format (and again, with the Id of 6).

The difference between a POST and a PUT is simple.  POST should always return a different object than the object you sent it.  PUT should always return the same object that you send to it.  These are the characteristics of a properly implemented RESTful web service.

HTTP DELETE

Change Fiddler to use the DELETE verb.  When you do this, the Request Body field in Fiddler will turn red.  That’s because, usually, no request body is sent along with DELETE requests.

Delete the request body and change the Url to; http://localhost:8085/BlogService/Post/6

Note that we are indicating which resource we want to delete via the Url, rather than having to pass an object to the server.

Consume the web service using jQuery

We won’t get too much into the nitty-gritty about how to consume the web service using jQuery, after all the entire source code is available on GitHub.  I personally used jQuery’s ajax method and simply varied the type depending on the verb I wanted to use.

For example;

$.ajax({
        type: "POST",
        url: baseServiceUrl + "/Post",
        contentType: "application/json",
        data: JSON.stringify(blogPost),
        dataType: "json",
        success: function (data) {
        blogPost.id = data.id;
        self.reset();
    }
});

And the DELETE request is even simpler (shown below).

$.ajax({
    url: baseServiceUrl + "/Post/" + blogPost.id,
    type: "DELETE",
    contentType: "application/json;charset=UTF-8"
});

We’re really just copying what we’ve already achieved using Fiddler.

For the demo I’ve used jQuery, Bootstrap, and KnockoutJS…so please be sure to download it and check it out for yourself!

Summary

WCF provides out of the box support for writing RESTful web services.  Using service contracts, operation contracts, and data contracts, we can make available all the basic information about our web service for consumption from any external clients, including non- .NET clients.  We can easily test that our service is working using Fiddler, a free debugging proxy tool that allows us to intercept and “fiddle” with traffic.

…and after all that, if your thinking “why not just use Web API?”, my response would be “its hard to disagree with you!”.

github4848_thumb.pngDownload the full source code including the full demo project from GitHub today!

How to create a RESTful web service using WCF (Part 2 of 3)

RESTful (Representational State Transfer) web services use HTTP verbs to map CRUD operations to HTTP methods.  RESTful web services expose either a collection resource (representational of a list) or an element resource (representational of a single item in the list).

Create the WCF service contract

Every WCF service begins with a service contract.  A service contract defines what operations are supported/provided by the service.  An operation contract is the definition of a method that can be invoked by a client application.

A WCF service can exist without any operations, but it wouldn’t be of much use.  Usually, all the WCF related definitions are placed on an interface, which is implemented on a normal class (this helps keep everything nice and tidy).  Although this is not strictly required.

Data Contract

Before we can get onto the goodness of implementing our WCF service, we need to make a small alteration to our BlogPost.cs model class.

A data contract is basically a promise (contract!) that describes the data that can be transferred between the client and the server.  A data contract is denoted by the DataContract attribute, which is added to each class you want to be serializable.  Each property that you want to be serialized is decorated with the DataMember attribute.  The DataMember attribute can be given additional metadata such as a name, which overrides the name of the property. 

Being able to define a name for each property when the serialization takes place is particularly important.  We will be writing a JavaScript front end for this application, which prefers field names to be in camel case… and we want to be consistent with that.

Update your model class (BlogPost.cs) as follows;

[DataContract]
public class BlogPost
{
    [DataMember(Name = "id")]
    public int Id { get; set; }

    [DataMember(Name = "title")]
    public string Title { get; set; }

    [Column("Url")]
    [DataMember(Name = "url")]
    public string UriString
    {
        get
        {
            return Url == null ? null : Url.ToString();
        }
        set
        {
            Url = value == null ? null : new Uri(value);
        }
    }

    [NotMapped]
    public Uri Url { get; set; }
}

Note that we haven’t decorated the Url property with the DataMember attribute because we don’t want it to be transferred to/from the client.

HTTP GET

In the Service project, add a new interface named IBlogService.cs and add the ServiceContract attribute.  Then add a new method definition, GetBlogPosts which returns an array of BlogPost (you will need to add a reference to the Data project here).

[ServiceContract]
public interface IBlogService
{
    [OperationContract]
    [WebGet]
    BlogPost[] GetBlogPosts();
}

The WebGet attribute is a REST specific attribute indicating that the operation is accessible via the HTTP GET verb.  The WebInvoke attribute can be used for POST, PUT and DELETE verbs.

Next, create a class named BlogService which implements IBlogService.  Add a static constructor to initialise the database and update the GetBlogPosts method to return all the blog posts in your database;

public class BlogService : IBlogService
{
    static BlogService()
    {
        Database.SetInitializer(new BlogInitializer());
    }

    public BlogPost[] GetBlogPosts()
    {
        using (BlogContext context = new BlogContext())
        {
            return context.BlogPosts.ToArray();
        }
    }
}

Before we can test our WCF service, we need to make a few edits to the configuration file, which was added for us when we created the project.  Open app.config and make the following alterations;

1. Make sure that the service name matches the full namespace for your service interface;

<system.serviceModel>
    <services>
      <service name="RESTfulTutorial.Service.BlogService">

2. Update the base address to tell WCF to use the port number 8085, and simplify the address a little to tidy it up;

<baseAddresses>
    <add baseAddress="http://localhost:8085/BlogService/" />
</baseAddresses>

3. Update the endpoint to use webHttpBinding rather than basicHttpBinding  Also check that the contract namespace is correct, and add a behaviourConfiguration named Web (we will define this shortly).

<endpoint address=""
    binding="webHttpBinding"
    contract="RESTfulTutorial.Service.IBlogService"
    behaviorConfiguration="Web"/>

4. Add an endpoint behaviour (just after the service behaviours section), which will tell WCF to respond in JSON by default, but permit responses in both JSON and XML;

<endpointBehaviors>
    <behavior name="Web">
        <webHttp automaticFormatSelectionEnabled="True" defaultOutgoingResponseFormat="Json" />
    </behavior>
</endpointBehaviors>

If you query http://localhost:8085/BlogService/GetBlogPosts using your web browser, you should see all the blog posts returned as an array (and in XML).  This works because by default, of course, your web browser issues a HTTP GET request, which we permitted using the WebGet attribute.

Whilst this works, its not very RESTful.  What I mean by this is that simply the URL describes the operation, rather than being representational of the data (see what I did there.).  To make the operation RESTful, update the WebGet attribute as follows;

[OperationContract]
[WebGet(UriTemplate = "/Posts")]
BlogPost[] GetBlogPosts();

If you query http://localhost:8085/BlogService/Posts this time, you should get the same data back as before, but in the proper RESTful way.

Parameters

It is possible, and useful, to pass parameters into a URL in order to return a specific resource rather than a collection of resources.

Take the following method;

[OperationContract]
[WebGet(UriTemplate = "/Post/{id}")]
BlogPost GetBlogPost(string id);

A place-marker ({id}) is used to indicate that a parameter will be provided, and that marker matches the name of the parameter accepted by the operation.  Unfortunately, when using custom Uri templates like this, WCF can’t identify the type of the parameter, only strings… so you have to manually cast the string to, in this case, an integer before using it (sigh).

Note that I have also changed the Uri template to Post rather than Posts, simply because I only want to return a single blog post in this case (again this is consistent with the REST specification).

HTTP POST/PUT/DELETE

Other HTTP verbs are just as easy to implement.  Add the following operations to your service contract;

[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/Post")]
BlogPost CreateBlogPost(BlogPost post);

[OperationContract]
[WebInvoke(Method = "PUT", UriTemplate = "/Post")]
BlogPost UpdateBlogPost(BlogPost post);

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

Instead of using the WebGet attribute, we use the WebInvoke attribute, which basically means most other verbs other than GET.  As we’re not using Uri templates with place-markers, we can pass in a complex object from the client and WCF will just figure out what to do with it.

For completeness, here is the implementation for each operation that we added to the service contract;

public BlogPost GetBlogPost(string id)
{
    int identifier;
    if (int.TryParse(id, out identifier))
    {
        using (BlogContext context = new BlogContext())
        {
            return context.BlogPosts.FirstOrDefault(post => post.Id == identifier);
        }
    }

    return null;
}

public BlogPost CreateBlogPost(BlogPost post)
{
    using (BlogContext context = new BlogContext())
    {
        context.BlogPosts.Add(post);
        context.SaveChanges();
    }

    return post;
}

public BlogPost UpdateBlogPost(BlogPost post)
{
    using (BlogContext context = new BlogContext())
    {
        context.Entry(post).State = EntityState.Modified;
        context.SaveChanges();
    }

    return post;
}

public void DeleteBlogPost(string id)
{
    int identifier;
    if (int.TryParse(id, out identifier))
    {
        using (BlogContext context = new BlogContext())
        {
            var entity = context.BlogPosts.FirstOrDefault(blogPost => blogPost.Id == identifier);
            if (entity != null)
            {
                context.BlogPosts.Remove(entity);
                context.SaveChanges();
            }
        }
    }
}

Summary

We’ve looked at how to define a WCF service contract, how to define so operations, and how to make our model classes serializable.  We’ve also looked at how to use various attributes to change how methods are accessed, to bring them into line with the REST specification.  In the final part of this series, we will look at how to test the web service using Fiddler, and a high level look at how we might implement a client application using jQuery.

How to create a RESTful web service using WCF (Part 1 of 3)

RESTful (Representational State Transfer) web services use HTTP verbs to map CRUD operations to HTTP methods.  RESTful web services expose either a collection resource (representational of a list) or an element resource (representational of a single item in the list).

HTTP verbs are used as follows;

  • Create (POST) > create a new resource.
  • Read (GET) > retrieve one or many resources.
  • Update (PUT) > update an existing resource.
  • Delete (DELETE) > delete an existing resource.

This tutorial demonstrates to how implement a simple RESTful web service using WCF, and how to query it using various jQuery methods (at a high level).  Entity Framework code first will be used for data persistence.  The program we will create will be for reading, editing and updating a list of blog posts… what else?! Smile

By the way, throughout this tutorial I will use the terms RESTful service, web service, and WCF service interchangeably…which is fine for this tutorial (but not in the wild).

Project Structure

I think its very important to establish the correct project structure before developing a solution, as it can often be hard to change later.

SolutionAdd three new projects; Data, Service and Web (as shown to the left).  We want to define clear boundaries in our solution, which would (if this were a real project) make future maintenance easier.

The data project will contain our entities, and all (surprisingly little) logic required to persist and retrieve data from an external data store. In this case, for simplicity, I have used Entity Framework code first approach.

The service layer will contain our WCF RESTful service definition, all associated configuration, and each of our CRUD methods.

Finally, the Web project will be the client.  Again for simplicity, I simply added a HTML file (index.html) and jQuery to pass requests to the service.  We will not dive too much into how this works, because its relatively straightforward.  All associated source code for this solution is available on GitHub.

Add each project using the following templates;

  • Data > standard C# class library
  • Service > WCF Service library
  • Web  > Empty ASP .NET Web application (completely empty).

Cross Origin Request Service (CORS)

I found that CORS requires quite a bit of additional code to work correctly.  In case you don’t know, CORS enables us to make requests to the web service across domains.  By default, Visual Studio will spin up the WCF service and the IIS Express instance on different ports, so basically nothing will work out of the box (CORS is strictly disabled by default).

To make your client and WCF service run on the same ports, follow these steps;

  • When we define an endpoint for our service (a little later on) set the port number to 8085.  This is an arbitrary number.
  • Right click on your Web project, and click properties.
  • Click the Web tab.
  • Set the project Url to; http://localhost:8085 (or whatever port number you have decided to go with).  What matters is that they are the same.

Web

So now your WCF service and client run on the same port number, all the extra agony that comes with CORS is avoided.

Data persistence using Entity Framework Code First

I find Entity Framework code first to be one of the best and fastest ways to rapidly prototype a SQL server database, fill it with data, and query that data.  Perhaps not an approach you would want to use in a production environment, I find the whole concept of migrations to be a little clunky, but great for getting up and running quickly. 

I’m assuming that you have a good working knowledge of Entity Framework code first.  If not, then have a look at my tutorial on Entity Framework code first in 15 minutes. And by the way, if you also need to scrub up on code first migrations, have a look at Entity Framework code first migrations tutorial.

A blog post, for this tutorial at least, consists simply of an Id, Title and Url property. Add BlogPost.cs to your Data project as follows;

public class BlogPost
{
    public int Id { get; set; }
    public string Title { get; set; }

    [Column("Url")]
    public string UriString
    {
        get { return Url == null ? null : Url.ToString(); }
        set { Url = value == null ? null : new Uri(value); }
    }

    [NotMapped]
    public Uri Url { get; set; }
}

As you may know, Entity Framework can only deal with simple types so we need a wrapper property to retrieve and set the value of the actual property for us.  We have used the ColumnAttribute to indicate the name of the column that the property is to be mapped to, and used the NotMappedAttribute to explicitly tell Entity Framework not to use said Url property.  (By default Entity Framework tries to map all public properties).

We will revisit this class later and tidy it up for WCF and so that it can be consumed properly by the client.

Next, add a BlogContext.cs as follows;

public class BlogContext : DbContext
{
    public BlogContext()
        : base("BlogContext")
    {
    }

    public DbSet<BlogPost> BlogPosts { get; set; }
}

And finally, add a database initializer and define some seed data;

public class BlogInitializer : DropCreateDatabaseAlways
{
    protected override void Seed(BlogContext context)
    {
        context.BlogPosts.AddRange(
            new[]
        {
            new BlogPost { Id = 0, Title = "Resilient Connection for Entity Framework 6", Url = new Uri("http://developerhandbook.com/2014/02/05/resilient-connection-for-entity-framework-6/") },
            new BlogPost { Id = 1, Title = "How to pass Microsoft Exam 70-486 (Developing ASP.NET MVC 4 Web Applications) in 30 days", Url = new Uri("http://developerhandbook.com/2014/02/01/how-to-pass-microsoft-exam-70-486-developing-asp-net-mvc-4-web-applications-in-30-days/") },
            new BlogPost { Id = 2, Title = "5 easy security enhancements for your ASP .NET application", Url = new Uri("http://developerhandbook.com/2014/01/26/5-easy-security-enhancements-for-your-asp-net-application/") },
            new BlogPost { Id = 3, Title = "10 things every software developer should do in 2014", Url = new Uri("http://developerhandbook.com/2014/01/18/10-things-every-software-developer-should-do-in-2014/") },
            new BlogPost { Id = 4, Title = "15 reasons why I can’t work without JetBrains ReSharper", Url = new Uri("http://developerhandbook.com/2013/12/28/15-reasons-why-i-cant-work-without-jetbrains-resharper/") }
        });
    }
}

I went with the DropCreateDatabaseAlways initializer so that I can add whatever dummy data I like and just reset everything by simply restarting the application.

Summary

We’ve set the important groundwork for developing our RESTful WCF service.  In the subsequent parts of this tutorial we will look at creating a WCF service contract, and how to invoke it using various HTTP verbs.  Stay tuned!