目次

Version 1, last updated by dpp at Nov 28 06:47 UTC

Lift provides general purpose abstractions on top of the HTTP request/response cycle at various different levels of HTTP and HTML.

At the core level, Lift can provide simple REST services by pattern matching the incoming request and generating a response.  Lift's RestHelper allows you to easily abstract HTTP request processing:

 serve {
case Req("api" :: "static" :: _, "xml", GetRequest) => <b>Static</b>
case Req("api" :: "static" :: _, "json", GetRequest) => JString("Static")
}

You can choose to associate a RestHelper with a container session:

LiftRules.dispatch.append(MyRestHandler)

Alternatively, you can respond to HTTP requests without associating the request with a container session:

LiftRules.statelessDispatch.append(MyRestHandler)

Lift also has a full HTML rendering pipeline which loads a view, processes the view by looking for snippet tags, and invoking the snippets.  Historically, Lift's HTML rendering pipeline has required a container session and the information that was stored in the session was non-serializable, thus sessions could not migrate across address spaces.

Lift 2.2-M1 introduces support for stateless requests that span both the dispatch and HTML pipeline request handling in Lift.  Specifically, you can mark a request as stateless in two ways:

  • Registering a path as stateless:
    LiftRules.statelessTest.append {
      case "my_requests" :: _ => true
      case "my_apis" :: _ => true
    }
    Which will designate all requests /my_requests/* and /my_apis/* as stateless requests.
  • Put Loc.Stateless in the parameters of a SiteMap Loc.
In both cases, the request will be marked stateless which has the following characteristics:
  • If there is an existing container session, it will be accessible in read-only mode.  This means that all SessionVars will be visible.
  • If there is no existing container session, an ephemeral session (visible to Lift, but not the container) will be created that has a lifespan of the current request.
  • The request will be handled normally with views loaded, snippets executed, etc.
  • If any snippet or other code attempts to change state in the session, an exception will be thrown.  The following are changes in state:
    • Any attempt to write to a SessionVar.  Touching an unitialized SessionVar will cause the SessionVar to calculate its default value.  If the session is a container-related session, the default value will be stored in the session.  If the session is ephemeral, the default value of the SessionVar will be available for the duration of the request, but will be discarded at the end of the request.
    • Any attempt to write to the session's function table (the association between a GUID delivered to the browser and a server-side function).
    • Any attempt to create or display a CometActor.
  • In development and test mode, the exception will result in the display of an error <div> in the location on the screen where the snippet content would be displayed.  In all other modes, the exception will be logged and the snippet will not be displayed, but the page will continue to render.
  • Forms and Ajax built with Lift's SHtml helper will fail in stateless mode.  However, you can still build forms and do ajax calls "the old fashioned way" in stateless mode.  This means you can build search forms, access REST URLs via Ajax and do most anything that you're used to doing in other frameworks from Lift in stateless mode.
Use cases for stateless pages include:
  • Marking content pages as stateless so web crawlers do not generate many sessions as they crawl across the content pages.  Examples of content pages include Foursquare's venue pages.
  • Serving CMS-style sites in stateless mode because the delivery of content has nothing to do with a particular user's session, although the "editor" parts of the site may be stateful to allow users to log in and modify content.