Tag Archives: services

How to make a #REST-ish API with #WCF

Where I work we integrate a lot with external partners where they sometimes dictate the conditions. At the same time we have our technology, architecture and environment to deal with and solve it as good we can. This put us in a bit of a position recently when we were tasked with “make a REST API that conformes to this document”. We use WCF. And then there was headache.

But, since WCF is carrier agnostic, this shouldn’t be any problem right?! You can deliver via HTTP, TCP, you name it. It’s just the flick of a switch in some config. Turns out it wasn’t quite that easy. The document stated that the request will be sent as content-type “application/json”, it also stated that it will be a POST request and furthermore that the actual JSON request will be a payload in the BODY of the message. WCF don’t give you access to the body. Since it is by design to be protocol agnostic and not all protocols have a body or they differ from eachother.

This is all very well documented if you enter the correct search terms. Read more on both the problem and solution here, here (this is where most paths lead) and here.

This is mostly for me to remember for the future since I know now that I’ve gone through it I did it once before but forgot all about it until it was right there in front of me.

While it all sounds complicated it really isn’t. It’s as easy as 1-2-3, like David points out in his blog post on the subject.

1. Add a new WebContentTypeMapper, like so:

public class RawContentTypeMapper : WebContentTypeMapper
{
  public override WebContentFormat GetMessageFormatForContentType(string contentType)
  {
    //Make if-else statements here if you want to respond differently to different contentTypes. This one will always return Raw regardless of what you attack it with.
    return WebContentFormat.Raw;
  }
}

2. Make your new content type mapper available for use:

<bindings>
  <customBinding>
    <binding name="RawMapper">
      <webMessageEncoding webContentTypeMapperType="Your.Namespace.RawContentTypeMapper, Your.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </binding>
  </customBinding>
</bindings>

3. Put the new available content type mapper to use:

<endpoint contract="MyContract" behaviorConfiguration="MyEndpointBehavior" binding="customBinding" bindingConfiguration="RawMapper" />

(4.) When working with a Raw content type, your usual way of working with WCF will be put slightly out of order. Instead of using your standard contracts, your method will need to take in a Stream. After that you are free to work as you like. Here is what we did.

public string Check(Stream request)
{
  var json = new StreamReader(request, Encoding.UTF8).ReadToEnd();
  var internalRequest = JsonConvert.DeserializeObject(json);
  var querystring = HttpContext.Current.Request.QueryString; //perhaps some additional data in here?

  //Do stuff

  return string.Empty;
}

The above will give you everything you wanted from the start. Almost.

Now you are thinking “NICE! And then I just use the UrlTemplate(…) to get a descent way of finding the methods!”. Well, not quite. It won’t turn out like http://mydomain.ext/api/check, but rather http://mydomain.ext/path/endpoint.svt/api/check. While I haven’t tried, I’d go with some URL rewriting in IIS or something. Perhaps you have a loadbalancer who can do it for you, or some other mechanism.

Tagged , , , ,