Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2003-624
$eventId
ID of event: wwdc2003
$eventContentId
ID of session without event part: 624
$eventShortId
Shortened ID of event: wwdc03
$year
Year of session: 2003
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC03 • Session 624

WebObjects - Creating Web Services

Enterprise IT • 59:10

WebObjects gives you the ability to build or use standards-based web services without writing low-level SOAP, XML, or WSDL. Learn how to use WebObjects to build, configure, and test web services from existing data assets. Advanced topics include debugging web services, object serialization, adding custom operations, and calling web services from within WebObjects.

Speakers: Karl Hsu, Ron Lue-Sang

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it may have transcription errors.

Good morning, everybody. I hope you guys had a nice lunch, a good nap, or a session, depending on how awake you were. And hey, that wasn't a joke. So we're here going to talk about WebObjects and creating web services. This is session 6.2.4. If any of the above sounded wrong, you're probably in the wrong room.

As our nice, friendly voice of God introduced me, I'm Carl Su. I work in Web Objects Engineering. And I'll be doing the first half of this presentation. The second half of the presentation will be done by my compatriot, Ron Lue-Sang. He's the friendly Jamaican Chinese guy. So we have to have the obligatory what you will learn in this session slide.

They told us. All right, so web services. We're going to talk very briefly about what a web service is. In our case, when we talk about web services, we're going with a stricter definition. I mean, technically, web services is anything where you invoke services over the web. But we're going to specifically talk about the standards-based web services that WebObjects provides and uses. We'll talk a little bit about practical applications of web services, why you would use web services in lieu of just a regular HTTP Connect or Corbo or anything else like that.

Then finally, we get to the meat of the matter. We'll talk about WebObjects and Web Services. WebObjects as a server, WebObjects as a client, and finally, about the crown jewels for Web Services and WebObjects direct to Web Services. Hopefully that will be a relief to those of you who have been going to the WebObject sessions and not actually hearing a whole lot about WebObjects.

So in a single sentence, what are web services? Web services are remote procedure calls for the internet era. And they're XML based. The goal, I think, in that one sentence was to hit as many little buzzwords as you possibly can. It'll sound great to managers, IT people. It's fantastic.

There are a bunch of standards and specs in the official web services sphere. There's description of the web service in the WSDL, which is the web services description language. There's discovery of a web service, how you find what web services exist and how do you find the information about them. And that's the UDDI, which stands for something I can't remember.

Universal Discovery Definition and Interface or Interrogation, something like that. Thank you. Nobody calls it that. Nobody remembers what it's called. Everybody just says UDDI. So when you hear that buzzword floating around, you know what it is. Ah, that's discovery. The encoding of the web service itself. When you send XML back and forth, you have to agree on a particular way that the XML will look. That's SOAP, the Simple Object Access Protocol. And finally, the transport. When you send the XML and receive it, you have to do it over something, over the wire, whatever. And those vary. That's probably the most flexible part about the whole thing. But the two most common, the two that are defined in the spec itself, are HTTP and SMTP. WebObjects in particular mostly deals with HTTP. the U.S. and the United States.

So let's go a little bit over the parts of a web service. When people talk about a web service, they typically talk about three major parts. There's the WSDL. And the WSDL, the WSDL, is a contract. It defines everything about your web service. You can sort of think about it as the interface to a class.

When you publish a web service, you publish the WSDL to it. And that's what the client uses to know how to talk to the web service. There are a number of tools out there that can also use the WSDL to generate stub classes and so on and so forth. The service itself consists of a set of operations and invocation information. It's the -- again, in an analogy, it's the class itself. It can hold state or whatever you need it to do. The operations exist within a service. That's something to keep in mind. A single service can have multiple operations. It's sort of a grouping, because a service exists at a certain point. It exists at a certain URL. And then you can invoke multiple operations at that point. Those are analogous to methods.

Let's take a quick look at the WSDL. It's the Web Services Definition Language. It's also defined in XML, and it basically defines everything you need to invoke a web service. It's the structure of the web service itself. It defines data types that are used in the web services. Not only the standard set of data types-- ints, strings, dictionaries, whatnot-- but also custom data types that you may have for your web service. EO global IDs, whatever. It defines message types-- requests, responses, error messages, anything that you might send, what you're supposed to send, and what you might get back. It talks about the available operations on that web service, what can you do with it. Can I add something?

