logo

The Case For Using a Web Service Badly

So, how I did I come to be wondering if using Web Services within the same application was wrong yesterday?

Well, let's imagine some scenarios and their "traditional" solutions.

Scenario 1

Problem

Say you want to simply approve/decline a document in a workflow and pass it via email to the next approver, but you know that, for whatever reason, the user won't have Author access to it.

Solution

What I'd tend to do here is create an Agent which accepts the document's ID and the action/status to be performed.

Issues

This is no biggy really, but ideally this would need to be a POST request (we all know GET should only fetch data and not change it, right!). When you POST data to an Agent you need to manually decouple all the name/values manually from within the REQUST_CONTENT field (or REQUEST_CONTENT_001 etc if more than 64k passed!!). This is where it gets a bit messy and tedious.

Scenario 2

Problem

You just want to change the value of field on a document. Ideally you want to be able to specify the field.

Solution

You could always create a HTTP request that posted to a ?SaveDocument URL with the field's name/value pairing as the only parameter passed.

Issues

What if you want to avoid triggering a full save of the document? Maybe because you don't want to run the code in the form's WQS agent, for whatever reason.

Again you find yourself needing to create an(other!) agent. 

Scenario 3

Problem

You want to re-order a set of documents. This is something I've described before and you can see demos of it here.

Solution

To do this I POST a list of the documents and their order to a ?CreateDocument URL. The document (which have SaveOptions field set to "0") has a WQS agent which loops through the mutli-value field which received the list and, for each document, updates its order.

Issues

While this works well it involves the addition of two new design elements to the database just to solve one "simple" task.

What's The Problem?

While the scenarios above aren't exhaustive - just some things that came to mind right now - you should see a common theme appearing?

In all cases all we want to do is perform some action on the server. It doesn't really matter what we want to do. The problem is that for each new action we decide to add we need to create a new design element (if not two). If you end up adding 10 action you could have up to 20 design elements cluttering up (an already cluttered in some cases) database.

What's The Solution?

For ages now I've been thinking of doing away with all these separate agents by writing a single agent that can perform any action needed. You can call if via GET or POST and you pass the action it is to perform using the URL. So the URL might be:

/database.nsf/actions?OpenAgent&action=approve

The document ID and other data would then be posted to it.

Inside the agent would be a big "Select Case (Action)" which examines the URL and performs the right code block depending on what it's asked to do.

Still all quite messy but at least all the backend "business logic" is in one place. I haven't got as far as creating it yet, as I'm knee-deep in Flex at the moment and that allows me to use Web Services, which, potentially, make it even simpler.

Where Do Web Services Come In?

In Flex there is support for using Web Services. You define the Web Service and when the app loads it fetches the WSDL code and you then have all the backend methods/actions available.

Using a Web Service you can keep all the logic for the various actions you might need to perform within a database in one place.

Better yet it defines what parameters a method needs to accepts and even makes them "typed" for us. We don't need to decode and decouple the data posted. The Web Service does this for us. In our backend code we can just start working directly with the data parts as we'd expect.

Even better still the Web Service can return the result of the action to Flex as a String, Boolean etc and Flex works with it without any type casting/checking needed.

In Summary

We're not talking about replacing the Standard Domino URLs here, such as ?SaveDocument etc. If you're creating/editing a document with a form then use the standard approach.

What I'm talking about is a simple way to code the actions we often need to bolt on to make an application/database do anything useful.

Yesterday's discussion didn't feel like there was a conclusion as to whether consuming a Web Service from the same server and the same application was "wrong". The more I think about it though the less I care. I'm a Domino developer. I've spent the last 10 years using any method I can to get things to work.

Eight years ago I described a hack that uses the Navigator design element to get a Form to act as a database's homepage. I still use it to this day. Who uses a Page to store CSS still, even though there's a StyleSheet design element specifically for this? I know I do.

As Domino developers we're using to the by-whatever-means approach to making things do what we want. I don't see why I should stop now.

Tomorrow?

Tomorrow I'll show you the code on both sides of this --- the Flex code that consumes the Web Service and the LotusScript that makes up the backend logic. Hopefully then you'll agree that what I am doing makes not only sense but our jobs easier, which has to be a good thing, right?

