javascriptauthenticationfeathersjs

How to create custom path for service in FeathersJS 5


I created service jobs in my feathers application. I can make CRUD on /jobs endpoint. But now I need to create new endpoint /jobs-count for that service.

I tried code below, but it's not working as expected. When I use it without authentication, I can get response, but when I add authentication("jwt") to it, it's just still loading.

jobs.js

// For more information about this file see https://dove.feathersjs.com/guides/cli/service.html
import { authenticate } from '@feathersjs/authentication'

import { hooks as schemaHooks } from '@feathersjs/schema'
import {
  jobsDataValidator,
  jobsPatchValidator,
  jobsQueryValidator,
  jobsResolver,
  jobsExternalResolver,
  jobsDataResolver,
  jobsPatchResolver,
  jobsQueryResolver
} from './jobs.schema.js'
import { JobsService, getOptions } from './jobs.class.js'
import { jobsPath, jobsMethods } from './jobs.shared.js'

export * from './jobs.class.js'
export * from './jobs.schema.js'

// A configure function that registers the service and its hooks via `app.configure`
export const jobs = (app) => {
  // Register our service on the Feathers application
  app.use(jobsPath, new JobsService(getOptions(app)), {
    // A list of all methods this service exposes externally
    methods: jobsMethods,
    // You can add additional custom events to be sent to clients here
    events: []
  })
  // Initialize hooks
  app.service(jobsPath).hooks({
    around: {
      all: [
        authenticate('jwt'),
        schemaHooks.resolveExternal(jobsExternalResolver),
        schemaHooks.resolveResult(jobsResolver)
      ]
    },
    before: {
      all: [schemaHooks.validateQuery(jobsQueryValidator), schemaHooks.resolveQuery(jobsQueryResolver)],
      find: [],
      get: [],
      create: [schemaHooks.validateData(jobsDataValidator), schemaHooks.resolveData(jobsDataResolver)],
      patch: [schemaHooks.validateData(jobsPatchValidator), schemaHooks.resolveData(jobsPatchResolver)],
      remove: []
    },
    after: {
      all: []
    },
    error: {
      all: []
    }
  })


  app.get('/getJobsCount', authentication("jwt") async (req, res) => {
    try {
      const jobsService = new JobsService(getOptions(app))
      const count = await jobsService.getJobsCount()
      res.status(200).json(count)
    } catch (error) {
      res.status(500).json({ error: 'Server error' })
    }
  })
}

and this is my function in jobs.class.js

async getJobsCount() {
    try {
      const jobsCount = await this.Model.count('id as count').from('jobs')
      return jobsCount[0].count
    } catch (error) {
      console.error('Error fetching office count:', error)
      throw new Error('Failed to fetch office count')
    }
  }


Solution

  • You have two options here:

    1. Generally a new path in Feathers is its own service. You can create a custom service on the jobs-count path and implement only the find method (using this.options.app.service('jobs').Model instead of this.Model
    2. You can register getJobsCount as a custom service method