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 has known transcription errors. We are working on an improved version.
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 Karl Hsu. I work in WebObjects 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-Saang. He's the friendly Jamaican-Chinese guy. So we have to have the obligatory what you will learn in this session slide because... 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 WebObjects 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.
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.
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? Can I-- 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 WebObjects 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. 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.
So, problems 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--it means that if they decide to change the look of the site, if they say, "You know what? We're gonna do something nice. We're gonna put an ad here. We're gonna move this search field around," or something like that, you're totally bored, right? And sites change all the time. Part of the point is that, you know, the display is fluid.
It also means that it doesn't dictate any sort of display or usage. You can expose the information, 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-- as 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 know, 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, 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.
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 doesn't - 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.
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. So now the client sends a SOAP request. The server gets it as XML. In WebObjects, we unmarshall 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 Axis for its engine to do web services. It's 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 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 the 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 have a - and store server-specific web services. Karl Hsu, Ron Lue-Sang 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 going to 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.
[Transcript missing]
Text Editing, Syntax Coloring, and Text Editing. 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, you know, it's doable.
Okay. The client is going to be a little bit simple. What the client is going to do is it's just going to be-- a front end is going to be a WebObjects application with a text field. You're going to add in, type in a string, hit Enter, and as a response, we're going to 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.
[Transcript missing]
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, The only way to 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 marshaling, 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 Lu-Saeng. He's our Jamaican-Chinese WebObjects Engineering Cowboy.
Man, I hao ma. 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, Karl. Now that Karl has 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. So let's see. Actually, let's go to black first.
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. They should really be-- 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-to-web services, we've extended that and added to it the access and WebObjects 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 Access, 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
[Transcript missing]
So Karl's already told you about Axis, 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 Axis 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. Can 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.
[Transcript missing]
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 WSDL 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'll be updated in the rule system there. So now we can look for all users with a 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 passkey, 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 passkey set yet.
So if we don't want to see these values in our client, or especially if our client is in a WebObjects application, we can go ahead and turn on returning SOAP 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 here. 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, OK. 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. It will dynamically figure out what parameters you set as input and output parameters and merge those into a WSDL for your service. Let's say hello to Karl from me. Wait for it, Karl. Okay. 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...
[Transcript missing]
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.
[Transcript missing]
[Transcript missing]
Connect. We'll still connect through 8.8.8.8. We could connect through 7.7.7.7, 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, it should serialize it out with the UR type instead of as SOAP_ENC_ARRAY. So we can dynamically change how things are serialized and deserialized, as well as which serializers get used.
And another thing... 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.
[Transcript missing]
Okay, so I have a few classes in here that were generated by WSMakeStubs, which is located in /developertools, 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.
[Transcript missing]
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 Karl 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, OK. 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 specifically for Cocoa. You could do this for any other client. Dotnet has worked. We could do this for regular AppleScript clients as well. And if I send myself a message-- We 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 Karl 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, sending 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? 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.
As well as creating a new operation for it. We bring up a new operation dialogue. 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 an 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... Let's 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. We also generate a static WSDL page that you can edit.
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 want to 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, WebObjects. Just read the directions in the readme here.
So now that I've copied that template there, I can go and create a new-- Direct-to-Web Service Operations 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.
[Transcript missing]
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, When the operation name that's invoked is... 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.
[Transcript missing]
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 Access 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 Karl 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 WebObjects. He talked about, a little bit, about session support and load balancing. We do support multiple instances of WebObjects 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 client.
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-- and 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 XMethods 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 okay. The goal for us, of course, was that, you know, 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 going to 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-to-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 working. 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.