you know, invoke a particular method that will return some status, whatever. It's all in there. It defines where that service is actually located, the URL or address that you would invoke that web service at. And finally, it talks about the transport bindings. Most of the time, for web objects in particular, that will be HTTP.

Let's talk a bit about SOAP. It's the Simple Object Access Protocol. This is basically the protocol. When you send the XML across the wire, you can think of this a little bit like the meta schema for what you're actually going to send across. It defines the language in which you will define your web service. Okay? It splits up the message layout itself. So each SOAP envelope will then have a header in which you can stuff ancillary information about the web service itself. In a particular invocation, for instance, it might include routing information or session-based information.

And then the body itself, which is where the bulk of the data that's going back and forth across the wire is kept. The SOAP standard defines several transport protocols, HTTP and SMTP, but it leaves it open for plug-in. They're not tied to a particular protocol. You could conceivably write a web service that required somebody to write down the XML on a piece of paper, run to your neighbor's house and give it to them and run back. It wouldn't be very effective, but it would technically be within spec.

just to show you just because it's a spec doesn't mean that it works. It's, you know, a lot like statistics. It supports synchronous and asynchronous modes. You can do the standard sort of HTTP way. You send a response. the service does whatever it's doing, and then it sends you the, I'm sorry, you send a request.

I'm sorry, I'm not worthy. You send a request, it gets processed, and it sends a response. There are also asynchronous modes in which the server may poll a client for a request, or for data, and so on and so forth. An interesting thing at this point is that there are two major styles of web service. There's an RPC style of web service, and there's a document style of web service. Most people, I think, would like to be using an RPC style. The RPC style is invoked very much like a remote procedure call.

That would be RPC. You invoke a method, you pass arguments in a particular order, and you get back a response. Document style is a little bit more flexible, but it's also more annoying, it's more work. You essentially say, I'm going to send you XML soup in some privately defined format. You muck with it and send me back more XML in a privately defined format, and we'll kind of negotiate it there. This actually negates a large point of web services, which is easy negotiation and easy understanding of what you're actually sending and receiving.

So this is a really quick example. I mean, you can sort of see, if I wanted to find an RPC service, it's very analogous to a class and a method. You receive optional arguments, you return something. In the case of a document service, you just get basically, in our case, you would get a DOM tree, and you would have to return something very similar. And how do you respond to that?

So problem solved by web services. The major bonus of web service is that it's very clean information transfer. There are a number of services out there, Watson, for instance, where at least initially, I'm not sure about now, the whole point was that it would screen scrape. It would hit a website, get back the HTML, and it would have to then parse its way through the HTML looking just for the information that you're looking for. That's bad, because it means that if they decide to change the look of the site, if they say, you know what, we're going to do something nice. We're going to put an ad here. We're going to move this search field around or something like that. You're totally bored. And sites change all the time. Part of the point is that the display is fluid. It also means that it doesn't dictate any sort of display or usage. You can expose the information. and you expose the service, and the client can do whatever they want for it. They can present it directly back to the user. They can aggregate it. They can do whatever you want.

Another important thing is that it's implementation dependent. The spec tries to be as clean as possible so that the server doesn't have to know anything at all about the clients. And this is what really separates it in large part from custom solutions, things where you just agree on a private format between you and the client. In this case, you don't need to know anything about the client if you're the server or vice versa. It tries to be fluid in a way that the spec tries to encompass pretty much anything. So you can have WebObjects written in Java running on Mac OS X talking to Pearl running on Linux or C# running in a.NET client on a Windows machine. And you don't have to know what that is. As long as you can talk the web services talk, it goes back and forth and everybody's happy. And finally, one of the reasons it was created this way is that it's firewall friendly. Unlike older iterations of things like Corbo and such, you don't have to open up any funny ports. You don't have to do anything interesting to make your system administrator really unhappy.

You basically punch a hole. You no longer have to punch a hole through anything. You can just route it right through your web server the way that you would normally. And because it fits that well onto this sort of Internet standard, it makes things much easier to use. The best part about it, though, is that it's human-readable. - Yeah.

