dominoGuru.com

Latest Updates

Loading... Please Wait!

Products & Applications

Showtime
My Blackberry Enterprise Server Push Utility for the Lotus Notes Client, allows you to create Jobs for individual Channel, Message, and Browser Content Pushes, as well as allows you to delete Pushed Channel Icons from defined recipient devices.

Time Tracker
The idea is simple. At the start of your day - upon completion of your first task - create an entry highlighting what you did and whether you feel it was an efficient or inefficient use of your time. Based on several requests, you can also select the priority, apply categories, or even align your time against a project.

For Lotus Notes Client v8.0 and above, you can use the Time Tracker Widget to make this process even easier!

Zephyr
My Configuration-based Rich Text Mail Merge and Emailing Utility, Zephyr allows you to create rich, data-driven emails to support automated workflow - all via Microsoft Word Mail Merge-like architecture. Dear <firstname> allows you to personalize each email message not only to the individual recipient, but also to the individual application workflow event!

xCopy
xCopy is a simple configurable xCopy client for the Lotus Notes client. By creating and defining xCopy Profiles, you can batch process your file backup or remote upload jobs. With the addition of the xCopy sidebar widget, you can easily kick-off these jobs, and modify both the xCopy Profiles and xCopy itself.

Community & Resources

Lotus Technical Information & Education Community

The Lotus Technical Information & Education community is comprised of IBM, business partner, and customer subject matter experts who use product wikis, published articles, white papers, community blogs and the latest in social media to build and share high quality technical content.

OpenNTF.org - Open Source Community for Lotus Notes Domino

OpenNTF is devoted to enabling groups of individuals all over the world to collaborate on IBM Lotus Notes/Domino applications and release them as open source.

developerWorks Lotus : Wikis

Share your deployment experiences and best practices in our wikis and help IBM to create scenarios for successful deployments. Contribute to the community by collaborating on shared content and leverage the shared knowledge from that community.

IBM Lotus Notes Domino REST Web Services via XPage XAgents - Part 1

02/15/2010 06:10:00 AM by Chris Toohey

XPage XAgents: eat your HTTP Request like a cookie! I asked, and you (thankfully) responded that you wanted to hear about XPage XAgents! So here's what I was thinking...

To get us started, you should check out the following Show-and-Tell-Thursday post from Stephan Wissel:

Go on... I'll still be here when you get back, and it's an awesome read. You'll thank me.

...

OK, welcome back!

When I've discussed IBM Lotus Notes Domino XPage Development, I found that the majority of Notes and Domino Developers think of XPages as a simple skin for their existing applications. Sure, it can help you paint feature-rich UIs -- which I'm certain UI development will be the biggest entry point to XPage Development -- but that's like saying Lotus Notes Domino is just an email system!

... see what I did there?? Moving on...

Stephen's example of creating an XPage XAgent is a huge step in the right direction, where we start leveraging the power of SSJS and the JSF to do things that quite frankly just can't be done with IBM Lotus Notes Domino Standard Design Elements.

Like what?, I hear you ask? Well, like RESTful NotesData APIs. Tim and I were trying our damnedest to get RESTful Web Services out of the Domino HTTP Stack... and we found that it failed miserably.

A quick refresher: RESTful Web Services = using GET, POST, PUT, and DELETE Method States to READ, CREATE, UPDATE, and DELETE target resources. In the world of IBM Lotus Notes Domino, this would mean that calling the following:

http://dominoserver/notesdatabase.nsf/view/notesdocument

Via the DELETE Method, should actually delete the target NotesDocument.

Domino - regardless of configuration - consumes the DELETE Method but returns the NotesDocument as if we used the GET Method State.

You can see where this might be an issue, right? Yeah - no RESTful Web Services for Domino, sadly...

But what about for XPages? Specifically, what about for SSJS and the JSF that could be surfaced via XPages?

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
	<xp:this.resources>
		<xp:script src="/lib_api.jss" clientSide="false"></xp:script>
	</xp:this.resources>
	<xp:this.afterRenderResponse><![CDATA[#{javascript:
var cgi = new CGIVariables();
var exCon = facesContext.getExternalContext(); 
var writer = facesContext.getResponseWriter();
var response = exCon.getResponse();
response.setContentType("text/plain");
response.setHeader("Cache-Control", "no-cache");
writer.write(cgi.REQUEST_METHOD);
writer.endDocument();}]]></xp:this.afterRenderResponse>
</xp:view>

The above lib_api.jss contains the Script Library from How to access CGI variables in XPages.

Before we test our proof of concept... we need to make sure that our Domino Server is configured to allow RESTful Methods.

