FeathersJS Basics
Updated: 03 September 2023
Notes from this Coding Garden Series on FeathersJS
Simple Feathers Service
To create a super simple feathers
service you can do the following:
Init App
Create Feathers Instance
Next up, create an app.js
file with the following to initialize a feathers app:
app.js
Create Service
You can then create a service, each service needs to have a class which defines what methods are available in the service, for example the MessageService
below defines a find
and create
method:
app.js
Register Service
We can then register a service by using app.use
with a name for the service followed by an instance of the service class:
Listen to Events
We can use the app.service('...').on
method to add a handler to an event on a service which will allow us to react to the service events:
Interact with Service
We can interact with a service by referencing a method in a service:
Expose as REST and Web Socket
Once we’ve defined a feathers
service we can expose it as a REST endpoint as well as a Web Socket automatically using feathers’ express
Install the @feathersjs/express
and @feathersjs/socketio
packages:
Then, we need to configure the app as an express app instead as follows:
Next, add the middleware for json
, urlencoded
, and static
serving:
And then, automatically create the epxress and feathers endpoints for our services:
Note that the
messages
from the previous service definition now becomes/messages
as it’s an endpoint definition now
Lastly, we add the express error handler:
Now, we will be able to listen to the connection
event to trigger something each time a client connects and that will give us access to the connection. We can also add any client that connects to a group so that messages can be broadcast to them:
Lastly, we start the server:
Now, you can start the application with node app.js
and go to http://localhost:3030/messages
where you can see the list of messages that are currently in the service
Connect from Browser
Create an index.html
file, from here we’ll be connecting to the feathers backend we’ve configured using the feathersjs
and socketio
clients for the browser:
Which we can then include in the index.html
file:
index.html
Then, in the index.html
we can use the following js to subscribe to the socket. We can actually use code that’s almost identical to what we use on the server to interact with the service. An example of a form that allows users to send data to the service and receive updates from the service would look something like this:
index.html
Init Feathers Application
The previous app that’s been configured is a very simple service. To make a more complete feathers
app we will make use of the CLI
To create a new feathers
app you will need to use npm or yarn to install the cli
And then create an app with:
Below are the options I’ve chosen:
Config
Once created you can find the application config in the config/default.json
file. In the config files you can do something like "PORT"
as a value which will automatically replace it with an environment variable called PORT
, this can apply to any environment variable you want to use in your config file
Entrypoint
The entrypoint to a feathers
application is the index.ts
file which imports the app
as well as some logging config, etc.
Additionally, there’s the app.ts
file which pretty much configures an express app for feathers
with a lot of the usual configuration settings, body parsers, and middleware
Models and Hooks
The User Model and Class Files specify the default behaviour for the specific user
entity. Additionally this also uses hooks
to allow us to run certain logic before and after a service is run as well as manage things like authentication
Channels
The channel.ts
file is where connections are handled as well as assign users to channels in which they have access to as well as manage what channels get which events published to them
Authentication
The authentication.ts
defines an AuthenticationService and configures the auth providers that are available
Configure
The app.configure
function is used all over a feathers app. A configure
function is a function that takes the app
function.
app.configure
takes a function that takes the app
and is able to configure additional things and create services from the app
. The configure
function essentially allows us to break out application into smaller parts
Feathers Services
Feathers services are an object or class instance that implements specific methods, they can do things like:
- Read or write from a DB
- Interact with the file system
- Call another API
- Call other services
Service interfaces should implement certain CRUD
methods and each service should implement one or more of the following:
Service | Method | Endpoint Structure | Event Name |
---|---|---|---|
find | GET | /things?name=john | |
get | GET | /things/1 | |
create | POST | /things | created |
update | PUT | /things/1 | updated |
patch | PATCH | /things/1 | patched |
remove | DELETE | /things/1 | removed |
Incoming requests get mapped to a corresponding rest method
Every service automatically becomes an EventEmitter
which means that every time a certain modification action is created then the service will automatically emit the specific event that can then be subscribed to from other parts of the application
Due to the design of services we are able to have each service exposed by Feathers via REST and Web Sockets
Database adapters are just services which have been implemented to work with specific databases automatically
We can generate a service using feathers with:
Which will then allow you to select the DB to be used for the service as well as a name for it:
This will generate a new service in our services
directory as well as a model
in the models
directory
We are also able to modify a service’s class so that it behaves the way we would like it to, for example we can modify the users
service class so that it generates an avatar url for each user:
users.class.ts
Hooks
Hooks allow us to make use of reusable components that gets implemented as middleware on all service methods. An example implentation of these are the user
hooks which do some authentication as well as output data cleansing:
users.hooks.ts
We can implemet a hook like createdAt
or updatedAt
on a service so that we can track date timestamps on an entity and modify data on the context
object
In order to generate a hook you can run:
And then enter the hook name as well as when it should be run:
Then, we can update the hook implementation to match our requirements:s
hooks/set-timestamp.ts
In this case, we would use the above hook with:
Service vs Hooks
Services and Hooks are very similar, we will primarily make use of services for functionality that is specific to a service and we will make use of hooks when the functionality is something that can be abstracted and shared with different services