This actually isn't a very complicated thing. I think the best description that I've ever heard of this is the fact that the SOAP XML is human readable does not actually guarantee that it is readable by humans. So you could, in fact, you could conceivably encrypt it or something like that. It doesn't really matter. I mean, the goal is that you wouldn't actually have to look at it. One of the goals of things like web services is that the XML is well-defined. XML is well-understood. The SOAP spec that defines how the XML is structured is well-understood. And it becomes very easy for you to write tools so that machines can talk to machines. It's written in XML. It's done in XML so that there are a number of tools available to read and write it, not so that you can actually do this by hand. Please, if you do, though, it would be really interesting to hear about it.

Okay, hold on a second. It should be obvious by now. Participants in a web service, you have a server and you have a client. Often they're called a provider and a consumer. It's just a different name for it. Shouldn't have to worry about it. Theoretically, what ends up happening is the server will write the web service. They then register with some sort of universal directory, and then they publish the WSDL to that in a way that's described in the directory.

So you would go to the directory and you would look up, I want web services that do, let's say something really lame, add two numbers together. And you would get a list of URLs for contact information and WSDL locations for those services. And then you could hit those services, take a look at the WSDL that came back, run your client automation thing, and now you can talk. Finally, of course, the server has to provide the web service itself. Okay.

The client does the opposite. It has to look up the web service in a directory. It will then configure itself using the WSDL, and it can invoke the web service. The configuration using WSDL can be either dynamic or static. There are a number of tools out there that will generate stubs. WebObjects, the default implementation for WebObjects doesn't do that. In fact, it just retrieves the WSDL and then tries to be sort of nice about it.

Very quickly, we'll go over this. This is a little bit more specific. This sort of is looking at the web service event flow from a WebObjects point of view. And I'm not going to talk about the client side, because it's essentially a mirror image of what happens on the server.

So the client sends its WSDL request. The server returns the WSDL to the client. The client will then... I mean, this can happen offline. You can cache the WSDL. You can keep it in a file, use it to generate stubs or whatever. That happens... could happen right before the request and have the client dynamically do something to generate the proper SOAP request. Sometimes it happens much earlier. Okay. So now the client sends a SOAP request. The server gets it as XML. In WebObjects, we unmarshalled the XML into a set of objects, native types. We process it. We marshal the response back into XML.

and we return the response to the client. Again, it's very simple. So let's begin talking about WebObjects and Web Services. WebObjects uses Access for its engine to do Web Services. This is the Apache Extensible Interaction System. I don't know why it's called that, because it doesn't seem to have anything to do with what it actually does. It's written by the Apache group. It's open source. It has support for both the client and the server, and it has automatic WSDL generation.

We basically stuffed it directly in. WebObjects does do some nice stuff for you. It has plug-ins for both session support and custom serialization and deserialization of objects. In particular, all of the basic objects that WebObjects is likely to use, all of our NS collection classes and the EOs themselves. And of course, on top of the Access Engine, we wrote our coup de grace, the direct-to-web services. And we'll talk about that later.

Actually, he'll talk about that later. So things that we do to you, specifically the deserializers that we have are for NSArray, data, dictionary, range, time zone, enterprise objects, and global ID. In a WebObjects application and on this client, they are automatically registered for you. We also provide WSDL for these.

We also provide--this is actually one thing that we do that should be really nice. It's session support. We have the custom session handlers installed on both the client and the server side. One major lack in the SOAP 1.1 spec is that it doesn't talk at all about transaction semantics. There's no way to carry on a conversation about web services. When they define the spec, they sort of assume that each web service would be nice and sort of self-contained, that the answer from one invocation would have nothing to do with the request of another one. We felt this was a major lack, particularly when we were trying to deal with databases. So what we added was we extended the session support in WebObjects to support sessions through web services so that you can invoke a web service and store server-side state. Can anybody else say that three times fast?

I can't, that's okay. The other thing we add, and this is pretty minor, is just dynamic registration. Access is configured typically through a set of XML files, and we typically don't like to do that. So we provided the WoW Web Service Registrar. It's a single call that you can use to register a web service. Okay, so really quickly, I'm just gonna run through the demo.

