Scripting Web Services

 

Andrew Clinick
Microsoft Corporation

March 13, 2000

Download Services.exe.

Contents

This Is All Future Stuff, Right?
How Does Remote Scripting Relate to SOAP?
Scripting a Web Service Today
Client Scripting of a Web Service
Implementing the "How's the Weather?" Service
What About the Server?
Summary

Just when you thought you had Web development pegged, along comes another shift. The biggest change coming to the Web development world (I think, anyway) is the introduction of Web Services. They take many forms, depending on whom you talk to, but every one seems to agree that they're all about making the Web programmable rather than just having a bunch of Web pages.

I like to think of the Web today as being somewhat similar to DOS: You can do some really cool things—but to do so, you end up writing nearly all the code yourself. Along came Windows and provided a common API for printing, displaying graphics, and so forth. That made writing applications much easier, since developers could concentrate on writing great applications rather than spending time writing "plumbing." The advent of COM took application development to the next level, allowing developers to expose their applications or components to be used by other applications. I'm sure I don't have to convince you of the benefits of component-based programming. Web services provide a similar shift in programming, allowing you to build Web applications quickly and to concentrate on writing your application to meet your users' needs—rather than focusing all your energies on implementing infrastructure.

This Is All Future Stuff, Right?

Developing Web services in the future will be considerably simpler than today, thanks to some of the great new features in Visual Basic 7.0, but that doesn't mean you can't get a jump-start on Web Services now and use them in your existing applications. On the simplest level, a Web Service is just a component, running on a server that has exposed a public interface that is callable via HTTP. The ideal mechanism to communicate with a Web service is through a new technology called Simple Object Access Protocol (SOAP). Memorable name, but it's already spawned some questionable bylines. The best I've heard so far is "it's a clean architecture" (groan). SOAP provides an implementation-independent infrastructure (that is you don't need to be running any vendor's operating system to communicate via SOAP) for calling remote objects via HTTP. This is important when calling a Web service, since you don't want to introduce a need to change firewalls and so forth just to call a particular Web Service.

SOAP is a pretty new technology—and at the moment, there aren't many shipping, robust implementations. This doesn't mean that you can't start to design for and use Web services in your applications. Rather, you have to be somewhat creative in how you design your application, so that you can swap your current wire protocol with SOAP when it becomes available. To illustrate how you can script Web Services today, I'm building a simple application that actually uses Remote Scripting for its wire protocol—but in such a way that this could be swapped with SOAP very simply as and when an implementation you're happy with becomes available.

How Does Remote Scripting Relate to SOAP?