We want to confirm that GET and POST -- which should be enabled by default -- are indeed enabled along with the PUT and DELETE Methods.

Now, using the REST Client of your choice -- I'm using a Firefox add-on aptly named RESTClient -- we'll test our XPage XAgent:

IBM Lotus Notes Domino XPage XAgent consuming a DELETE Method HTTP Request

That's an IBM Lotus Notes Domino XPage XAgent consuming a DELETE Method HTTP Request!

The only issue here is -- quite frankly -- this still isn't REST. Aside from your XPage XAgent not actually doing anything with the DELETE HTTP Request, it's not pointing to a NotesDocument URI.

See, to properly Create, Read, Update or Delete via REST, the URI of the target object you wish to perform said action against needs to more or less be the recipient of your HTTP Request. We got this to work with an XPage XAgent, not with a NotesDocument. So our actual target URL schema should look something like this:

http://domino/dir/db.nsf/view/notesdocument

Call that with a POST, and it should Create a new NotesDocument.

Call that with a GET, and it should Read/Return an existing NotesDocument.

PUT will Update, and DELETE will -- say it with me -- Delete the defined NotesDocument.

(For my next trick, I'll need a Lotus Domino Admin...)

We're going to use Internet Site Documents in combination with Substitution Rules!

For those of you not familiar with Internet Site Documents and in particular Substitution Rules, I'll give you an example.

I use this approach mostly for maintining old/bad permalinks that are no longer permalinks (and all-around Search Engine Optimization) for dominoGuru.com, so it's high-time I put it to good use for an application! It just so happens to work rather brilliantly.

IBM Lotus Notes Domino Internet Site Documents and Substitution Rules for dominoGuru.com

When I first setup the NotesDatabase that runs this site, it was located in the following subdirectory structure:

/dominoguru/home.nsf

A few years ago I moved it to the following subdirectory structure:

/hosting/dg/site.nsf

What you may not know is that -- with an IBM Lotus Notes Domino Internet Site Document Substitution Rule -- the target URL/URI is not redirected (there is no 302 HTTP Header Response issued). What this means, is that you could hit dominoGuru.com via http://www.dominoguru.com/dominoguru/home.nsf/index.html even though it's no longer in that subdirectory... and the HTTP Request URI remains unchanged.

Ya see where I'm going with this?!

Let's add two lines to our XPage XAgent:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
	<xp:this.resources>
		<xp:script src="/lib_api.jss" clientSide="false"></xp:script>
	</xp:this.resources>
	<xp:this.afterRenderResponse><![CDATA[#{javascript:
var cgi = new CGIVariables();
var exCon = facesContext.getExternalContext(); 
var writer = facesContext.getResponseWriter();
var response = exCon.getResponse();
response.setContentType("text/plain");
response.setHeader("Cache-Control", "no-cache");
writer.write(cgi.REQUEST_METHOD);
writer.write(cgi.REQUEST_URI);
writer.write(cgi.QUERY_STRING);
writer.endDocument();}]]></xp:this.afterRenderResponse>
</xp:view>

Now, let's say you create api.example.com as an Internet Site Document for a NotesDatabase Application that you want to REST Web Service-enable. You could easily add the following Substitution Rule to your Internet Site Document:

/api.nsf/* -> /api.nsf/api.xsp

That's it! All of your requests that go to api.nsf will be consumed by your XPage XAgent!

In the next part of this series, we'll actually make our XPage XAgent functional, and create our Method Handler Controller via SSJS -- Stay tuned!

 
Nathan T. FreemanName:Nathan T. FreemanWebsite:http://nathan.lotus911.comComment So once you get the syntactical sugar down for making the HTTP requests to perform CRUD operations, you'll need to figure out how to describe the payload.  May I suggest cracking open this project and porting it to SSJS? http://www.openntf.org/Projects/pmt.nsf/ProjectLookup/Decepticon Bjørn CintraName:Bjørn CintraWebsite:http://blog.isite.noComment

Shameless plug: I use this a lot in our iSite Publisher product, of which an example can be found here: blog.isite.no.
In our case, routing /home.nsf/ -> /home.nsf/index.xsp/* combined with the fact that everything after the /* can be accessed trough exCon.getRequestPathInfo() , means we can get domino URL's that actually looks like this: http://blog.isite.no/2010/02/formula-can-now-return-a-vector-in-freemarker .
And I am, btw, using the "XPage XAgent" trick to build pages using Freemarker as a templating engine. Pretty sweet :)


(not published)




Evaluate this Formula: @LowerCase(@Text("FOO"))