Web services are a new feature of the .NET Framework that lets client code access software components across networks using standard protocols such as SMTP and HTTP. Over the past few years, Microsoft Windows programmers have become used to COM and its role in producing software components. COM allows programmers to produce self-contained, language-independent components that can be built together into systems and used to form the basis of flexible distributed applications. Other component systems are also in widespread use, such as CORBA and Java RMI.
Although COM is very useful, it has some shortcomings. First, writing COM components can be difficult because the programmer needs a wealth of arcane knowledge to write them. Second, COM uses a proprietary binary protocol to communicate between components running remotely, which makes it hard to use COM components anywhere outside of a pure Microsoft environment. Integrating a COM system with components that use CORBA or Java RMI is not at all simple.
Web services help in two ways. First, you don’t need much specialized knowledge to write Web services, and it’s often very easy to provide a Web service interface to existing code. Second, Web services use standard Internet data formats and protocols for communication, so it’s a lot easier to build heterogeneous distributed systems. If you want to talk to some Windows-based components written in C++ from a remote client written in Java, you’re going to have a much easier time if you use Web services.
Here’s a simple scenario to show you how Web services can make the development of distributed services much easier.
Imagine that on one page of your Web site, you need to present some data on currency exchange rates. How do you get up-to-date exchange rate data? In the past, you might have had to use a proprietary online service to access the data or even extract the data from HTML scraped off the appropriate Web page. If the bank provides the appropriate Web service, you can simply make a call to the remote method, passing in the currency details and getting back the exchange rate. The Web service acts as a remote procedure call (RPC), allowing you to call a function exposed by a remote Web server. The use of standard Web protocols irons out any computer or language dependencies. So you could access the service from client code written in anything from VBScript to C++.
Web services provide a way to move toward a service-based computing model. As the world becomes more and more interconnected, it will become increasingly common to make use of Web services to build distributed applications. This might happen on many scales, from the micro to the macro. At the micro level, a programmer could use a Web service to provide a small parcel of functionality to his or her application. Someone writing a word-processing program might use Web services to provide access to specialized spelling checkers, or the writer of a spreadsheet might use Web services to give access to financial information.
On the macro scale, entire applications could be exposed as Web services so that users could subscribe to software rather than buy it. In the future, it might be possible to pay Microsoft to subscribe to Microsoft Office rather than buy it. Nothing would be installed on your computer, and every time you wanted to write a document, you would connect to the remote Office service.
Several pieces of infrastructure are needed to make Web services work, such as:
Data formats and protocols to enable Web services to communicate in a language-independent and platform-independent manner
A standard way for Web services to describe themselves
A way for clients to discover Web services
Let’s look at this infrastructure in more detail.
One of the major advantages of the Web service model over COM and CORBA is the use of standard data formats and protocols over proprietary offerings. Clients can communicate with Web services in the following three ways:
Using HTTP GET commands
Using HTTP POST commands
Using Simple Object Access Protocol (SOAP)
The first two methods use HTTP in a way that will be familiar to anyone who has written code to talk to a Web server. The use of the HTTP GET command (which adds request data to the end of the URL sent to the server) and the HTTP POST command (which passes data in the body of the HTTP message) means that you can talk to Web services from almost any language. The third method uses the SOAP protocol that is being developed by Microsoft, IBM, and several other authorities. The advantage of SOAP over HTTP is that it enables clients and servers to exchange more highly structured information than is possible with the HTTP commands.
SOAP provides a way to call methods using XML and HTTP. The details of the method you want to call and any arguments you need to supply are formatted as an XML SOAP packet. The server parses the contents of the packet, makes the call, and sends back a reply packet, which is also in XML. SOAP gives you, in effect, an XML-based and HTTP-based RPC mechanism. SOAP relies on Worldwide Web Consortium (W3C) schemas to define the content of SOAP packets, and the use of schemas makes it possible to define and pass over structured data.
SOAP isn’t a Microsoft invention, although Microsoft gives a lot of input to the committee that is defining the SOAP standard. There are SOAP bindings to many languages, and a growing number of applications are using SOAP to provide language-independent and platform-independent access to services.
Binary protocols such as DCOM and CORBA often find it hard to work through firewalls, but SOAP is much easier to work with in normal commercial distributed environments because it uses HTTP to send and receive data.
All three communication methods use HTTP as the transport mechanism, which means that Web services integrate very well with existing Web-based solutions.
Clients need to be able to obtain a description of how to interact with a Web service, such as the name of the service and what arguments it requires. Anyone who has worked with COM will be familiar with the idea of the COM type library, which contains a description of a COM object, its interfaces, and the methods they support.
The Web Service Description Language (WSDL) provides the equivalent of the type library in the .NET Framework. WSDL describes the methods exposed by a Web service and the in and out parameters they require, and as you might expect by now, it provides the information using XML. The format of WSDL files is quite complex, and because of the tools provided for you in Microsoft Visual Studio .NET, you won’t need to work with it directly, so I won’t mention it further.
You might want to advertise the Web services that your server supports so that clients can find your service from elsewhere on the Web. DISCO (Discovery of Web Services) is a SOAP-based protocol that defines a format for description data, along with a protocol for retrieving the data. If you want to advertise your Web services, you post DISCO files on your server. Clients can use these files to navigate to the appropriate WSDL files that describe the Web services in detail.
You can choose to advertise your services by static or dynamic advertising. Static advertising makes use of DISCO files that point to WSDL documents.
<?xml version="1.0"?> <disco:discovery xmlns:disco="http://schemas.xmlsoap.org/disco" xmlns:scl="http://schemas.xmlsoap.org/disco/scl"> <scl:contractRef ref="http://myServer/myService.asmx?WSDL"/> <scl:discoveryRef ref="http://someotherServer/serviceDir.disco"/> </disco:discovery>
DISCO documents always contain a discovery element as the root and define the disco namespace (which is used to tag the discovery element) and the scl namespace. The scl namespace is used to tag the contractRef elements that point to WSDL files and to tag discoveryRef elements that point to DISCO files on linked sites.
Dynamic advertising means that all Web services under a URL will be advertised automatically if you include a dynamic discovery file in the directory. Dynamic discovery files look like this:
<?xml version="1.0"?> <dynamicDiscovery xmlns:disco="urn://schemas-dynamic:disco.2000-03-17"/>
If you place this file in the root directory of a Web server, all Web services under the root will be automatically advertised. However, you can use exclude elements to omit some directories from the search path, like this:
<?xml version="1.0"?> <dynamicDiscovery xmlns:disco="urn://schemas-dynamic:disco.2000-03-17"> <exclude path="_vti_cnf" /> </dynamicDiscovery>
The exclude element can be used to speed up the search by omitting directories that don’t need to be searched. It can also be used to hide Web services that aren’t publicly available.
If you create Web services using Visual Studio .NET, you’ll get a dynamic discovery file created for you.