This is a question I get asked a lot, more so as SOAP gains acceptance. I view Remote Scripting as an early version of Web Services (shame we didn't think of such a catchy title). It implemented on technology the script group had to build from scratch, since we didn't have any infrastructure to access the url, or to get the XML back, and we didn't have a wire protocol. If we were to write Remote Scripting today, we could use the XMLHTTP object to communicate with the server and use SOAP as the wire protocol, rather than inventing our own. In future articles, I'll cover how you can take what you already know about Remote Scripting and apply it to the brave new SOAP world. For more information on how Remote Scripting works, check out my April 1999 article.

Scripting a Web Service Today

To provide you with some real-world samples of scripting Web Services, I've split my examples into two main areas: client and server. The client example provides a class that abstracts the calls to the server. I took this approach so that when SOAP comes along, I can provide a new version of the class that changes the implementation but not the public interface. This should allow a seamless upgrade to SOAP; we'll see how successful that turns out to be! To illustrate calling a Web service from the server, I've chosen to show how you can use Microsoft Passport as a service from your ASP solutions. For those of you who haven't seen Passport yet, it's an authentication service that allows Web sites to provide users a single login. This is a huge boon for users (after all, how many passwords does a person need) and also for site developers. The key to it all is a service that is callable via HTTP, so your server can be any server that can talk HTTP and XML.

Client Scripting of a Web Service

When I started this article, I struggled to find any viable Web Services that I could use to demonstrate how to script them from a Web browser. Eventually, I decided that writing my own would probably best suit my needs. As any British readers will know, we're a nation obsessed with the weather—and since I live in Seattle, I get more questions about the weather than any sane person should have to answer. To help alleviate this, I thought I'd write a "how's the weather?" answering Web Service, which I can use on my personal home page and which anyone else afflicted with such a weather burden can call from their own Web page.

Implementing the "How's the Weather?" Service

To make it easy to implement and explain, I've implemented Weather version 1.0 as an ASP page—but rather than providing it as a standard ASP page, I've exposed the functionality of the page via Remote Scripting. This allows me to "publish" what the page can do while hiding any private functions on the page. I guess that makes the ASP page a simple object. To call the ASP page, users must use the Remote Script client software. In Weather version 2.0, I'll replace the Remote Scripting with a pure SOAP implementation, so that any application that supports SOAP can call the service.

The implementation of the service is written as a Visual Basic Scripting Edition (VBScript) class and a JScript® object, so you can use whichever language you prefer. Since this is a demo, the implementation it includes knows about a few cities (Seattle, London, Los Angeles, Phoenix) and the weather it returns is more my observations of each city than reality—although I'm convinced they're correct.

VBScript implementation: clsWeather.vbs

Class clsWeather
Public function getConditions(strCity)
   Select Case ucase(strCity)
      Case "LONDON"
         If month(now) <= 7 or month(now) >=9 then
            getConditions = "overcast"
         elseif month(now) = 8 then
            GetConditions = "partly overcast"
         End if
      Case "SEATTLE"
         If (month(now) = 7) and (day(now) = 4) then
            GetConditions = "torrential rain"
         Else
            GetConditions = "rain"
         End if
      Case "LA"
         GetConditions = "smoggy"
      Case "PHOENIX"
         GetConditions = "hot"
      Case Else
         GetConditions = "partly cloudy with a chance of showers"
   End select
end function
End Class

JScript implementation: clsWeather.js

function clsWeather() {
   this.getConditions = getCondition
function getCondition(strCity) {
   var now = new Date();
   switch (strCity.toUpperCase()) {
      case "LONDON":
         if (now.getMonth() <= 7||now.getMonth() >=9){
            return "overcast"
         }
         if (now.getMonth() == 8) {
            return "partly overcast"
         }
         break;
      case "SEATTLE":
         if (now.getMonth() == 7 && now.getDay()==4){
            return "torrential rain"
         }
         else {
            return "rain"
         }
         break;
      case "LA":
         return "smoggy"
         break;
      case "PHOENIX":
         return "hot"
         break;
      default:
         return "partly cloudy with a chance of showers"
   }
}
}

Once the functionality has been coded, it has to be made public to outside callers. In Remote Scripting, this is achieved by setting the public_description variable on the page to be an instance of the class or function. The Remote Scripting server runtime uses this variable to determine what should be made public. Using SOAP, I'd create a Service Description Language (SDL) file that described my service, and the SOAP listener would use that to marshal the calls into the Web Service. I've built weatherservice.asp to create the instance and do the Remote Scripting hookup. The VBScript or JScript code is included into weatherservice.asp, so it's kept separate for ease of migration in version 2.0.

weatherservice.asp

<%@ LANGUAGE=VBSCRIPT %>
<!--This includes the VBScript version but just change 
the .vbs to .js for JScript -->
<!--#INCLUDE FILE="clsWeather.vbs"-->
<%
set public_description = new clsWeather

' Call RSDispatch to use the public_description object 
and make its methods available for Remote Scripting Calls
RSDispatch %>
<!--#INCLUDE FILE="../_scriptlibrary/rs.asp"-->

Now that the service has been implemented, we can call it from a Web page. To do this, I've abstracted the Remote Scripting calls into a simple client-side script (in both VBScript and JScript). This script uses the Remote Scripting getASPObject method to get a proxy client object that actually remotes all calls to the weatherservice.asp page. Providing the script as an include allows for version 2.0 to change the implementation—so that it will use SOAP to call the Web service, yet my code in the Web page won't have to change.

To test out the Web service, I've written a really simple form that asks you for the city you want to know the weather for. When you click on Submit, client-side script calls the getConditions method on the proxy object, which in turn remotes the call to the weatherservice.asp page. The result of the method call is used to update a <DIV>. Since the return value is just text (after it's been extracted from the Remote Scripting XML payload) it could be a textual description or an <IMG> tag providing a graphical view of the weather.

<HTML>
<HEAD>
<TITLE>Web services from the client</TITLE>

<BODY>
<script language="JavaScript" src="../_ScriptLibrary/rs.htm"></script>
<script language="JavaScript">RSEnableRemoteScripting("../_ScriptLibrary");</script>

