Building .NET 3.5 WCF RESTful web services with Delphi 2007

Posted by on in Blogs
What is "REST" anyway?
"REST" does not have anything to do with relaxing. It is rather a hot term used in the context of Service Oriented Architecture (SOA). The term "Representational State Transfer" was coined by Thomas Fielding in 2000, in his PhD dissertation "Architectural Styles and the Design of Network-based Software Architecture". In essence it is all about making services available through HTTP protocol easier. With traditional web services HTTP is used as transport for exchanging SOAP messages. REST supporters make a point that HTTP protocol is rich enough on its own, and it is possible to use it directly for exchanging arbitrary messages, not necessarily SOAP, and not necessarily XML.

In the early days of web services the HTTP protocol was the only mean for exchanging XML-encoded SOAP messages. Windows Communication Foundation (WCF) architecture introduced in .NET 3.0 decouples SOAP messaging from the underlying transport and introduces other then HTTP transports for exchanging SOAP messages. For example there is "NetTcpBinding" that uses TCP as transport protocol. With RESTful web services the underlying protocol is HTTP, however messages are not encoded as SOAP envelopes, and does not even need to be encoded in XML. It is more and more common to encode them in simpler JSON format instead, or even plain text. RESTful web services can be used to retrieve arbitrary MIME-types, not necessarily text, for example images.

Aaron Lerch in his "Creating RESTful Web Services with WCF 3.5" article points out that "Representational State Transfer" is a phrase that describes the generic principles that make up much of what we know to be the HTTP protocol. As it applies to web services, the primary concepts of interest are resources, and the actions that can be taken on a given resource. Resources are identified by Uniform Resource Identifiers (URIs), something that nearly everybody is familiar with. SOAP-based web services typically use a single URI to represent the service endpoint plus an operation. A RESTful web service uses a unique URI to reference every resource, and HTTP verbs to define actions on those resources. REST-based services are making heavy use of different HTTP verbs (GET, POST, PUT, DELETE), HTTP result status codes, and encoding request details inside the URI.

The .NET 3.5 Framework introduces support for this low-level "web programming" through new types defined in the "System.ServiceModel.Web" namespace. Specifically there is a new WCF binding for web programming called "WebHttpBinding", corresponding "WebHttpBehavior", new attributes for specifying HTTP GET or POST methods - "WebGet" and "WebInvoke", and also new "UriTemplate" custom attribute for mapping URIs to methods and their parameters.

Building basic Delphi 2007 WCF REST service

Let's build a simple Delphi 2007 WCF REST service application. The structure of Delphi 2007 WCF 3.5 web application is very similar to the Delphi 2007 WCF 3.0 applications described in the "Introduction to WCF Programming in Delphi" CodeGear Developer Network article. To successfully build the service application make sure to have .NET 3.5 installed and CodeGear RAD Studio 2007 "December Update" installed.

The first step is to create a new "Console Application - Delphi for .NET" and save it for example as "DelphiRESTBasicSample_Service" project.

The second thing to do is to add appropriate project references. Right click on the "References" node in the "Project Manager" and select "Add Reference...". Click the browse button and add the following reference assemblies to the project:

  • C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.ServiceModel.dll

  • C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\System.Runtime.Serialization.dll

  • C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.ServiceModel.Web.dll


The side effect of adding these references to the project is adding directories where these assemblies reside to the project's search paths.



Now it is time to add two empty units to the project. One for the service interface and one for the implementation. I'm going to start from implementing a simple "calculator" service. This time using new WCF attributes introduced in the .NET 3.5.
unit uServiceIntf;  

interface

uses
System.ServiceModel,
System.ServiceModel.Web;

type
[ServiceContract]
IService = interface

[OperationContract]
[WebGet(UriTemplate='Add?a={x}&b={y}')]
function Add(x, y: integer): integer;

[OperationContract]
[WebGet(UriTemplate='Sub?a={x}&b={y}', ResponseFormat=WebMessageFormat.Json)]
function Subtract(x, y: integer): integer;

end;

implementation

end.

Note the usage of the new "WebGet" attribute. To invoke both methods declared in the "IService" interface HTTP GET method must be used. The "UriTemplate" is used to specify how the web method is going to be invoked. The "UriTemplate" class supports the matching or binding of a string template with name-value pairs. When defining an OperationContract, a UriTemplate is specified and it accomplishes two purposes. First, it provides the mapping between a request URI and an OperationContract, and second, it identifies the named values that are subsequently bound to matching OperationContract method parameters. By default responses are encoded in XML. The second "WebGet" attribute contains "ResponseFormat=WebMessageFormat.Json" to instructs the WCF runtime to encode response as JSON, instead of XML.

The implementation of the service is trivial:
unit uServiceImpl;  

