On 2010-07-07 15.19, Marc Grue wrote:
In Streamflow, the DCI process flow seems to be "top-down" where
dci.api.CommandQueryRestlet has the central role of handling the whole life
cycle from all requests through URL mapping, Context/Interactions
mapping/processing, Template choosing/merging/rendering to final redirection
of response to the browser. I can see great benefits of minimal duplication
of trivial plumbing code with this generic approach.
Yes, that's the idea. There's so much web plumbing code that is just
gone with the approach we have now. One issue, however, is that our
current context code actually mixes the web layer (=know about links,
mediatypes, etc.) with the application layer (=know about how to get
objects and invoke interactions). This makes the code quite confused, to
be honest. Maybe we should split them into two separate parts, but then
I'm afraid we're into code duplication land again. If there was a good
way to separate these two, without a whole lot of duplication, that
would be nice.
For my own needs I want to use Wicket for a more "down-up" approach where I
have a lot of customized (no-template friendly) Wicket Pages/Panels that
call/compose each other. That, I presume, moves the responsibility of
calling the Context away from a central place in the application layer (like
CommandQueryRestlet) to the Wicket java Pages in the Web layer, right?
Seems so, yes.
Is
the difference wether or not the Context layer defines what part of the
domain (through Context) the Web layer can access in each particular page?
With the Streamflow approach I would need to change the Context layer (the
link building) if I wanted some link in my Web layer pointing to some other
part of the domain, or?
As above, the current Streamflow context code does two things: the web
and application layer. So yes, we have to change it if our web layout
changes.
Could one compare the Context to the old Controller (in MVC) - at least with
regards to being an access point to the domain? Or is the Wicket Page in a
way the controller - a responsability distributor (still knowing only the
domain from the "outside" through the Context)? I guess some old terms don't
map to DCI...
You can compare the Context either to Action classes (in e.g.
WebWork/Struts), which in simple cases uses the domain model directly.
You could also compare it to stateless session facades in the
application layer of EJB apps. In the session format you'd have facades
with methods like:
facade.doStuff(id1,id2,id3,param1,param2)
which now becomes
context<id1,id2,id3>.doStuff(param1,param2)
i.e. the conversion from id strings to objects, and binding them into a
context, is not done in the interactions anymore (doStuff). This is a
lot of boilerplate code that goes away, which is nice. You are also
decoupling *how* those objects are retrieved from their usage in the
interaction.
Below I have compared the process flow of Streamflow to how I imagine I can
do in Wicket. I'm interested in hearing what pitfalls you see in my way of
calling the Context layer:
Streamflow
CommandQueryRestlet.handle(Request, Response) runs the show:
- Restlet handles GET/POST
- URL segments extracted from Request
- newUnitOfWork()
- DCI Context initiated, setting app root subContexts
- getInteractions() maps segments through the SubContext/Interactions chain
- Invoking found interaction (a context method corresponding to last segment
in the URL)
- Responsewriter merges result from interaction invocation with view
template and renders result to response
- Links with URLs to new pages are created in Contexts (URL composition
stays out of Web layer)
- uow.complete()
CommandQueryRestlet done
Something like that, yeah.
Wicket
Wicket java Page runs the show:
- Wicket handles GET/POST
- RequestCycleProcessor.onBeginRequest(): newUnitOfWork() // should uow
start here or around each context call?
- Wicket Page form (or any other component) calls the Context for data:
- UserDTO userDTO = getContext().user("123"); // retrieval through
interactions chain
- Wicket CustomForm("form", (IModel) userDTO); // some conversion of userDTO
to a Wicket IModel
- Form/IModel is shown, edited and validated
- UserDTO userChangedDTO = (UserDTO) getModel(); // IModel cast back to a
UserDTO
- onSubmit(): getContext().user("123").update(userChangedDTO);
- Some redirect to results page
- RequestCycleProcessor.onEndRequest(): uow.complete() // or around each
context call
- Links with URLs to new pages are added/defined by current Wicket Page (in
Web layer)
Wicket Page done
Other queries/commands examples:
userOrganizations = getContext().user("432").organizations().index();
organizationUsers = getContext().organization("117").users().index();
getContext().user("432").organizations().create(organizationDTO);
getContext().organization("117").users().create(userDTO);
etc.
Am I on a viable path with this approach? Mis-/non-understandings,
pros/cons?
In the above you don't have any separation between building up a context
and calling interactions, and you don't really have any interactions at
all actually (you call the domain directly). Which you are not doing
either, since you're calling the DTO, not the domain. I'm having a
really hard time mapping the above to DCI at all, actually.
What are your interactions?
What are your roles?
It seems as though Phil's solution to detache the session in
http://old.nabble.com/Web-framework-ts24548505.html#a24555233
supposes to deal with EntityComposites (entities) extending EntityIModel
from within the Wicket layer. But isn't it better to receive DTO's from the
Context, change them and send them back to the Context for persistence (not
exposing the domain objects)? Or should I clone immutable ValueObjects?
Sorry, if I'm mixing up the terms.
I'm not sure. I have a hard time trying to imagine what it would look
like, without getting down and dirty myself with Wicket. And, from what
I've seen, Wicket is not a framework I would choose for doing webapps.
So far, as I said before, we are happy with the JS+CSS+HTML+REST
approach, where the serverside is strictly REST, and all the component
handling is done in JS. But we are early on, so might get bitten bigtime
later on. Time will tell.
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev