Loopback: Server-side MVC

Created on 15 Aug 2014  Â·  30Comments  Â·  Source: strongloop/loopback

Please tell me: Is loopback a MVC framework build on expresjs ?.

  1. How can I define a new controller to handle request. Or everything in loopback is model
  2. How can I send more information after each request, example: timestamp.
  3. I see in app.js have a line app.enableAuth() to check token, secure app. But how to customize this app, example I want to check if request have a specific header value.

Thanks in adavanced, loopback.io team

discussion

Most helpful comment

@pbalaga There is work being done with regards to adding controllers so stay tuned. No definitive dates on implementation, but there will be a blog post when it happens. Make sure you subscribe to get the latest announcements at https://strongloop.com/strongblog/.

All 30 comments

No, loopback is an API server built on top of express, it's doesn't handle views and controllers for you.

The strength of loopback is it's capability to help you build robust RESTful API real quick, with the help of built-in ACL, ORM, REST adaptor and abundant db connectors.

That being said, loopback is based on express, if you really need to handle both website and API requests in one server, you can hook in a typical router in app.js and handle requests there, for example:

app.get('/pricing', function(req, res, next){
    res.render('pricing');  // assuming using ejs template here
}

hth.

Yes, I understand what you said. Truly I'm creating a back end server for android application, so loopback is what I want. I don't need view.
But If it div into controller and model, the structure of application will be clear. That is my ideal ^^. I will try loopback and maybe I will discovery that my ideal is wrong.
Please show me the answer of question â‘¡ and â‘¢

You can use LoopBack remote hooks (http://docs.strongloop.com/display/LB/Defining+remote+hooks) or plain express middleware for 2 & 3.

IMO:

  1. JSON output is still view. The controller part should not contain business logic, most MVC framework do for you automatically. In loopback, strong-remoting does controller things. At last, model in loopback is Domain Model, briefly, data + action.
  2. you can accomplish that by:
  3. adding connect/express middleware, if you have generally purpose for every request
  4. defining remote before hooks

3 same as 2

We've couple traditional controllers onto model classes, which has seemed to work out well enough for v1 and v2 but I think v3 might need controllers to support clearer separation of concerns.

Food for thought:

// in common/controllers/example.js
module.exports = function(ExampleCtrl) {
  // handles '/example' by default via a remote method
  // use any strong remoting adapter (eg. via websocket, zeromq, JSON RPC, etc)
  ExampleCtrl.prototype.index = function(cb) {
    // ctx => remoting ctx, if http => ctx.req + ctx.res
    var ctx = this.ctx;

    // callback with a result of some sort
    cb(null, 'my result'); // by default rendered as html (like the `res.send()` defaults from express)
  }

  // custom methods just like model methods
  ExampleCtrl.prototype.custom = function(cb) {
    cb(null, 'hello world');
  }

  ExampleCtrl.sharedClass.defineMethod('custom', {isStatic: false});
}

@ritch interesting - so essentially controllers use the same remoting API as models? So in your example, for 'custom', the default verb will be GET? And you'd have a controllers/example.json config file alongside this definition? Is this where you'd define ACL's and so on?

So in your example, for 'custom', the default verb will be GET

Yep

And you'd have a controllers/example.json config file alongside this definition? Is this where you'd define ACL's and so on?

Yes to both.

Would anyone mind sharing a sample Loopback project boilerplate code that achieves the abovementioned recommendations? Basically showing some example routes, controllers, etc. I'm looking for a Loopback project that can perform simultaneously as REST API, MVC, and also serving static files like css & images.

Although perhaps it would be better to have two distinct nodejs services: one for REST API , and one for a RoR-ish MVC?

Or... Another thought... Has anyone explored the possibility of dropping in a framework, ex: paypal Kraken, into a Loopback project to achieve this overall goal? Probably too convoluted to be useful, but I'm not sure.

@gavinengel

Check out Sails.js. I think it handles the MVC paradigm more readily than LoopBack.

If you really need an MVC boilerplate for LoopBack, here's something I cooked up real quick: loopback-example-mvc. It doesn't support views at the moment, but please feel free to look at how controllers are implemented. The boilerplate also has Sails.js-like services and mocha tests built in.

You can access the express object on loopback object and then just build the MVC that way. I have built several this way, although I usually serve client side MVC, the structure is the same.

You put your views in the server/views and use

var app = loopback(); //Express object
app.set('views', './server/views'); 
app.set('view engine', 'jade'); //Can use any express view engine(Jade/handlebars/haml/react)

You can put your controllers in server/controllers
and require them in server/server.js and set them to appropriate routes.

Please post questions to https://groups.google.com/forum/#!forum/loopbackjs. See https://github.com/strongloop/loopback/wiki/Reporting-issues#question for more details.

@bajtos @raymondfeng @ritch Safe to close?

@superkhau I'd prefer to keep this open as an ongoing discussion about how to best support the MVC paradigm.

@bajtos Sounds good.

Hmm. The models in loopback are definitely there already in common/models. The views I guess are not meant to be in a loopback project, as it is returning raw json from ajax/websocket. Since routing basically follows a standard from LB/Swagger (I think), just leaves controllers. So, are controllers needed in a REST API framework? I think so. In my mind it makes sense that an endpoint is not tied to a single model. For instance, let's say I'm sharing listings from an auction website at /listings/. In addition to a huge array of listings, I want to give out a small nested array within each array of the seller's basic info. Not necessary, but I think it would save other hits to /users/ that my API users might write to pull info on every listing. There would be other controllery I would do in these controller files that I don't like doing in the server.js or in the model .js files. So I wouldn't mind seeing a simplified controllers layer added to loopback, even if they all shared the same names like user.js but were in a common/controllers dir. Maybe a third party plugin on npm like loopback-controllers would be useful to add a uniform layer if wanted?

Would it not be simple enough to mount a server side MVC framework like sailsJS or locomotiveJS at a route point in loopback?

Anyone has had any luck with that?

Has anyone made any progress with this?

Now that sails future is not clear, using Loopback as a server side MVC looks like a good alternative.
I found an article about serving views, which worked perfect.
However there are some things that are unclear like how to expose the controllers and services.
@kisayista I couldn't find the boilerplate you made, any chance you can upload it again?

@niallobrien @ronenteva We have used Loopback as a server side MVC for while now. Here is a router/controller https://github.com/FreeCodeCamp/FreeCodeCamp/blob/staging/server/boot/nonprofits.js and the views for this controller are here https://github.com/FreeCodeCamp/FreeCodeCamp/tree/staging/server/views/nonprofits

Sorry @ronenteva. I've deleted the repo from both Github and my local computer. :(

I'd assume we'd need more features for server-side rendered apps though, eg. csrf protection on forms etc.

@kisayista No worries, thanks for letting us know.
@niallobrien I've been researching for a while now, and Loopback seems to be the best alternative in my honest opinion.
@BerkeleyTrue Thank you for sharing your use case, I find it VERY useful! :+1:
@superkhau @bajtos I assume it's not on your roadmap, but I really think that if you'll post an official boilerplate / tutorial, you'll be seeing a lot of confused sails users coming your way.

Hey guys, I'm exploring options for implementing controllers right now. Has anyone used @kisayista's implementation (I found a fork here)? What about @BerkeleyTrue's implementation?

Keep the discussion going, I'm interested in any more thoughts.

Probably as many others I wonder if this topic is still being explored. Loopback sets its goals clear as an API framework but - in spite of its growth - the Node ecosystem seems to be lacking a reliable MVC-based framework for building web apps (similar to RoR, ASP MVC, etc.). I would imagine this has a lot of potential.

Is there anything going on in this direction?

@pbalaga There is work being done with regards to adding controllers so stay tuned. No definitive dates on implementation, but there will be a blog post when it happens. Make sure you subscribe to get the latest announcements at https://strongloop.com/strongblog/.

Hello, I have found some material about MVC implementations but so far I think the most complete and well explained approach has been posted by @BerkeleyTrue , so, I have a question regarding the server.js example material submitted by him. Is that aproach valid to deliver node server up and running in a production environment?
That approach also validares and apply security suggestions shown in official loopback documentation, so, I think worths it to be posted as a solid and final respond to this issue which discuss MVC pattern on loopback based applications.
His suggestion is 5 posts up.

Is that aproach valid to deliver node server up and running in a production environment?

There are many ways to skin the cat, but yes that is one approach that is valid (you would do the same as you would with vanilla express routes -- see http://expressjs.com/en/guide/routing.html). The app in server.js is the same app as you get with express() with additional functionality. How you organize your routes (in server/controllers, etc) is up to you. However, I do agree we should probably have some sort of standard locations so we can all benefit from convention over configuration.

Hello, Sorry to be again adding more doubts to this topic but I have some observations about documentation and server side MVC implementation:
1) After hours of digging deeply in loopback documentation I found some differences about how to succesfully secure server side views using third parties authentication, example: loopback-component-passport, the docs here specify the need of 3 basic models creation which are: UserIdentity model, UserCredential model and ApplicationCredential model, also it says that the last model has to extend Application model (WHEN IN THE FIRST PLACE I BUILT THAT MODEL???), and in the same documentation it references an example code which is not following the official documentation explanation, so, in the first place this result TEDIOUS and ANNOYING having to research why in the example there are 3 different models and no Application model specification NOWHERE, in the example there are the following models: user-credential, user-identity and user-token model which I guess is the substitute to ApplicationCredential model.

2) When I check the code of the example models (https://github.com/strongloop/loopback-example-passport/tree/master/common/models) i can see

"base": "UserCredential",

so, if I use slc loopback:model I don't have a UserCredential base model to use it as it sais BASE, I can suspect the UserCredential model is on the builtin models, but no, it is not, ALL MY CLASSES EXTENDS PersistedModel. So this discordances affects negatively the learning curve of this framework and i think results in number of users running away. I do understand this requires a basic programming skills in node.js but not all of us are IBM engineers to figure out why in the heck the model.json file in the example is based on itself, accordingly to the code base: "UserCredential" means that UserCredential is extending itself??
here is the code: user-credential.json

{
  "name": "userCredential",
  "plural": "userCredentials",
  "base": "UserCredential",
  "properties": {},
  "validations": [],
  "relations": {
    "user": {
      "type": "belongsTo",
      "model": "user",
      "foreignKey": "userId"
    }
  },
  "acls": [],
  "methods": []
}

3) Loopback created middleware.json file to order all middleware functions in a global file with a global context and it's great but, why LAZY coders that submits examples to Loopback official documentations do such things as this: server.js file in https://github.com/strongloop/loopback-example-passport/blob/master/server/server.js

// to support JSON-encoded bodies
app.middleware('parse', bodyParser.json());
// to support URL-encoded bodies
app.middleware('parse', bodyParser.urlencoded({
  extended: true,
}));

// The access token is only available after boot
app.middleware('auth', loopback.token({
  model: app.models.accessToken,
}));

app.middleware('session:before', loopback.cookieParser(app.get('cookieSecret')));
app.middleware('session', loopback.session({
  secret: 'kitty',
  saveUninitialized: true,
  resave: true,
}));

WHY? WHY loopback coders breaks up the default loopback modularity attempt to organize everything in well documented and specified files schema?
So, this are my observations as newbie coder AND possible next ex possible loopback coder.
Regards.

Hello,
I would like to request that a "MVC Server" be placed in the "? What kind of application do you have in mind? (Use arrow keys)" part of the "slc loopback" command.
There currently doesn't seem to be any kind of guidance on creating an MVC framework with Loopback. I would love to see something that can compare to what Sails currently has. I feel Loopback is much much more active than Sails, there is way more focus given to Loopback than Sails and there are many other little things that really make Loopback attractive. The only thing that is keeping me from switching completely is the lack of official MVC support. It should not be too difficult to implement as:
https://github.com/ForkedRepoSnaphy/loopback-example-mvc

already has the controller part of mvc.
I would also love to see a "getting started" example be in the readme of each configuration type.

We will be adding support for controllers in the next major version of LoopBack. Stay tuned!

Was this page helpful?
0 / 5 - 0 ratings