mORMot and Open Source friends
View Ticket
Not logged in
Ticket UUID: bd94c11ab167d0a075fa1c3918b60f2c2fdd0b85
Title: Implement MVC model (like RoR) in mORMot, for the exact purpose of serving WEB content
Status: Fixed Type: Feature_Request
Severity: Important Priority: High
Subsystem: mORMot Resolution: Implemented
Last Modified: 2014-11-12 15:06:39
Version Found In:
Description:
We would like to introduce a new MVC model (like RoR) in mORMot, for the exact purpose of serving WEB content.

Note that a generic caching mechanism should be made available, to improve service responsiveness. This cache may be handled at View level, and/or at Controller level, depending on the business logic.

Model

The MODEL would be the main mORMot's ORM model.

Controller

The CONTROLLERS would be dedicated classes (inheriting from an abstract TMVCController class), which will compute the data to be viewed within:

  • method-based services (published methods of the controller class);
  • or interface-based services (implemented by the controller class).

Output of the controller would be a JSON object, similar to the Mustache HASH:

{
  "header": "Colors",
  "items": [
      {"name": "red", "first": true, "url": "#Red"},
      {"name": "green", "link": true, "url": "#Green"},
      {"name": "blue", "link": true, "url": "#Blue"}
  ],
  "empty": true
}

To compute this JSON object, we would expect the following:

  • For method-based services, it may be directly emitted as raw JSON;
  • For interface-based services, this object may be created from the list of OUT parameters of the method (i.e. the interface should be able to serialize its result not as a JSON array, but as a JSON object including the parameter names).

All server-side methods (ORM and services) would be usable to compute the resulting JSON object.

View

The VIEWS would be dedicated classes (inheriting from an abstract TMVCView class) for rendering the JSON object as computed by the CONTROLLERS into HTML or any other mean.

We propose to implement:

  • JavaScript kind of view (via our SpiderMonkey integration), which would be able to generated e.g. HTML or PDF reports (via a dedicated service publishing the most common methods of TGDIPages via an interface);
  • Mustache kind of view (implemented at first via JavaScript library, potentially in a more optimized way - pure Delphi - in the future, even if the JavaScript implementation is pretty powerful, since it allows inlined scripting) - both ORM operations and interface-based services would be available within Mustache;
  • any custom kind of view model, e.g. Razor-like or Lua-like - but I guess that such kind of rendering would be unneeded, since high-level scripting tends to put some logic in the View, which should better stay within the Controller.

Typical Mustache template may be:

<h1>{{header}}</h1>

{{#items}}
  {{#first}}
    <li><strong>{{name}}</strong></li>
  {{/first}}
  {{#link}}
    <li><a href="{{url}}">{{name}}</a></li>
  {{/link}}
{{/items}}

{{#empty}}
  <p>The list is empty.</p>
{{/empty}}

Which may be rendered as such:

<h1>Colors</h1>
<li><strong>red</strong></li>
<li><a href="#Green">green</a></li>
<li><a href="#Blue">blue</a></li>
<p>The list is empty.</p>

Mustache has some nice features, like partial templates (which are some kind of "include"), and the ability to execute a function (see lambdas in its manual) before rendering the content.


ab added on 2014-06-10 09:17:12 UTC:
Some feedback and proposals in forum thread. Worth the discussion.

User Comments:
root added on 2014-06-27 10:12:54:

Linked to [73c1da3c401eccaf0c], which is similar to this feature request, but for Delphi VCL/FMX UI.


root added on 2014-08-23 08:01:12:

This model is pretty close to the MVC implemented in AngularJS.

Our data context is indeed the same "glue" between the view and the controller.
The AngularJS' $scope has the same exact purpose.

See the Angular official tutorial for details about it.


root added on 2014-08-23 12:52:35:

[48e30e0e05] feature request did let TServiceMethod.InternalExecute() incoming parameters be encoded as a JSON object, alternatively to a JSON array.

Here, the same rules applies all all routing mode:

  • Any missing parameter will be replaced by its default value;
  • Properties order is not sensitive any more;
  • Unexpected parameters will just be ignored.

This feature request may be used directly in our MVC model: the incoming parameters of the controllers or the view may be defined as a JSON object, and TServiceMethod.InternalExecute() will use only the needed parameters.

Since the MVC feature would most of the time be executed in the same process, on the server side, having a whole context supplied to the method won't be a problem. Process cost on the server side will be negligible, since our implementation will just ignore those unexpected properties, without allocating any memory for them.


ab added on 2014-11-12 15:06:39:

I suspect we reached some point of stability of this feature request.

See the corresponding documentation available online.

Any further modifications may be handled as separate bug fix or feature request tickets.