So we have a demo server. And you can see Session Test Service is the name of my service. The service class itself is not terribly complicated. It's called state test. What I'm gonna do is it gets the current session. Sorry. Does anybody remember how to change the font on this thing? references, text editing, syntax coloring. Here we go. Sorry about that. Please forgive me. I know not what I do. Ah, there we go.

This is about as simple of a service as you can get. We get the current context, the WebObjects context. We get the session. And in our session, we just store an array of strings, basically, so that as we send, each time we add to that list. And finally, application. Here's that single line that I was talking about to register. I've actually registered the session under a different name, session test, just to see it's doable.

Okay, the client is gonna be a little bit simple. What the client is gonna do is it's just gonna be a front end, it's gonna be a WebObjects application with a text field. You're gonna add in, type in a string, hit Enter, and as a response we're gonna send back the list of previously submitted strings. This is obviously a very trivial application. So, web service client, we can get the web service client, so on and so forth. All right, so let's run these suckers.

One thing to keep in mind at this point is that the client, because what I want to do is I want to show you what's happening on the client through something called TCP Monitor just to prove that we're actually going across and so you can see what the state looks like. I've actually stored the WSDL locally on the machine. And it looks like this.

You can see here, state test response, state test return. It returns an array. The request takes a string. The name of the service is the session test service. The operation is named the state test. And it takes a string, returns the response. takes a request, returns a response. Those are the message types that I was talking about. All right. So let's hook this up.

And let's hope the network is kind to us. And it is. OK. And here, so our first request is this one. Sorry, is the font still too small for this? You can see it's a very simple one. You have the soap envelope itself, which defines all of the namespaces. You have the body and the string itself encoded. On the way back, Again, the envelope. Here's where the session support comes in. We start sending the session. We send the information in the header. You can see that we have the session ID, for those of you who are familiar with WebObjects, and the instance ID. In our case at this point, since we're running directly, there's no instance ID at all. If you walk through the rest of them, it's the same request. you can see that we're simply returning an array. Okay, back to slides.

Let's talk a little bit about the client really quick. It's basically a very thin convenience API on top of Access. While on the server side, we added direct web services, we didn't add anything quite that complex on top of the client side. The custom deserializers and serializers are available. They're registered. The session support is registered. For security, you can do HTTPS on the client side to connect using the standard Java APIs.

Going forward, talking about security, currently the current state of the art for web services security in terms of secure connections is pretty much just HTTPS. That's fine. It works pretty well. There is an industry standard, WS security. It's been basically Microsoft, IBM, all the big people are behind it. WebObjects doesn't support that at this point, unfortunately. We do provide a security delegate that will get invoked at pretty much every single phase, before the response is sent, after the response is sent, before and after marshalling, so that at any point you can hook in and ask WebObjects to do whatever needs to be done. And finally, so I'd like to introduce Ron Lue-Sang. He's our Jamaican-Chinese web objects engineering cowboy.

Man. I hao ma. Man. Man. Man. Man. Man. Man. You know, your hat's out of date. It's already obsolete. Yeah. It's panther time now. I can only find a panther-colored cowboy hat. So, thanks, Carl. Now that Karl's told us everything we need to know about web services and how WebObjects leverages access to support web services, I'll just take the next 20 minutes or so and tell you about our kick-ass technology, direct-to-web services.

I'll just talk a little bit about three things. Three things, basically. First, what is it that Direct Web Services is trying to address? What problem is it trying to address? And also, what technologies went into Direct Web Services? And then I'll give you a cool demo that has a WebObjects application talking to a Cocoa desktop application via Web Services. So what problem is it that Direct Web Services solves?

Basically, we in the WebObjects department believe that our developers write too much code. And by that, I mean they write too much application-specific code. We want our developers to have simple lives and simply work on fine-tuning their business logic. So to that end, we've come up with these rapid development technologies. And if you're familiar with direct-to-web or direct-to Java client, then you're probably familiar with the rule system that we have in WebObjects. With direct web services, we've extended that and added to it the access and web object support for web services, and also our fantastic enterprise objects framework, and wrapped that in the rule system that we have. If you haven't heard of our rule system, it's basically a question and answer system that lets you infer values from a set of rules and some contextual info. That way you can have a really dynamic application where a set of rules instead of lots of code defines your application behavior.

