Skip to content

Services

Services are the heart of every Feathers application. You probably remember the service we made in the quick start to create and find messages. In this chapter we will dive more into services and create a database backed service for our chat messages.

Feathers services

In Feathers, a service is an object or instance of a class that implements certain methods. Services provide a way for Feathers to interact with different kinds of data sources in a uniform, protocol-independent way.

For example, you could use services to read and/or write data to one of the supported databases, interact with the file system, call a third-party API/service (such as MailGun for sending emails, Stripe for processing payments, or OpenWeatherMap for returning weather information), or even read and/or write to a completely different type of database.

A standardized interface allows us to interact with the Database/API/Gnomes inside in a uniform manner across any transport protocol, be it REST, websockets, internally within the application, or Carrier Pigeon 🕊️

Once you write a service method, which usually does not do anything Feathers-specific, you can automatically use it as a REST endpoint or call it through a websocket. Feathers takes care of all the necessary boilerplate, so you can focus on writing the service method itself.

Service methods

Service methods are CRUD methods that a service can implement. Feathers offers a set of general methods that a service can implement, these are:

  • find - Find all data (potentially matching a query)
  • get - Get a single data entry by its unique identifier
  • create - Create new data
  • update - Update an existing data entry by completely replacing it
  • patch - Update one or more data entries by merging with the new data
  • remove - Remove one or more existing data entries
  • setup - Called when the application is started
  • teardown - Called when the application is shut down

Below is an example of Feathers service interface as a class and basic registration on a Feathers application via app.use(name, service[, options]):

ts
import { feathers } from '@feathersjs/feathers'
import type { Application, Id, NullableId, Params } from '@feathersjs/feathers'

class MyService {
  async find(params: Params) {}
  async get(id: Id, params: Params) {}
  async create(data: any, params: Params) {}
  async update(id: NullableId, data: any, params: Params) {}
  async patch(id: NullableId, data: any, params: Params) {}
  async remove(id: NullableId, params: Params) {}
  async setup(path: string, app: Application) {}
  async teardown(path: string, app: Application) {}
}

const app = feathers<{ myservice: MyService }>()

app.use('myservice', new MyService())

The parameters for service methods are:

  • id - The unique identifier for the data
  • data - The data sent by the user (for create, update, patch and custom methods)
  • params - Additional parameters, for example the authenticated user or the query

For setup and teardown (which are only called once on application startup and shutdown) we have

Usually those methods can be used for most API functionality but it is also possible to add your own custom service methods.

info

A service does not have to implement all those methods but must have at least one. For more information about services, service methods, and parameters see the Service API documentation.

When used as a REST API, incoming requests get mapped automatically to their corresponding service method like this:

Service methodHTTP methodPath
service.find({ query: {} })GET/messages
service.find({ query: { unread: true } })GET/messages?unread=true
service.get(123)GET/messages/123
service.create(body)POST/messages
service.update(123, body)PUT/messages/123
service.patch(123, body)PATCH/messages/123
service.remove(123)DELETE/messages/123

Service events

A registered service will automatically become a NodeJS EventEmitter that sends events with the new data when a service method that modifies data (create, update, patch and remove) returns. Events can be listened to with app.service('messages').on('eventName', data => {}). Here is a list of the service methods and their corresponding events:

Service methodService event
service.create()service.on('created')
service.update()service.on('updated')
service.patch()service.on('patched')
service.remove()service.on('removed')

This is how Feathers does real-time.

js
app.service('myservice').on('created', (data) => {
  console.log('Got created event', data)
})

Database adapters

Now that we have all those service methods, we could go ahead and implement any kind of custom logic using any backend, similar to what we did in the quick start guide. Very often, this means creating, reading, updating and removing data from a database.

Writing all that code yourself for every service is pretty repetitive and cumbersome, which is why Feathers has a collection of pre-built services for different databases. They offer most of the basic functionality and can always be customized to your needs. Feathers database adapters support a common usage API, pagination and querying syntax for many popular databases. The following database adapters are maintained as part of Feathers core:

  • SQL for databases like PostgreSQL, SQLite, MySQL, MariaDB, MSSQL
  • MongoDB for MongoDB
  • Memory for in-memory data

tip

There are also many other community maintained database integrations which you can explore on the ecosystem page. Since they are not part of Feathers core, they are outside the scope of these guides.

If you went with the default selection, we will use SQLite which writes the database to a file and does not require any additional setup. The user service that was created when we generated authentication is already using it.

Generating a service

In our new feathers-chat application, we can create database backed services with the following command:

sh
npx feathers generate service

The name for our service is message (this is used for variable names etc.) and for the path we use messages. Anything else we can confirm with the default:

feathers generate service prompts

This is it, we now have a database backed messages service with authentication enabled.

What's next?

In this chapter we learned about services as a Feathers core concept for abstracting data operations. We also saw how a service sends events which we will use later to create real-time applications. After that, we generated a messages service. Next, we will look at Feathers hooks as a way to create middleware for services.

Released under the MIT License.