#167 Aspects and late binding of relationships

brian Thu 27 Dec 2007

The problem I'm currently struggling with right now is how to glue everything together into a cohesive whole. We want to have independently composable mini-apps like admin screens, a blog engine, an issue engine, database plugins, etc. Then we have functionality that cross-cuts these components like visualization and security. Specifically the issues to solve in the short term include:

  1. how to setup the Resource namespace
  2. how to map Resources to web "views"
  3. how to apply web "chrome" across any view
  4. how to search file exts when resolving a Uri: /test, /test.fan, /test.html
  5. how to map a directory to a "view": index.fan, index.html
  6. how to setup security ACLs

The core abstraction here is how do we create late binding relationships? On one hand we want a registry like solution based on the pods installed - for example what web::Widget should be used to visualize a sys::DateTime? From experience we know this is quite powerful, but doesn't provide quite enough flexibility. Because sometimes we want to establish these relationships on a per-application basis - for example given a Uri or Resource what HTML chrome should be used?

I originally started thinking about these problems from a web setup perspective, but in reality the core abstraction is much more fundamental - it should probably be a sys thing. I don't have quite concrete thoughts, but I'm thinking of these things as "Aspects" because the cross cutting nature is kind of like Aspect-Oriented programming. I'm also thinking of a hybrid model that works off a static registry of installed pods, but also flexible enough for customization on a per app basis. For the dynamic piece I've thinking of matching Uris to aspects via regular expressions - kind of like RoR or Django URL routing, but at a lower level of abstraction.

Then once we have a solid "aspect binding infrastructure", we can use that for all these problems:

  • Bind widget aspects to resources and their target objects
  • Bind chrome aspects to resources and/or URI paths
  • Bind resolution rules like ext path to URI paths
  • Bind security aspects to resources and/or URI paths

It seems like the right path to follow - I'm just not sure of the actual details.

brian Fri 28 Dec 2007

Brainstorming notes on this topic:

Big discussion around whether this is Obj level or Resource level functionality. I think we finally all agreed that Fan is based on the notion of wrapping Objs with Resources, so that the Resource can provide context. So we need embrace this approach, and focus on making it easy to wrap things. Because the Resource will be providing context and additional functionality we agreed to make aspects part of the Resource API, not a generic Obj hook. The user side API then looks like this:

class Resource
{
  Obj aspect(Type of)
  Obj[] aspects(Type of := Obj.type)
}

chrome := r.aspect(Page.type)
editor := r.aspects(Widget.type).first
acl    := r.aspects(SecuritySettings.type).first

The flip side of the API is how to plugin "aspect indices" which can establish (or un-establish) aspect relationships. To keep things simple and open ended we discussed a simple API to register handler functions:

class Sys
{
  |Resource r, Obj[] a| aspectHandlers()
  Void addAspectHandler(|Resource r, Obj[] a| f)
  Void removeAspectHandler(|Resource r, Obj[] a| f)
}

Aspect handlers are functions that take a resource and manipulate a list of aspect objs: add to the list, reorder the list, or remove aspects from the list.

We discussed two specific aspect handlers:

  • pod database: all the statically defined aspects defined by types and facets
  • uri map: maps uri by regex to aspects

Login or Signup to reply.