We are exploring whether it is worth it to switch from SOAP webservices to REST. I have created a REST webservice with the following info:
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "Execute")]
ExecuteResponse Execute(ExecuteRequest request);
[OperationContract]
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "ExecutePutJSON")]
ExecuteResponse ExecutePutJSON(ExecuteRequest request);
}
The implementation code behind (RestServiceImpl.svc.cs) is as follows:
public class RestServiceImpl : IRestServiceImpl
{
public ExecuteResponse Execute(ExecuteRequest request)
{
//processing code that returns ExecuteResponse
}
public ExecuteResponse Execute(ExecuteRequest request)
{
//processing code that returns ExecuteResponse
}
}
The RestServiceImpl.svc is as follows:
<%@ ServiceHost Language="C#" Debug="true" Service="CICJIS.IWS.RestServiceImpl"
CodeBehind="RestServiceImpl.svc.cs" %>
The Web.config:
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing">
<listeners>
<add name="messages" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\Logs\RestService.svclog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
<system.web>
<compilation debug="true" defaultLanguage="c#" targetFramework="4.0" />
<httpRuntime maxRequestLength="999999" maxQueryStringLength="999999"
executionTimeout="999"/>
</system.web>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="10000000" />
</diagnostics>
<services>
<service name="RestServiceImpl" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="webHttpBinding" contract="IRestServiceImpl"
behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
The implementation code behind does the same thing as the SOAP webservice and returns the same ExecuteResponse Object. I consumed the two services through fiddler to obtain the statistics on how long it took to get a response back. The SOAP webservice uses ws-security but the REST webservice does not have any security implemented. What I found was that the SOAP webservice returns the response much faster than the REST webservice.
I'm not sure if maybe the scenario we have is not well suited for a REST service or maybe I've implemented the REST webservice incorrectly? I've also tried debugging both the REST and SOAP service and found that when it breaks in the method, the processing code in both methods completes at the same rate, but it takes longer for the response to return to the REST client than the SOAP client. Is it possible that the WCF api for REST is slower than the WCF api for SOAP when serializing the objects?
The following is an example of the stats from fiddler :
For SOAP: Request Count: 1 Bytes Sent: 13,693 (headers:299; body:13,394) Bytes Received: 2,651,288 (headers:235; body:2,651,053) ClientConnected: 16:12:39.775 ClientBeginRequest: 16:12:39.775 GotRequestHeaders: 16:12:39.775 ClientDoneRequest: 16:12:40.120 Determine Gateway: 0ms DNS Lookup: 0ms TCP/IP Connect: 1ms HTTPS Handshake: 0ms ServerConnected: 16:12:40.122 FiddlerBeginRequest: 16:12:40.122 ServerGotRequest: 16:12:40.122 ServerBeginResponse: 16:12:40.123 GotResponseHeaders: 16:13:25.744 ServerDoneResponse: 16:13:26.863 ClientBeginResponse: 16:13:25.744 ClientDoneResponse: 16:13:26.863 Overall Elapsed: 00:00:47.0877083 application/soap+xml: 2,651,053 ~headers~: 235
For REST: Request Count: 1 Bytes Sent: 2,369 (headers:298; body:2,071) Bytes Received: 1,982,735 (headers:230; body:1,982,505) ClientConnected: 16:12:07.728 ClientBeginRequest: 16:12:32.427 GotRequestHeaders: 16:12:32.427 ClientDoneRequest: 16:12:32.428 Determine Gateway: 0ms DNS Lookup: 0ms TCP/IP Connect: 2ms HTTPS Handshake: 0ms ServerConnected: 16:12:32.430 FiddlerBeginRequest: 16:12:32.430 ServerGotRequest: 16:12:32.431 ServerBeginResponse: 16:12:32.435 GotResponseHeaders: 16:20:06.914 ServerDoneResponse: 16:20:07.889 ClientBeginResponse: 16:20:06.914 ClientDoneResponse: 16:20:07.889 Overall Elapsed: 00:07:35.4626091 application/xml: 1,982,505 ~headers~: 230
The big difference between the two services is at ServerBeginResponse to GotResponseHeaders. I've repeated this test several times and got similar findings.
Anyone experience the same finding?