9

I define my api with something like the below:

class MyFeathersApi {
  feathersClient: any;
  accountsAPI: any;
  productsAPI: any;

  constructor(app) {
    var port: number = app.get('port');

    this.accountsAPI = app.service('/api/accounts');
    this.productsAPI = app.service('/api/products');
  }

  findAdminAccounts(filter: any, cb: (err:Error, accounts:Models.IAccount[]) => void) {
    filter = { query: { adminProfile: { $exists: true } } }
    this.accountsAPI.find(filter, cb);
  }

When I want to use database adapter methods, from the client, i.e. find and/or create, I do the below:

var accountsAPIService = app.service('/api/accounts');
accountsAPIService.find( function(error, accounts) {
  ...
});

How I call custom methods, such as findAdminAccounts() from the client?

Moshe Shmukler
  • 1,270
  • 2
  • 21
  • 43

1 Answers1

11

You can only use the normal service interface on the client. We found that support for custom methods (and all the issues it brings with it going from a clearly defined interface to arbitrary method names and parameters) is not really necessary because everything in itself can be described as a resource (service).

The benefits (like security, predictability and sending well defined real-time events) so far have heavily outweighed the slight change in thinking required when conceptualizing your application logic.

In your example you could make a wrapper service that gets the admin accounts like this:

class AdminAccounts {
  find(params) {
    const accountService = this.app.service('/api/accounts');

    return accountService.find({ query: { adminProfile: { $exists: true } } });
  }

  setup(app) {
    this.app = app;
  }
}

app.use('/api/adminAccounts', new AdminAccounts());

Alternatively you could implement a hook that maps query parameters to larger queries like this:

app.service('/api/accounts').hooks({
  before: {
    find(hook) {
      if(hook.params.query.admin) {
        hook.params.query.adminProfile = { $exists: true };
      }
    }
  }
});

This would now allow calling something like /api/accounts?admin.

For more information see this FAQ.

Daff
  • 43,734
  • 9
  • 106
  • 120
  • I guess, the wrapper service serves my problem. Right? – Moshe Shmukler Dec 14 '15 at 17:57
  • Yep, I think so. It's a little of a change in thinking from method based to a resource based approach but the benefits are worth it and it's what Feathers can do best. – Daff Dec 14 '15 at 20:01
  • Thank you. I am new to Node.JS in general, trying to comprehend multiple "technologies," including Feathers.JS, at once. Your help is truly appreciated. – Moshe Shmukler Dec 14 '15 at 20:35
  • No problem. Feel free to post your Feathers questions here, on Gitter (https://github.com/feathersjs/feathers) or on GitHub. We'll try our best to make learning it as easy as possible! – Daff Dec 15 '15 at 03:37
  • @Daff What about reusing methods in diferent services and hooks? For example, in my application I need to send a confirmation email to my user both when he first registers himself and also when he asks to send the confirmation email again. So, in this case I think I could create a service for sending emails, but I also think to call the same "sendEmail()" method/function in an after hook on the create user service. How can I make this work, so that my email be sent after the user registers and when he asks to receive the email again? – Ulysses Alves Jun 04 '16 at 23:01