aesteve / nubes

Annotation layer on top of Vert.x 3
Apache License 2.0
120 stars 35 forks source link

View support should change to be same as JSON marshalling result, with view annotation #49

Closed apatrida closed 8 years ago

apatrida commented 9 years ago

Having views add to a data bag isn't allowing using concrete view objects at the top level. And why not just make it identical to how you would do JSON/XML marshalling for a REST call. You return an object, and if there is a @View("viewname") annotation it hands the returned object to the view as the model.

Then you can have one method which can have a view when accepts is set to html, and not run the view when they ask for JSON from the same method.

@View("viewname", "contenttype") says when the view is triggered. Maybe something else that allows the JSON or XML marshalling to trigger such as @ContentType("application/json") on the method. could be combined:

@ContentType("text/xhtml", view="myviewnmae")
@ContentType("application/json")
public SomeDataClass myMethod() {...}

sets two content types, a view for one of them, and just straight marshalling to JSON for the other.

something along these lines...

or internal framework has a debug mode that allows you to &format=json on any view method to get the model instead as JSON. On the controller or method we allow debug mode to be on or off for that scope, and debug mode itself is controlled either by securely adding the flag into the session for internal users, or always on in dev mode.

aesteve commented 9 years ago

Wow, a lot of things here. Let me try to clarify, since I'm not really sure I understand all of your points.

  1. "ModelAndView"

I'm not sure what you mean by "view objects at the top level" along with Vert.x's template engines.

All templates engines implementations rely on a Map as a "view object" if I'm not mistaking. And this map is RoutingContext.data(). There's no "ViewObject" the same way Spring has "ModelAndView". So, what would you expect for handling a @View annotated method's return ? Just adding the return object to context.data() (or putAll if's a map) ? But under which key ?

  1. Same method for both a view and a REST call

I understand your use case but never faced it myself actually. (I designed Nubes from my actual needs since I had to start with something :\ ). Is this a pattern you're writing quite often ?

And more important : do you think having what you wrote (same method, two content types) is more readable than having two separated controllers relying on the same method (DAO for instance) under the hood ? (it's not a rhetorical question, I'm actually interesting in the answer :) ) In my applications, REST API calls are often mapped under /api/{version} which wouldn't allow me to write what you did in your example.

  1. &format=json

Two different things here.

Thank you.

apatrida commented 9 years ago

I'm actually not sure jaja. We have moved away from views in the app and do most client-side now. But we have some that are both API + View from same endpoint because it is the same action for us with a different output format. That is less of the issue I was really intending to address, than having it be such a different style of data.put() or data.add() instead of just returning the model for the view. Freemarker for example can use an object as a model and not just a map. With a comment in the view, you then have typesafe editing in IDE's such as Intellij IDEA. Having only a map as the data model is not what everyone wants.

villesau commented 8 years ago

I actually also noticed the way to use views. I would always avoid to put data to passed in variables, but just return the data instead. It's clearer and more convenient way to do it. i never modify the objects what have been passed into the method. The idea of @View("viewname") was also pretty nice imo. btw the project looks really nice, great work! :)