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?
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.