Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to add remote method to a built-in model #763

Closed
crandmck opened this issue Nov 6, 2014 · 18 comments
Closed

Document how to add remote method to a built-in model #763

crandmck opened this issue Nov 6, 2014 · 18 comments
Assignees
Labels

Comments

@crandmck
Copy link
Contributor

crandmck commented Nov 6, 2014

Currently, we document how to define a remote method for a custom model, and how to create a custom model that extends a built-in model (to which you could attach a remote method) but NOT how to attach a remote method directly to a built-in model.

Summary (example):

  1. Create a boot script, eg. /server/boot/userRemoteMethods.js.
  2. Add the following to this file:
User = app.models.User;
module.exports = function(User){

    User.greet = function(msg, cb) {
      cb(null, 'Greetings... ' + msg);
    }

    User.remoteMethod(
        'greet', 
        {
          accepts: {arg: 'msg', type: 'string'},
          returns: {arg: 'greeting', type: 'string'}
        }
    );
};
@crandmck crandmck added the doc label Nov 6, 2014
@ritch
Copy link
Member

ritch commented Nov 6, 2014

@bajtos do we support extending built in models from a model script? Or is this only possible from a boot script.

@bajtos
Copy link
Member

bajtos commented Nov 7, 2014

do we support extending built in models from a model script?

Not yet - see #397.

Or is this only possible from a boot script.

Yes.


I'd rather postpone this task until we implement redefine:true as proposed in #397:

A better solution is to implement redefine:true. A redefined "User" model is defined in common/models/user.json and scaffolded by yo loopback. Benefits: clean solution, allows redefinition of common models in the server facet.

@crandmck
Copy link
Contributor Author

crandmck commented Nov 7, 2014

@bajtos when you say

I'd rather postpone this task ....

Are you referring to documenting how to add remote method to a built-in model (in a boot script, apparently the only way to do so) or support for extending built-in models in a model script?

@bajtos
Copy link
Member

bajtos commented Nov 7, 2014

@crandmck I wanted to say that it's better to wait with documentation until we have implemented support for extending built-in models via a model script. The solution based on boot scripts is kind of hacky.

Although if extending builtin models is something that many people are asking for, then maybe we should not wait. In which case it would be good to mention that the current solution described in docs is not optimal and that we are planning to implement a better solution in the near future.

Here is a corrected boot script:

module.exports = function(app) {
  var User = app.models.User;

  User.greet = function(msg, cb) {
    cb(null, 'Greetings... ' + msg);
  }

  User.remoteMethod(
    'greet', 
    {
      accepts: {arg: 'msg', type: 'string'},
      returns: {arg: 'greeting', type: 'string'}
    }
  );
};

@ritch
Copy link
Member

ritch commented Nov 7, 2014

I agree with @bajtos proposal to wait until redefine: true is supported.

@raymondfeng
Copy link
Member

Same here.

@crandmck
Copy link
Contributor Author

crandmck commented Nov 7, 2014

OK!

@pulkitsinghal
Copy link

So I was looking for exactly this sort of documentation and the funny thing is I found it here in an issue created to document it but then again not document it :)
Given that an implementation isn't ready for the best-case scenario, wouldn't you say its easier on the loopback consumers to learn of this hacky approach?

Or is this only possible from a boot script.

I mean it is no hack~ier than the user vs User modification that I would end up with due to my lack of knowledge about this current workaround ... no?

When I put myself in your shoes though ... as a company, maybe you want to field such Qs in google groups and not in the public docs? shrug ... Is that what's going on?

@srguiwiz
Copy link

Does the example really work?

Keep getting 401 Authorization Required when invoking that method, despite known good AccessToken. Seems to be coming from loopback/common/models/roles.js .

What else do I need to do except above code, to make it work?

Did add one line for an HTTP GET for easier testing, so currently I have:

