On Wed, Jul 29, 2009 at 10:20 PM, Paul Mietz
Egli<paul.e...@fullpower.com> wrote:
> Interesting idea!  My initial implementation fetches the data from the table
> in the custom ResourceResolver and place it in a table-specific Resource
> implementation instance, but it sounds like you're suggesting instead to
> place the means of fetching the data into the Resource and let the rendering
> servlet actually do the fetching.  By deferring the actual fetch, I can let
> the rendering servlet inspect the request for filters and query parameters
> and have it fetch based on those params.
>
> For example, let's say I want to map a User table to /prefix/users.  For
> JsonRestStore to work, calling /prefix/users should return a JSON array of
> user objects and calling /prefix/users/id should return a single JSON object
> representing the user with the specified ID.  In addition, requesting
> /prefix/users?active=true should return a list of users in an "active" state
> (as defined by my application).  I would create a UserResourceProvider class
> that inspects the path to determine whether a list of users or a single user
> has been requested.  For a list of users, it would return a UserResource
> with a type of "myapp/user-list".  For a single user, it would return a
> UserResource of type "myapp/user" with a resource metadata key set to the
> user ID parsed off the path.  The UserResource object would implement
> adaptTo(MyAppDAO.class) where MyAppDAO is the data access object used to
> fetch User objects.
>
> I'm using Groovy scripts for rendering in this application, so to render a
> GET request for the user list I would create
> /apps/myapp/user-list/GET.groovy.  Inside that script, I can use the
> predefined request variable to look at the Content-Range header and any
> request parameters, then call my DAO that was adapted from the resource:
>
>  // pseudocode
>  def active = request.getParameter("active")
>  def dao = resource.adaptTo(MyAppDAO.class)
>
>  def users = []
>  if (active != null) {
>    users = dao.findUsersByActiveState(active)
>  }
>  else {
>    users = dao.allUsers()
>  }
>
>  // now render each user as JSON...
>
> I would also need to implement POST.groovy to fully support the
> JsonRestStore, but that is trivial since I have access to the MyAppDAO
> object in the script.  The scripts for GET, POST, PUT, and DELETE for a
> "myapp/user" object would get the MyAppDAO object the same way, but in
> addition would pull the user ID out of the resource metadata to determine
> which user to act upon.

Sounds good!

> My only concern with this setup is that I feel like I'm not leveraging all
> of the existing capabilities of Sling.  For example, instead of rendering
> JSON myself, it would be nice for my Resource subclass supported
> adaptTo(ValueMap.class) and use the "json" selector.

The existing json rendering provided by Sling is tied to JCR items
anyway, it's not generically implemented based on Resources and
ValueMaps. So that you have to do it yourself is actually expected.
Implementation is greatly simplified because of the JSONWriter that is
available to build proper json based on your data.


> Also, I expect that I
> would be able to save and delete instances of objects if I supported
> adaptTo(PersistableValueMap.class), though I haven't tried this yet.

Right. Supporting (Persistable)ValueMap pays off when you have generic
servlets or scripts that should be able to handle both JCR and
Database-based resources.

Regards,
Alex

-- 
Alexander Klimetschek
alexander.klimetsc...@day.com

Reply via email to