So the problem that we're trying to solve is-- sure, right now you can build a WebObjects application pretty easily that will vend your business logic as a web service using Axis, WebObjects, and EOF. But you still have to write some code. And usually that code does one of four things-- create, read, update, or delete a bunch of rows from your database, typically called-- the CRUD operations. So we'd rather have our developers skip doing all of that CRUD and leave the work to us. So that's what direct web services tries to solve, keeping you guys productive, working on your business logic, and leaving the CRUD behind. So-- Let's see. All right. And so then on to what technologies went into direct web services. So Carl's already told you about Access, which does all the heavy lifting of SOAP messaging for us. And he's also told you about how WebObjects adds session support and, of course, all the load balancing that you expect from WebObjects as an application server. So between Access and WebObjects, we already have a great way to talk web services. Then on the low end, we also have the Enterprise Objects Framework, which we believe is the best way for accessing and modifying, interacting with business data in your JNDI or JDBC data sources.

So and of course, again, wrapping all of this in the smarts that is the rule system, we've put together our kick-ass crown jewel technology, direct to web services. So I'm just going to go to the demo now. We get demo two, please. Cool. Just going to start a new project. Just like all of our direct to star projects, we have a project template called direct to web services. And we'll give it a cool name.

and we'll add a business logic framework that I've already built. All right. Navigational problems, sorry. Okay. And we'll just go ahead and build and launch the application. So along with the project templates, we also have assistants. Every direct-to-web application, direct-to-Java client applications, and now also direct-to-web services have assistant applications that you use to configure the rules for your application as a first step for specifying behavior of your application. So while that's starting up, let's see. So it'll bring up a little web browser, which isn't entirely useful for a web services application. But it tells you that. It tells you you should really put this URL in the Web Services Assistant, which I'll do here.

So now the Assistant is going to connect to our application, and it can already look at all of the models that are in our application, as you can see here. And it can also see all of the services that are already published. By default, we have an aptly named service, the WoW default web service already set up for us. We'll go ahead and enable it. And we'll make one of these entities public.

And over here, you can see the service is already populated by default. Every time we add an entity, we add a few operations that do all of those CRUD, all the CRUD work I talked about earlier. Specifically, inserting, searching, updating, deleting. And we also look through the fetch specifications for your model. So we find things like my named fetch specification for find user and login user. Just so you can see what I'm talking about here.

So let's just give it a try. We'll do a search for users, and we only want to have to specify somebody's first name, and I want all the first names to be case-insensitive-like, and we can also change the return values so that we don't return some random person's passkey. We just get their address, first name, and last name, And I want to change the public name for the operation, the return type, so that it's user name.

So this is an important thing. Right now, we're exposing your business logic as a web service, so clients can go and examine the wisdom that's generated from the service. And you don't want them to necessarily have a really good idea of how your data is modeled. So you can change the names to be something less sketchy for public consumption. So now we'll test this operation. and we'll send the changes that we've made in the Assistant back to the server, and it will be updated in the rule system there. So now we can look for all users with the first name starting with R.

Poof, we do get one user. Some of this text may be a little hard to read, but-- you'll see that there's a key value coding null value here. Don't worry about that. What's actually happening is we're sending back a serialized EO without the pass key, as you saw me configure earlier. On the client side here, because this is also using WebObjects technology, we can actually create a real EO on the client side, but it doesn't have the pass key set yet. So if we don't wanna see these values in our client, or especially if our client is in a WebObjects application, we can go ahead and turn on returning soaped struct.

This makes it a little bit cleaner for non-WebObjects clients. Alternatively, it makes it a little less efficient for WebObjects clients. So there's a trade-off there. Actually, let's go ahead and add messages as a public operation. You can see we've created some operations there. And let's go ahead and turn on the Insert Message operation. We don't want clients to automatically create the creation date for the messages that they're inserting, so we'll take that out. We'll just say we need a subject, a recipient to send it to by address. And let's add the sender's address and a message.