module.exports = function(app) {
  var User = app.models.User;

  User.greet = function(msg, cb) {
    cb(null, 'Greetings... ' + msg);
  }

  User.remoteMethod(
    'greet', 
    {
      accepts: {arg: 'msg', type: 'string'},
      returns: {arg: 'greeting', type: 'string'},
      http: { verb: 'get', path: '/greet' }
    }
  );
};

Then for URL (with valid token)

http://127.0.0.1:3000/api/Users/greet?msg=%22Joe%22&access_token=QqU0tx...

I keep getting

{"error":{"name":"Error","status":401,"message":"Authorization Required","statusCode":401,"stack":"Error: Authorization Required
    at app.enableAuth.isAuthEnabled (/home/joeb/project17/node_modules/loopback/lib/application.js:327:21)
    at Model.checkAccess (/home/joeb/project17/node_modules/loopback/lib/model.js:295:5)
    at module.exports.ACL.checkAccessForContext (/home/joeb/project17/node_modules/loopback/common/models/acl.js:437:23)
    at _asyncMap (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:254:17)
    at done (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:135:19)
    at _toString (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:32:16)
    at _asyncMap (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:251:21)
    at results (/home/joeb/project17/node_modules/loopback/node_modules/async/lib/async.js:575:34)
    at module.exports.ACL.checkAccessForContext.find.async.parallel.resolved.permission (/home/joeb/project17/node_modules/loopback/common/models/acl.js:420:17)
    at module.exports.Role.isInRole.resolver (/home/joeb/project17/node_modules/loopback/common/models/role.js:219:21)"}}

Just as a test, same server success with GETting a User with a URL

http://127.0.0.1:3000/api/Users/972294...?access_token=QqU0tx...

@bajtos
Copy link
Member

bajtos commented Feb 26, 2015

IIRC you need to add isStatic:true to your remoting metadata.

User.remoteMethod(
    'greet', 
    {
      isStatic: true,
      accepts: {arg: 'msg', type: 'string'},
      returns: {arg: 'greeting', type: 'string'},
      http: { verb: 'get', path: '/greet' }
    }
  );

See also #597.

@srguiwiz
Copy link

Tried variations without and with isStatic: true, and without and with prototype, and both with User.remoteMethod and with loopback.remoteMethod. No luck.

@bajtos
Copy link
Member

bajtos commented Feb 26, 2015

Please run your app with DEBUG=loopback*,strong-remoting* and see if you can find any hints in the debug logs. If you are still not able to figure this out, then please post a question to our mailing list, so that we don't derail this doc task into a support thread.

@srguiwiz
Copy link

In mailing list Raymond then mentioned required additional step:

Add the following ACLs to the "User" model in server/model-config.json:

"acls": [
  {
     "principalType": "ROLE",
     "principalId": "$everyone",
     "permission": "ALLOW",
     "property": "greet"
  }
]

@bajtos
Copy link
Member

bajtos commented Jun 2, 2016

wait until redefine: true is supported.

Since we were not able to implement redefine:true in the last 18 months, I think it will be best to stop waiting and update the docs right now.

/cc @crandmck

@bajtos bajtos removed the blocked label Jun 2, 2016
@crandmck
Copy link
Contributor Author

crandmck commented Jun 29, 2016

I think it will be best to stop waiting and update the docs right now.

I agree.

@bajtos I'd like to assign this (and a few other LB doc issues) to @Sequoia (who is doing some contract work for us) but he is not a collaborator in this repo... Can you do something so I can assign issues to him? PM me if you have questions.

@Sequoia
Copy link
Collaborator

Sequoia commented Aug 19, 2016

Writing up docs for this now. Unless I'm mistaken, it looks like methods added in this way do not show up in the API explorer, unfortunately, so I'll note this in the docs.

@Sequoia
Copy link
Collaborator

Sequoia commented Aug 19, 2016

Please review: https://docs.strongloop.com/display/APIC/Adding+Remote+Methods+to+Built-In+Models

If it looks good, feel free to remove page restrictions and close this ticket.

@crandmck
Copy link
Contributor Author

Edited and published. Thanks, @Sequoia !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants