• Jul 3, 2014

As this post's title implies, I'm considering making this a series on XPages anti-patterns, but no promises there.

In any event, this is a topic that's been stewing in my brain for a little while: my antipathy towards the session scope in XPages. Now, don't get me wrong: other than the "not reset on logout" thing that may be fixed by now, I have no technical qualms with sessionScope; it does what it says on the tin. However, I've often found that many people use it very frequently, whereas I have found fewer and fewer uses over time where it is appropriate.

To set the stage, I use the various scopes in roughly this order by descending frequency:

  1. viewScope
  2. applicationScope
  3. flashScope
  4. requestScope
  5. sessionScope

The main things that I use sessionScope for are things that truly make sense only for the current browser session, such as the current date range to view in a log-viewing app. Other than that, I generally don't use it for:

Caches

Though it's not wrong, per se, to use the session for this, I've found it better overall to use the applicationScope, either directly (applicationScope.put("someCachedValue", whatever)) or by putting a Map keyed by username in there. The latter gets the same user-specific cache benefits of sessionScope (and more reliable, too, due to the potential for switched authentication) while also having the benefit of keeping the cache if the user logs in from another device. This is particularly potent with Anonymous. This is not a hard-and-fast rule, though - you may decide otherwise for cache-size or other reasons.

Primary Navigation or Context

Unlike the previous one, this is a hard-and-fast rule: do not use sessionScope for important page context. The worst would be something like having an "open document" button that puts the desired document UNID (or, worse, note ID) in sessionScope and then navigates to the page. Never do this! Though XPage URLs are a continuing problem, they're still the correct place for target-document information. The rule of thumb is that you should be able to copy the URL any time, paste it into another browser, and be in basically the same place.

Secondary Context

By this I mean things like the active linksbar category for the current page. I've seen things like having a navigation bar link that sends the user to a certain page while also setting a sessionScope variable to indicate the active menu bar. This is a huge problem for a number of reasons: it's a maintenance nightmare (having to code every link to do this), it's just asking for bugs (links setting the wrong or no value), and it breaks completely when the user bookmarks the page or comes back after session expiration. It's technically better than the previous crime, but only barely. The correct place for this information is handled somewhere in the page structure, though the specifics get murky. I generally take a page from the Extension Library example DB and use a "navigationPath" properly on my layout control to define a slash-delimited hierarchy of navigation context.

Page-to-Page Context

I'm thinking of things like a task-tracking system where you're looking at a Client document and want to add a Task to them, providing the Client document's ID for context. This is another area where the URL is the correct choice: ending up with a URL like "/task.xsp?clientId=whatever" makes the intent ("create a new task for client with ID 'whatever'") clear and stable across visits.


Overall, I think of sessionScope as the Petyr Baelish of XPage features: there are some cases where you have to deal with it, but you should generally consider it extremely unreliable and untrustworthy.

Jul 4, 2014
Sven Hasselbach

I often see this when a fresh developer starts to create a web application: Sooner or later, the solution for the most problems is to store everything in the sessionScope (or the matching counterpart of the used platform), and then having a lot of trouble to fix all issues because of this quick solution.

That's why I always tell them: "The SessionScope is evil!" (which is more a recommendation, not a rule).

 

Jul 4, 2014
Mark Leusink

So where would you store user specific information? Like his email address or name. In a Map in the applicationScope?

Jul 4, 2014
Jesse Gallagher

It'd depend on why I'm storing it. If it's a cache of data stored in documents somewhere, I'd go the Map-in-app-scope route (or a bean that does the keying of the Map internally). If it's like a "shopping cart" scenario where the user entered some temporary contact information but it hasn't yet been saved while they're browsing other pages, then sessionScope would make more sense. That latter case comes up pretty infrequently, though.

Jul 6, 2014
Paul Withers

I tend to store user data in userScope in OpenNTF Domino API. It's basically an applicationScope Map where the key is the person's username.

There's also serverScope in OpenNTF Domino API.

Post New Comment