And then for return values, we don't really need to return anything. Just insert it and be done with it. Then we'll enable the operation, turn on Soapstruct, returning just for the heck of it. And let's try this out. Ah, okay. I forgot to change this. I forgot to change this. Because we've gone and reverse engineered kind of the fetch specification in my model, I actually choose the names for the key value bindings in the model, which are not very kosher as far as web services names go. So I'll go ahead and change these as well.

And so you notice there, we can actually do a little bit of validation for you to make sure that you're not going to end up publishing a WSDL that isn't valid. So again, let's go back and test the insert message operation. Let's take a look at the WSDL for this service, the entire service, just for fun. This is the sort of thing that we don't want you guys to have to worry about. This is precisely the sort of thing that Direct Web Services handles for you. will dynamically figure out what parameters you set as input and output parameters and merge those into a whistle for your service. Let's say hello to Carl from me. Wait for it, Carl. OK. And we get an exception. So what's happened here is it claims that the creation date is-- yeah, so we got an exception. So now we know that we need to start debugging our app.

All right. Yes, I believe this was expected, but this isn't the exception I expected. So in any case, I can move on to starting up an application that know works. So we have a mess server-- message server, rather. I've gone ahead and turned off WoW Auto Open in Browser and set the port. I'll also add a couple of rules to our rule model file.

This part I want to emphasize. For editing rules in your application, please add a new file and name it d2w.modelfile like I've named it here. So you'll get this. Edit this file. Do not edit the user.d2wmodelfile, which is edited by the assistant for you. They're two separate files. You should edit the d2wmodelfile with rule editor.

So what I'm going to do is change the location. that my web service application claims it's running on. I have it actually running on port 8888, but through this rule, the service location URL, which is a rule for where, like how we publish the WSDL, we can change where clients will go to invoke our web service. And the reason that I'm going to do that is so I can show you all of the cool XML that goes back and forth through a TCP monitor. Okay, so that's clean build and run. And we'll go back to the assistant. We'll still connect through 8888. We could connect through 7777, but then you'd get a little bit more garbledy-gook. All right. And here we can search for all of our users.

So one of the things that I've already gone and done is change the return type for arrays. You can change how things get serialized out simply by adding a call to the WoW web service registrar. What I've done is make the XML that we return simpler and more Cocoa web services friendly. That's why the client here didn't like it.

So I'm going to add this to one of the download sites after this conference so you can actually try this code out. Basically, we tell it that if we're serializing out an array, should serialize it out with the urtype instead of as a SOAP_ENC_ARRAY. So we can dynamically change how things are serialized and deserialized, as well as which serializers get used. And another thing We can change-- thanks to our dynamic deployment stuff, we can change how the response is encoded as far as the entire SOAP message. One of the things I'm going to do in order to make this more friendly for Cocoa Web Services is add my Cocoa response handler here into the response chain. I do that by... by copying this line into the response bit here. What this handler does, it's a simple piece of code that runs through the SOAP element that we return to the client and makes sure that the return name for each element is just return. So let's stop that and run it again. And I'll bring up my Cocoa application and hide some of this stuff. So here we go.

Okay, so I have a few classes in here that were generated by WSMakeStubs, which is located in slash developer tools, which takes a bunch of WSDL and generates some Objective-C or AppleScript or one other, I believe just CF code, that lets you invoke the web service really easily. You don't have to write as much of this stuff. I'm going to make sure that I use a valid name.

Place, clean. And I'll build and run this. So here our server is running. So we'll hide that. And we'll get rid of this. Basically, what this Cocoa application will do, one of the things it can do is log in to... Log into our web service using just a simple name and password and find a global ID. This global ID, then, you can pass back as a key to other web services invocations. Similarly, you could conceivably return a session ID or something else like that that lets the following operation invocations do something more intelligent, kind of contextual information.

So here's my app. What I'll do is I'll check my email. There's nothing there. That's fine. Let me try sending Carl a message. Let's take a look at the important debugging tool, TCP monitor. TCP monitor debugging. Oh, I've done something very silly and not included--. This in my build target. Hang on.. So we'll give this one more try.