interface

uses
uServiceIntf;

type
TService = class(TObject, IService)
public
function Add(x, y: integer): integer;
function Subtract(x, y: integer): integer;
end;

implementation

{ TService }

function TService.Add(x, y: integer): integer;
begin
Result := x + y;
end;

function TService.Subtract(x, y: integer): integer;
begin
Result := x - y;
end;

end.

The last step is to add code to the project's source code. To display project source in the editor select "View Source" option from "Project" menu. Here is the full source code of the project.
program DelphiRESTBasicSample_Service;  

{$APPTYPE CONSOLE}

uses
SysUtils,
System.ServiceModel.Web,
System.ServiceModel,
uServiceIntf in 'uServiceIntf.pas',
uServiceImpl in 'uServiceImpl.pas';

var
aBaseAddress: string;
URIs: array of Uri;
host: WebServiceHost;

begin
try
aBaseAddress := 'http://localhost:8000/';
SetLength(URIs, 1);
URIs[0] := Uri.Create(aBaseAddress);

host := WebServiceHost.Create(typeof(TService), URIs);
host.Open;

writeln('Service is running and listening at ' + aBaseAddress);
writeln('Press any key to quit...');
readln;

host.Close;

except
on e: Exception do
begin
host.Abort;
writeln(e.Classname, ': ', e.Message);
readln;
end;
end;
end.

Note the new "WebServiceHost" class for hosting our RESTful service web service. The service is complete. After running it from inside the IDE you should see the following window. Press any key to stop the service application. Here we are hosting the WCF service in the console application, but it is also possible to host it inside the IIS.



To test the service application we can just start a web browser and type in the following URL:
http://localhost:8000/Add?a=2&b=3

Right-clicking on the browser window and selecting "View Page Source" reveals that the following string was returned from the "Add" method.



In order to consume RESTful web service an arbitrary HTTP client is required. Luckily Delphi 2007 comes with a number of Indy 10 components for low-level network programming. The "TIdHTTP" component implements an HTTP client and can be used to interact with our RESTful web application. In the CodeGear RAD Studio 2007 installation there is a demo Delphi for Win32 project that uses "TIdHTTP" component that can be used directly as a test client for our service application. In the default installation it can be found in the following location:

C:\Documents and Settings\All Users\Documents\RAD Studio\5.0\Demos\Indy10\HTTPVCLForm\IdHttpDemoVCL.dproj

Now we can test both methods: "Add" and "Sub". I have compiled the "IdHttpDemoVCL" project and started it from outside the IDE. Because I keep changing the service application, it is more easy to run the service from within the IDE.



Summary

The .NET 3.5 introduced support for building RESTful web services that do not use SOAP for encoding messages. This simplifies building SOA applications and clients. In this article I have demonstrated building basic .NET 3.5 RESTful web services with Delphi 2007 for .NET and consuming them with TIdHTTP component from Delphi 2007 for Win32 VCL Forms application.

References


About
Gold User, Rank: 9, Points: 364
Crazy about Delphi Programming!

Comments

  • Guest
    Thomas Pfister Saturday, 5 April 2008

    Pawel, congrat for this interesting article (and the references). This helps me at the moment a lot for a project-idea!

  • Guest
    Rob Cooke Saturday, 12 April 2008

    Thank you for posting this article. I've been trying to follow the examples. One two different computers, one running XP Pro the other Vista, both using RAD Studio 2007 with December Update, when I simply add the references and try to build I receive the following compiler messages:

    F2084 Internal Error: G3957
    E2202 Required package 'System.Runtime.Serialiation' not found.

    I've tried adding the inluded folders to my PATH, but that doesn't seem to help. The internal error is confusing and I've not found an reference to it on the web. Do you have any suggestions?

  • Guest
    Per Bakkendorff Wednesday, 30 April 2008

    I can run the test application OK, but I've tried to upgrade to the MVC preview 2, but I get the same internal error as Rob.
    [DCC error] F2084 Internal error: G3957
    [DCC error] E2202 Required package 'System.Web.Extentions' not found
    I've just added the DLL to the required section of the project.
    Anyone know what that means ? Or more importantly, a workaround ?

  • Guest
    Wuping Xin Thursday, 15 May 2008

    I got the same errors:
    [DCC Error] F2084 Internal Error: G3957
    [DCC Error] E2202 Required package 'System.Runtime.Serialization' not found

    Anybody has a solution?

  • Guest
    Restful Web Services | Web Service Guide Sunday, 23 September 2012

    [...] Paweł Głowacki : Building .NET 3.5 WCF RESTful Web Services …What is “REST” anyway? “REST” does not have anything to do with relaxing. It is rather a hot term used in the context of Service Oriented Architecture (SOA). … Content Retrieval [...]

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: