Transform existing WCF services to REST API

This could be legitimate use cases for most of you where you would like to expose existing WCF service as REST without breaking any existing client

Category REST API | Tags: WCF

Published: 27 March 2021

In this article, we will see a simple approach of exposing WCF service endpoints as REST API in addition to existing endpoints.

This could be legitimate use cases for most of you where you would like to expose existing WCF service as REST without breaking any existing client which might be using SOAP, TCP way of communication with the service. This approach, however, can be considered as a temporary resolution or workaround.

WCF (Windows communication foundation) is a rich SOA framework. It has allowed us to create enterprise SOA (service-oriented architecture) applications easily. However recent popularity of Restful API in the direction of Microservices architecture and adoption has overtaken WCF as a favorite framework for Service/API development.

For any organization, 70% and above portfolios still rely on legacy services. That means Old is still a gold – at least in the value proposition.

The legacy business value is still ahead of any new technology stack initiative and it would take maybe another decade to overcome any legacy existing framework. And we don’t know even today’s green technology could be obsolete in few years down the line.

Don’t Break existing Clients

Most of you you must be either trying to migrate all your WCF services to either RESTFull .NET Core API/ services Or trying to create a wrapper around existing legacy services.

In this article, we shall be leveraging on the WCF framework’s ability to expose multiple endpoints for a given contract.

So that means if you already have a client using SOAP endpoint or NET TCP endpoint they will remain unaffected.

 

WCF Services Support Multiple Endpoints?

WCF Services Support Multiple Endpoints which is built in framework feature.

One can expose the same contract or multiple contracts on the same or multiple endpoints and it is pretty simple to do so.

Today I am going to talk about an approach of enabling WCF service as REST API without breaking any existing client.

 

Getting started

I already have a sample WCF service that exposes a contract with simple API GetEmployee

[ServiceCOntract]
public interface IEmployeeService
{
    [OperationContract]
    string GetData(string value);

    [OperationCOntract]
    EmployeeDetails GetEmployeeData(string value);
}

[DataContract]
public class EmployeeDetails
{
    [DataMember]
    public string FirstName { getset; }
    
    [DataMember]
    public string Lastname { getset; }
    
    [DataMember]
    public string Address { getset; }    
}

 

Convert WCF Contract as REST API

I now will be trying to decorate existing WCF contract to act like REST API interface as below,

Please decorate your method with WebInvoke annotation as below,

[WebInvoke(Method = "GET", UriTemplate = "Employee/{empId}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]

 

using System;

[ServiceCOntract]
public interface IEmployeeService
{
    [OperationContract]
    string GetData(string value);

    [WebInvoke(MethodAccessException = "GET", UriTemplate = "Employee/{empId}",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
    [OperationCOntract]
    EmployeeDetails GetEmployeeData(string value);
}


WebInvoke 
can also be defined for POST, DELETE or PUT method as required.

RequestFormat can also be used to specify XML as a message format if needed.

[WebInvoke(Method = "GET", UriTemplate = "Employee/{empId}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
 


Configure REST endpoint and Behaviour

The Web.config file needs to register for additional endpoints for REST. Each endpoint will be supporting the same contract IEmployeeService at different addresses using different bindings. The base address can remain the same.

<services>
    <service name="WcfEmployeeService.EmployeeService">
        <!--Base address for the host-->
        <endpoint binding="basicHttpBinding" contract="WcfEmployeeService.IEmployeeService"/>
        <!--Secured call endpoint-->
        <endpoint address="authorize" binding="wsHttpBinding" contract="WcfEmployeeService.IEmployeeService"/>
        <!--RESTFul endpoint-->
        <endpoint address="api" binding="webHttpBinding" contract="WcfEmployeeService.IEmployeeService"
        behaviorConfiguration="jsonBehaviour"/>
    </service>
</services>


In the above configuration, we have defined three endpoints. One of the endpoints is RestFul which we added recently.

The behaviour is defined as below,

<endpointBehaviors>
   <behavior name ="jsonBehaviour">
    <webHttp automaticFormatSelectionEnabled="true"/>
   </behavior>
</endpointBehaviors>


Finally, Execute the API using the normal proxy way and using HttpClient, you shall see the same results.

Using Proxy client

 
EmployeeServiceClient client = new EmployeeServiceClient();
var details = await client.GetEmployeeDataAsync(id);

 

Using HttpClient

 

private static HttpClient _client = new HttpClient();

[HttpGet("{employeeId}")]
public async Task<IActionResultGet(string employeeId)
{
    var uri = new Uri($"{ServiceUrl}/{employeeId}");

    var response = await _client.GetAsync(uri);

    if (response.IsSuccessStatusCode)
    {
        return Ok(response.Content.ReadAsStringAsync().Result);
    }
    else
    {
        return StatusCode(500, "Server error");
    }
}

 

The above service URL should also match the JSON route.

I have used the below route for HTTP calls API :

ServiceUrl = “http://localhost:65524/Service1.svc/api/Employee”;

 

.NET Core Client support?

You can very much use the .NET Core client. In fact above client application, I have used is the ASP.NET Core API application.

 

Summary

It is possible to enable and expose WCF service as REST API without breaking the existing clients. WCF allows you to expose multiple endpoints and we can very much leverage that concept. This approach can be a handy and workaround in many scenarios.