And that definitely seems to have worked. Let me check first. Oh, okay. So here we've gone across, let me check again so you don't miss it, and sent a clear text name and password. Don't do this. and replied with a bunch of messages that are encoded for specifically for Cocoa. You could do this for any other client. Dot net has worked. We could do this for regular Apple script clients as well. Let's see. And if I send myself a message-- can see that we first log in, finding the name of the recipient here.

And getting the global ID. This is an encoding of a global ID, so that we can use it later when we send the actual message. So this is a two-step process for this specific web service. Here you can see we've sent a global ID for the recipient and the sender. And I can check my mail again.

and see that we indeed did get the message. One of the other things that Carl alluded to was session support and how that enables transactions for direct web services and WebObjects web services in general. You'll notice when I check the service panel here, we have a little checkbox for "allows transactions or not." With that enabled, we can go and check any of these and look in the WSDL, there will be three extra operations.

begin and commit and roll back transactions operations. This way, a web service client can explicitly ask for session state to be kept on the server for the remaining transactions. Once they initiate a begin transaction operation, simply begin transaction to the server, we keep the session alive, reply with some session headers in the SOAP message, which the client hangs onto.

Simply forwarding those message headers to the server awakens the correct session for the client. So you can do things like keeping a bunch of changes in the editing context on the server going, keep making changes without committing them to the database until a commit transaction is sent. So that's it. And I think that was all. Oh, as far as extending the frameworks here, how much time do I have?

Extending the framework, you can see we have all the default services and default operations. You can also create your own. You can see you can create a new service and change its name. Okay. as well as creating a new operation for it. We bring up a new operation dialog.

name the operation, and define which entity it works with. All of these changes are saved in the rule system so that simply by invoking a operation by name, WebObjects will automatically know what entity the operation is meant for and whether it should be inserting or deleting or updating new records in the editing context. So we can add a search user operation named have fun, change the parameters and This play with play with any of these settings until we get it just right at which point we might want to actually make some small tweaks into how it's working at that point we can actually freeze the operation this generates real source code. We can name the operation source. And then we go and generate the source for you. for everything that you would need for actually doing what is done by default. And we also generate a static WSDL page that you can edit. Yes, you can always do it.

So we've generated a lot of code, and it does the same thing. Boring. Next, I'd like to simply-- I'd rather just subclass the existing operations and only tweak the little things that I need, rather than having to manage a set of source. If I really needed it, this would be useful, but in my case, I typically just wanna change the return object by one little amount. So instead of freezing an operation, I can create a new operation here, name it a simple subclass, And same settings. And you'll notice that once we froze the previous operation, we can no longer edit any of these arguments and return values. So you have to get it right before you freeze it. You can unfreeze, but you still have to throw out your original source.

When we subclass, you'll see we still get the dynamic system here in order to configure arguments and return types. Now, subclassing involves one little thing. There is a template that ships with WebObjects, and it lives in developer, documentation, WebObjects, web services, templates. I'm going to simply copy that with this cute little script I wrote. I'm going to copy that into developer project builder extras file templates web objects. Just read the directions in the read me here. So now that I've copied that template there, I can go and create a new-- Direct to web service operation subclass. We'll name it.

And you can see now we have something much simpler than this, but it does pretty much the same thing. All you need to do is tell the -- or define your operation to subclass one of our other operation types, search or insert or delete operation. This one is going to be a search service, search operation. And here I can -- print out a little extra debug information.

One of the things that we get when we're invoked, when an operation is invoked, is a set of input part values. These are the values that the client has actually sent to the server. And we'll also have to register this service, this operation, with the rule system. The way we do that is editing, again, the D2W model file, and we'll say, "D2W, when the operation name that's invoked is--.

DAVID J. Say hello. Don't ask me where I come up with these names. I don't know either. then the operation class that should be invoked is my happy happy class. And a very similar rule needs to be used in order to tell the rule system that it is a dynamic operation. Oh, I didn't need to do that. Copy paste is a wonderful thing.

Okay, so operation class name is set. Is operation frozen is set to false. Save, stop and build. And then we can go back to the Assistant, disconnect, wait for the application to warm up again. And then once we've connected, we can start configuring this new operation that you'll see there. So in My Simple Service, we can actually rename this to Say Hello.