Comments

  1. "Who uses a Page to store CSS still, even though there's a StyleSheet design element specifically for this? I know I do."

    Well when they make the Style Sheet entries dynamic so that I can embed computed text, I'll switch. But until then I'll stick with using a page. After all, sometimes the locations of graphics change across databases. One page, one profile document, loads of uses.

    Yes Devs use any method to make things work. And you know what? Over the past few years we've done it so many times that it's hard to get out of the rut. But what if the rut is actually better than the other options?

    I am extremely wary about having a one-size-fits-all kind of method. Because the biggest headache with such things is security. Once people start poking around in the code (and trust me, they do) you can end up with a whole slew of problems. A single agent could be a real can of worms.

    Whilst it certainly may be ok in a corporte environment, having such code out on the 'net is a recipe for disaster if it's not written extremely carefully.

  2. Unfortunately I missed the debate yesterday, but to say that using a web service from the same application / server is wrong, is somewhat outside the spirit of web services.

    Web services are meant to be flexible, lightweight, cross-platform, and easy to use. For most of our application development, my team has almost done away with the entire post-get page cycle and use web services almost exclusively for dynamic content.

    Just like you said, to save a single piece of content should not require me to go through the entire post / bind / evaluate / execute process of a page's lifecycle. Why not just use the small, lightweight approach which translates to better performance?

    This does add a bit more effort to the design process, but the performance increases are pretty significant, and it also allows team members who are not web savvy, to contribute to a project since web services resemble any other method call.

  3. Hi Jake,

    I'm currently building a Flex app with Domino as the backend. Due to the cost of Domino hosting, I'm now thinking of moving this to a Rails backend. To see how this would work I got the "Flexible Rails" book by Peter Armstrong. In that there is a good discussion of using a Restful approach to connecting Flex to Rails which i would highly recommend. Although this is about Rails as a backend, the topics on Flex could be appropriate to most platforms. It's definitely given me some thoughts about integrating Flex with Domino using a Restful approach. Unfortunately, since I'm moving platform I wont be looking into this any time soon.

    So in short, if you've not already got it, I'd highly recommend "Flexible Rails" (http://www.manning.com/armstrong/), just for the Flex stuff if nothing else. It doesn't really cover Flex basics, but it does cover structuring a Flex app, refactoring Flex code and goes onto use the Cairngorm framework (which I think is a bit overkill for what I'm working on, but useful to know what it is).

    Cheers

    Alan

    • avatar
    • Michael Bourak
    • Thu 2 Apr 2009 10:12 AM

    let's not forget that Domino Web Services are not re-entrant : you could have a deadlock situation if for exemple a an agent calls a webservices on the same domino server under "heavy" load...

    @Jeff : I tend to think that using web services on the same server is too much work (for you, for the server ...). If you really want to be able to split part of applications on different servers, why not use a simple REST api that perform much faster than webservices ?

  4. For Scenario 1.. Create a reusable class for dealing with requests. If you (not you as in Jake, but you as in the reader) don't have something like this already, you only have yourself to blame..

    <blatant threadjacking>

    Example from my own HttpRequest-class.

    http://dontpanic82.blogspot.com/2008/09/httprequest-class-updated-get-cookie.html

    Dim request As New HttpRequest()

    'The request-class autodetects if

    'the request is a POST or GET request

    Dim somePOSTParameter As String

    somePOSTParameter = request.parameter( "somePOSTParameter" )

    'In need of a cookie?

    Dim someCookie As String

    someCookie = request.cookie( "someCookie" )

    'Want to inspect all headers/etc?

    Call printHtmlReport()

    </blatant threadjacking>

    Sorry for the threadjack, but I just wanted to show how easy it can be.

    *runs and hides*

    • avatar
    • noon
    • Thu 2 Apr 2009 02:45 PM

    By using the (Domino) web services you have a standard API to modify / access your database data. And when you have a standard access, other applications may consume your web service as well by exporting & sharing the WSDL of your web service. WebServices should have been in the Domino long time ago.

    A good tool to your toolbox is the "Stubby" (Axis stub generator) which you can download from http://www.openntf.org/Projects/pmt.nsf/ProjectLookup/Stubby

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Thu 2 Apr 2009

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content