<table border="0" width="100%">
   <tr>
      <td width="15%">
          <p align="right">Which city?:
      </td>
      <td width="17%"><input type="text" name="txtCity" size="20">
      </td>
   </tr>
</table>
<input type="button" value="Get Weather" name="btnFindFlights"></input>
<br><br>
The weather is:<br>
<div id="divWeather"></div>

<script language="jscript">
function btnFindFlights_onclick(){
divWeather.innerHTML = svcWeather.getConditions(txtCity.value).return_value
}
btnFindFlights.onclick = btnFindFlights_onclick
</script>
<script language="JScript" src="clsWeatherservice.js"></script>
</BODY>
</HTML>

View the form in action. (For this sample to work, be sure to install remote scripting and to put the file into the wwwroot of your server with RS installed.)

Hopefully, this has whetted your appetite for writing Web Services using the currently available script technologies. The experience you gain from designing your applications around the services paradigm will prove invaluable, and will be applicable once SOAP comes along. In a future article, I'll be translating this example to use SOAP, so you can see how easy it really is to do.

What About the Server?

I think the sweet spot for Web Services will initially be when used in server development, since it's much easier to add functionality at the server level without having to worry about what version of the browser a user is running. Calling a Web service on a server allows you to take advantage of not only the service providers' code but also their computing power—always an advantage on overstressed servers. To illustrate how you can use Web Services on the server, I'm going to run through how you can use the Microsoft Passport Web Service. Using the Passport service brings not only a simple programming model but also a prebuilt data center that can handle millions of users. If you were to write your own authentication mechanism, you'd have to design a system to authenticate and also manage the databases that hold all the users' data—not a job for the faint of heart!

Passport provides a set of COM components for use within your ASP pages. The COM components provide an abstraction of the communication between your server and the passport authentication servers. All you need to do is set properties and call methods on the object model, and the COM component takes care of the transmission for you. I won't go into the entire Passport SDK in this article, but I'll show you some of the code that's required to get Passport up and running. For more in-depth information about Passport, check out http://www.passport.com/business/.

The simplest use of Passport is to check whether the user has been authenticated. To do this you need just a few lines of server side script:

'Create an istance of the Passport object where oFactory is an
'object in the application scope
Set oPassMgrObj = oFactory.CreatePassportManager
' Check to see if the user is authenticated
' set the TimeWindow to be 5 minutes to allow for timeouts
' don't force logon
If Not (oPassMgrObj. IsAuthenticated (300, False) Then
   ' redirect the user to the logon page
   response.redirect "login.asp"
End if

The call to the IsAuthenticated method will cause Passport to communicate back to the Passport servers, via HTTP, and to check the user authentication. So you get all the value of the service (the database calls, inter-server communication, and so forth) just by using one method call.

Using a Web service by calling a method and checking the return value is very similar to calling a set of functions in an include. The value of Web Services can be increased further by the type of data the service returns and how that data is displayed to the user. Passport provides a simple way to display the users logon status in your Web pages in the form of a picture.:

This provides a consistent user interface in all sites that use Passport, making users' lives a little easier. To display the images and the authentication state of the user is just a method call on the Passport object in an ASP page.

<% = oPassMgrObj.LogoTag (Server.URLEncode (ThisPageURL), _
TimeWindow, ForceLogin, CoBrandArgs, LangId, Secure) %>

The method call checks with Passport, and the return value provides HTML that includes all the information required. When users click on the image to sign in, they go directly to the sign-on page on Passport.

Passport chose to return HTML, since it makes sense to have the same user interface to log on in different applications. A Web Service could return data (for example, news headlines) in XML, to which you could then apply an XSL style sheet to display the data in a form that makes sense for your users.

Summary

I hope I've given you an insight as to how scripting Web Services can make your Web application development easier and more flexible. As the technology progresses and SOAP becomes more prevalent, we should be able to start using Web services in the same way we use components today. In the short term, I recommend you take a look at Remote Scripting as an interim mechanism for implementing Web services, and keep an eye on the MSDN Online Web site for some exciting new Web Services technology. I'll do a follow-up to this article and explain how the wonderful weather service can be ported to using SOAP and made available to every application—not just Remote Scripting-enabled Web pages.

 

Scripting Clinic

Andrew Clinick is a program manager in the Microsoft Script Technology group, so chances are, if there's script involved, he's probably had something to do with it. He spends most of his spare time trying to get decent rugby coverage on U.S. television and explaining cricket to his new American colleagues.