And you can see we can still edit the arguments, return types, and which service it's associated with, whereas the frozen one is still just frozen. We'll go ahead and add subject and a recipient as, - input parameters and change these. And the creation date and the sender. So lots of little parameters. Oh, I have to make these public. Another security feature reminding you that you must make these things public before anybody can invoke them.

So we can at least set the subject. We'll probably get an exception saying that we don't have the serializer for the response type. But here you can see on the server side that we did in fact get some input part values that we can futz with before invoking super. So this way we still don't have to do all of the work of actually inserting or searching or deleting or whatever. We can just tune little parameters of the operation to suit our needs. And with that, I'd like to go back to the slides.

That's it, direct web services, web services made easy, based on the Axis and WebObjects support for web services, using EOF so that you don't have to write any of the CRUD code, and using the rule system to define the parameters and the behavior of your application. With that, I'd like to bring Carl back up.

Another demo, but I did that one. There we go. Back, back. Thank you, Ron. So, running a little short on time. That's okay. Let's talk really quick. There are some deployment considerations when you're deploying web services through web objects. He talked a little bit about session support and load balancing. We do support multiple instances of web objects vending web services and then load balancing between them. The key to that, though, is that the load balancing is based on cookie support. The client, we basically send which instance you should be talking to back as an HTTP cookie. So the client has to be able to understand that and vend it back to us properly. Otherwise, the whole transaction session thing breaks down entirely. So that's one thing to keep in mind. The WSDL location, you generally want to simply publish a single WSDL. It's nice that we dynamically generate it, and it means it's easy to change, But it's probably best if you simply put it up on a web server and then reference it directly from there. It probably shouldn't change all that often, because a lot of people do things like generate stubs off of it. So if you change it, you will break the clients.

Finally, we talked about registration. UDDI was designed to be this sort of analog to DNS, or the phone book, where all sorts of web services operations would register in this gigantic directory that was all over the world, and everybody would look up stuff there. So far, it hasn't really caught on.

It's beginning to build a little bit of momentum. It's in the GH2EE 1.4 spec, and so on. But it's still not this giant-- phone book thing that the original authors had intended. In lieu of that, a lot of companies use web services internally, and in order to publish their web services, they either have an internal UDDI server-- there are a number of free UDDI servers out there-- or they do something simple like the web page or something, like the way X methods would do it. Or just word of mouth. You send an email out saying, "Hey, guys, I've published a web service. "The WSDL kit is available at blah."

So web services, in two words, even less than the one sentence, it's Internet RPC. It has lots and lots and lots of acronyms. Hopefully you know a little bit more about them now, but that's OK. The goal for us, of course, was that much of that could be skipped, that we would try to do as much of that as possible for you.

They would like it to be located and registered in a UDDI server, and because we're talking about standards, we're kind of gonna go in that direction. It's described by the WSDL. It's sent as SOAP-encoded XML over HTTP or SMTP, snail mail, carrier pigeon, whatever. Hey, don't knock the carrier pigeons. They were very efficient and cheap. You try laying a T1 line versus getting a bird.

So WebObjects itself, at a very fundamental layer, very basically adds transactions and type support. And that's good. That's helpful. The big thing for us is that we add direct-to-web services. And this is something I really want to stress. Direct-to-web services provides you with automatic, comprehensive, and very easy to configure web services for your entire database. You no longer have to go through and figure out what you need to write. How do I access this?

How do I expose it? You basically point direct web services at your database, bring up the assistant, do a little bit of clicking and pointing and checking and unchecking, and you can expose your entire database. With transaction support, it looks transparent to people. They can say, let's start a transaction.

Add some stuff, modify some things, set up some relationship. When you're done, check if everything's in a good state. If so, commit. If not, roll it back. It's beautiful. I believe, actually, that it's even better than something like Direct-to-Web. When you build something like Direct-to-Web, you're generating a UI. And then you have to tweak the UI so it looks good, so it fits in with your site and everything else like that. With Direct-to-Web services, it's just the information. Your database is exposed directly. It can be used by multiple clients. It can be used by clients you've never heard of in languages you don't know or don't recognize, can't read. It's that easy, and it's something that we would really, really like people to take advantage of. Thank you.