Yet another software engineer

My thoughts are my own

Create a custom route in FeathersJS without creating new service

Posted at — Nov 19, 2019

If you do not know what FeathersJS is then this line is for you. It is taken from FeathersJS’s official website.

A framework for real-time applications and REST APIs

Index

There are more features that I about Feathers for example: hooks, auto configured authentication, auto configured test using mocha and more.

I am assuming you already know how to install, create app and create service using feathers. I am writing an small instruction for those who does not know yet. I will use the latest version of Feathers which is 4.2.3.

Run the following command to install feathers CLI npm install -g @feathersjs/cli .

First of all create a folder then navigate to it and run the following command feathers generate app. You will be asked a few questions like app name, source folder name, which package manager would the CLI use, is it typescript app or javascript, type of API (REST/Real-time/Both) etc.

For this topic I am going to create a service named organizations. **** To do that run the following command feathers generate service. You will be asked a few queries related to your service. CLI will perform a few actions to create a new service. One of the action is create a new folder inside [source_directory] > services. For my case it looks like this: src > services > organizations. Our organizations service is ready to CRUD.

Organizations directory has three files in it. They are organizations.class.js, organizations.hooks.js, organizations.service.js. We will be focusing on .class and .service file in this article.

Initially the organizations.class.js and organizations.service.js file would look like this.

const { Service } = require('feathers-mongoose');

exports.Organizations = class Organizations extends Service {
  
};
// Initializes the `organizations` service on path `/organizations`
const { Organizations } = require('./organizations.class');
const createModel = require('../../models/organizations.model');
const hooks = require('./organizations.hooks');

module.exports = function (app) {
  const options = {
    Model: createModel(app),
    paginate: app.get('paginate')
  };

  // Initialize our service with any options it requires
  app.use('/organizations', new Organizations(options, app));

  // Get our initialized service so that we can register hooks
  const service = app.service('organizations');

  service.hooks(hooks);
};

The easy way

FeathersJS uses ExpressJS under the hood. So, we will be able to take advantage of it. To make a custom route the easy way follow the code block below and notice from line 15 to 18.

// Initializes the `organizations` service on path `/organizations`
const { Organizations } = require('./organizations.class');
const createModel = require('../../models/organizations.model');
const hooks = require('./organizations.hooks');

module.exports = function (app) {
  const options = {
    Model: createModel(app),
    paginate: app.get('paginate')
  };

  // Initialize our service with any options it requires
  app.use('/organizations', new Organizations(options, app));

  // Initialize our custom route
  app.get('/custom-organizations', (req, res) => {
  	res.send('Hello from custom route');
  });

  // Get our initialized service so that we can register hooks
  const service = app.service('organizations');

  service.hooks(hooks);
};

The feathers way

In the service > organizations directory create a new file named custom-organizations.class.js. Copy everything from organizations.class.js and rename Organizations to CustomOrganizations. Now the file should look like this.

const { Service } = require('feathers-mongoose');

exports.CustomOrganizations = class CustomOrganizations extends Service {
};

Now we have to connect this custom class with our service somehow. Here is how you can achieve it. This is update version of organizations.service.js.

// Initializes the `organizations` service on path `/organizations`
const { Organizations } = require('./organizations.class');
const { CustomOrganizations } = require('./custom-organizations.class');
const createModel = require('../../models/organizations.model');
const hooks = require('./organizations.hooks');

module.exports = function (app) {
  const options = {
    Model: createModel(app),
    paginate: app.get('paginate')
  };

  // Initialize our service with any options it requires
  app.use('/organizations', new Organizations(options, app));

  // Initialize our custom route
  app.use('/custom-organizations', new CustomOrganizations(options, app));

  // Get our initialized service so that we can register hooks
  const service = app.service('organizations');

  service.hooks(hooks);
};

Notice line number 3 and 17. First imported the class in service, then register the class on the applicaton.

Technically, we are creating a new feathers service.

Now run the app and hit /custom-organizations. You should get expected response.

Conclusion

Technically speaking we had to create a new service but, also for simple task this way of creating a custom endpoint is convenient in my opinion.

Video

Reference: