RAGE: Letting The Beast Out (aka An Introduction To Relative Action Group Execution)

Posted January 1, 2007 at 11:34 PM by Ben Nadel

Tags: ColdFusion

I have this idea in my head that I have started to call Relative Action Group Execution or RAGE. The way I see web applications, there are two main tasks that need to be accomplished:

  1. Figuring out what needs to be done.
  2. Figuring out how to do what needs to be done.

For example, in FuseBox, the fuse action would determine what needs to be done (user.list, product.edit) while the circuits/fuses, the MVC framework, or whatever framework you are running, determines the HOW of what needs to be done. RAGE is a twist on the first part, the figuring out of what needs to be done.

Before I get into Relative Action Group Execution, let me just touch upon the problems I have with other fuse-action style notations. But I don't want to pick on FuseBox specifically, so I will just refer to a generic "action variable" that houses some sort of defining value for the system. If you think of a web application like it is a map then the action variable would be the coordinates of a particular action to execute. So, if your action variable was something like "user.editAddress" you would know that you are editing the address of a user.

This is good, but in my head, this is very incomplete as far as coordinates go. If anything, this provides ONLY information About coordinates, not the coordinates themselves. Meaning, yeah, we're editing a user's address, but what user? What address? To make up for this short coming, frameworks will add other defining values to the coordinates such as a user ID and address ID. Now, the coordinates for the above action require an action variable, a user ID, and an address ID.

That's THREE pieces of information required just to define what action is going to take place. And what happens if the action is more specific? What happens if we have a system where we are editing the emergency contact's address associated with a user's contacts? What would that even look like?

user.editContractEmergencyContactAddress??? How many IDs would need to be passed around? Even with something like nested fuse actions (of which I know very little) would this even get any better? user.contract.editContactAddress. Is that better? Does that limit the amount of information needed to define an action?

The problem with most action variables is that the action is, for some reason, separated from the item upon which it acts. Relative Action Group Execution, or RAGE, merges these two required sets of data together into one easy-to-use action variable. So, for the above example where a generic action query string might look like:

action=user.edit&userID=34

... the RAGE query string would look like:

user:34.edit

Notice that this is all one variable within the query string.

The RAGE action variable is composed of chained action groups. A group consists of an item and an optional key separated by a colon (:). Each chained action group is separated by a period (.). Going back to the crazy example above that was:

user.editContractEmergencyContactAddress

The RAGE'ing version of this might look something like this:

user:34.contracts:3.contact:1.address:1.edit

To read this, it would state that we are editing the address of ID (1) that is related to the contact of ID (1) that is related to the contract of ID (3) that is related to the user of ID (34). While this might sounds like a mouthful, it actually makes life much more simple; no more passing around multiple IDs in different variables. No more worrying about what values are called (id vs. userID) - everything is in one place that doesn't even depend on a name.

Relative Action Groups

The idea behind relative action groups is that you don't really need to know where you are in the system, you just need to know who your relatives are. Take, for example, the list of addresses; you shouldn't have to care where you are in the application in any kind of absolute way, you only need to know where you are relative to you nearest relative action group: listing user addresses, listing company addresses, listing "places we made out" addresses. I am not explaining this very well but trust me, this is some good stuff. By making all navigation relative, you tremendously limit the amount of information that you need to keep track of.

So that's my quick little introduction to RAGE (Related Action Group Execution). It's what I have been developing as a navigational system and so far, it is kicking some butt. It's just too easy to use. I am hoping to show some code about this very soon including some ColdFusion components that will parse this out into a linked list of action objects (CFCs).



Reader Comments

Jan 2, 2007 at 4:53 AM // reply »
111 Comments

Hi Ben,

Very interesting approach (although seriously, RAGE?! - you need to get back to the gym before you start hurting people :->).

The nice thing about this approach is that it is keeping some very useful state information in terms of how you got there (you are actually editing Address 43, but we now know what contract and user you edited to get to that address - obviously depending on your admin schema you might also have just ended up editing an address WITHOUT going via user and contract.

You might (or might not!) want to generalize the format to support any primary key (e.g. User:test@test.com.edit for cases that require that) which would make it similar to a REST inspired admin interface I was considering (http://www.pbell.com/index.cfm/2006/11/15/A-RESTlike-Administrative-API) but with the ability to store multiple object IDs for composed objects. Hmmm, definitely worth pondering!


Jan 2, 2007 at 8:32 AM // reply »
11,246 Comments

Pete,

I like your post on the REST type interface. I have to say I am very new to REST in general. In fact, when I wired up my first web service (Amazon) it was the first time I even looked up what REST meant :)

I thought about having more general identifiers, and in fact, it has gotten me in a corner once or twice, but I love the numeric ID. It just makes me feel warm and fuzzy inside. Plus, like 99% of my stuff comes out of a database so the ID is mostly numeric. Of course, just as in your example of the email address, its gets hairy when you need to get something without a numeric ID.... but hey, I am still fleshing it out.

What I am really liking about this is the whole "relative" part of the it. The action variable actually gets parsed into a an action group stack that can have circular linking because each module simply pops off a stack item and checks what it is supposed to do with it (which might be passing control back up to the parent module). It's not the easiest to explain, so hopefully I will get some code posted up in the next day or so.

Of course, I have very little experience in Frameworks of any kind (mine or others) so this might all end in a horrible failure... but aren't the most horrible failures the best to learn from :)


Jan 2, 2007 at 8:49 AM // reply »
111 Comments

I think it is a really interesting approach and look forward to seeing how it turns out :->


Jan 2, 2007 at 11:32 AM // reply »
39 Comments

Ben,

Interesting post, coming from a non-framework/non-OO person (talking about me, not you). Actually I do think I use OO principles, but thus far I've avoided the frameworks because I like to have complete control over my apps, and I feel that frameworks too much control away from the developer.

However, I've been in a lot of debates over the last year where I felt like I didn't really know what I was talking about, so I'm planning on using Fusebox in a small community project I'm planning right now. If nothing else, I'll be able to point to that project as my experience with frameworks. But I suspect I'll actually be converted to the framework crowd, once I get my hands dirty.


Jan 2, 2007 at 11:46 AM // reply »
11,246 Comments

Jacob,

Yeah, I am not a huge framework person, but I also feel that I do use some OOP stuff - it's just not the OOP that is involved with MVC and all that jazz. I want to use what's good... i just have not been able to wrap my head around all that stuff yet.

I think / hope 2007 is my year to blossom.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
May 23, 2013 at 11:06 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Are you talking about As Number: YES As String: YES As Java: YES? If so, that's with 3 different ways of referencing the constant 1, not users.id[1]. Query object references(*) are what seem ... read »
May 23, 2013 at 9:55 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Dan, According to the CF Admin, I'm running Java "1.6.0_45". As far as the DB column, in the database it's an INT. I'll see if I can dig into what CF sees it as. @WebManWalking, But h ... read »
May 23, 2013 at 9:49 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, I think the problem is that we're used to loose typing in ColdFusion, like JavaScript. If a value is a number but it's needed in an expression to be a string, noooo problem. I've encountered ... read »
May 23, 2013 at 9:47 AM
ColdFusion QueryAppend( qOne, qTwo )
You rock! Thank you, thank you, thank you!!! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools