Let your consumers choose how to consume your service (in my case a WCF service). Encourage integration with your service by making life easy for your partners(or at least easier). A lack of SOAP support on non-Microsoft/.NET languages can be a barrier to entry for some programs/programmers. It’s not exactly easy or convenient to build a SOAP message with headers and all. Below is an example of the absolute minimum, which is 169 characters with no header or body.

<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
  <soap:Header>
  </soap:Header>
  <soap:Body>
  </soap:Body>
</soap:Envelope>

Then I considered the possibility of using other such standards that are more terse and appeal to a wider audience (e.g. Plain Old Xml(POX) and JavaScript Object Notation(JSON)). I looked around at various projects online to find a suffix anti-pattern in service contracts. Below I have provided the example for a fictitious method called GetData, and the anti-pattern looks like this.

    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string GetData(int value);

        [WebInvoke(Method = "GET")]
        string GetDataXml(int value);

        [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        string GetDataJSON(int value);
    }

Following this anti-pattern, I should create three methods in my interface for a single operation, because I want to support three output formats. Fortunately, there is a much better way. However it isn’t really well documented in its entirety(at least that I could find, which is as good as it not existing).

Our trusty and yet increasingly complicated web.config file is part of the solution. There will need to be three separate endpoints each with their own endpoint behavior.

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="jsonBinding"></binding>
        <binding name="xmlBinding"></binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="JSONPOXSOAP.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/JSONPOXSOAP/Service1/"/>
          </baseAddresses>
        </host>
        <endpoint address="json" bindingConfiguration="jsonBinding" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="JSONPOXSOAP.IService1"></endpoint>
        <endpoint address="xml" bindingConfiguration="xmlBinding" binding="webHttpBinding" behaviorConfiguration="xmlBehavior" contract="JSONPOXSOAP.IService1"></endpoint>
        <endpoint address="" binding="wsHttpBinding" contract="JSONPOXSOAP.IService1">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="jsonBehavior">
          <webHttp defaultOutgoingResponseFormat="Json"/>
        </behavior>
        <behavior name="xmlBehavior">
          <webHttp defaultOutgoingResponseFormat="Xml"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

This allows for a much simpler and straight forward interface and service that implements it. This means one method for one operation, which is much nicer than three.

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(Method = "GET")]
    string GetData(int value);
}

I hope this helps create cleaner interfaces and makes your services more accessible.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s