Note: For directly using a Feathers REST API (via HTTP) without using Feathers on the client see the HTTP API section.
$ npm install @feathersjs/rest-client --save
@feathersjs/rest-client
allows to connect to a service exposed through the Express REST API using jQuery, request, Superagent, Axios or Fetch as the AJAX library.
ProTip: REST client services do emit
created
,updated
,patched
andremoved
events but only locally for their own instance. Real-time events from other clients can only be received by using a websocket connection.
Note: A client application can only use a single transport (either REST, Socket.io or Primus). Using two transports in the same client application is normally not necessary.
REST client services can be initialized by loading @feathersjs/rest-client
and initializing a client object with a base URL:
{% codetabs name="Modular", type="js" -%} const feathers = require('@feathersjs/feathers'); const rest = require('@feathersjs/rest-client');
const app = feathers();
// Connect to the same as the browser URL (only in the browser) const restClient = rest();
// Connect to a different URL const restClient = rest('http://feathers-api.com')
// Configure an AJAX library (see below) with that client app.configure(restClient.fetch(window.fetch));
// Connect to the http://feathers-api.com/messages
service
const messages = app.service('messages');
{%- language name="@feathersjs/client", type="html" -%}
{%- endcodetabs %}
ProTip: In the browser, the base URL is relative from where services are registered. That means that a service at
http://api.feathersjs.com/api/v1/messages
with a base URL ofhttp://api.feathersjs.com
would be available asapp.service('api/v1/messages')
. With a base URL ofhttp://api.feathersjs.com/api/v1
it would beapp.service('messages')
.
Request specific headers can be through params.headers
in a service call:
app.service('messages').create({
text: 'A message from a REST client'
}, {
headers: { 'X-Requested-With': 'FeathersJS' }
});
Pass the instance of jQuery ($
) to restClient.jquery
:
app.configure(restClient.jquery(window.jQuery));
Or with a module loader:
import $ from 'jquery';
app.configure(restClient.jquery($));
The request object needs to be passed explicitly to feathers.request
. Using request.defaults - which creates a new request object - is a great way to set things like default headers or authentication information:
const request = require('request');
const requestClient = request.defaults({
'auth': {
'user': 'username',
'pass': 'password',
'sendImmediately': false
}
});
app.configure(restClient.request(requestClient));
Superagent currently works with a default configuration:
const superagent = require('superagent');
app.configure(restClient.superagent(superagent));
Axios currently works with a default configuration:
const axios = require('axios');
app.configure(restClient.axios(axios));
Fetch also uses a default configuration:
// In Node
const fetch = require('node-fetch');
app.configure(restClient.fetch(fetch));
// In modern browsers
app.configure(restClient.fetch(window.fetch));
You can communicate with a Feathers REST API using any other HTTP REST client. The following section describes what HTTP method, body and query parameters belong to which service method call.
All query parameters in a URL will be set as params.query
on the server. Other service parameters can be set through hooks and Express middleware. URL query parameter values will always be strings. Conversion (e.g. the string 'true'
to boolean true
) can be done in a hook as well.
The body type for POST
, PUT
and PATCH
requests is determined by the Express body-parser middleware which has to be registered before any service. You should also make sure you are setting your Accept
header to application/json
.
Authenticating HTTP (REST) requests is a two step process. First you have to obtain a JWT from the authentication service by POSTing the strategy you want to use:
// POST /authentication the Content-Type header set to application/json
{
"strategy": "local",
"email": "your email",
"password": "your password"
}
Here is what that looks like with curl:
curl -H "Content-Type: application/json" -X POST -d '{"strategy":"local","email":"your email","password":"your password"}' http://localhost:3030/authentication
Then to authenticate subsequent requests, add the returned accessToken
to the Authorization
header:
curl -H "Content-Type: application/json" -H "Authorization: <your access token>" -X POST http://localhost:3030/authentication
Also see the JWT and local authentication chapter.
Retrieves a list of all matching resources from the service
GET /messages?status=read&user=10
Will call messages.find({ query: { status: 'read', user: '10' } })
on the server.
If you want to use any of the built-in find operands ($le, $lt, $ne, $eq, $in, etc.) the general format is as follows:
GET /messages?field[$operand]=value&field[$operand]=value2
For example, to find the records where field status is not equal to active you could do
GET /messages?status[$ne]=active
More information about the possible parameters for official database adapters can be found in the database querying section.
Retrieve a single resource from the service.
GET /messages/1
Will call messages.get(1, {})
on the server.
GET /messages/1?fetch=all
Will call messages.get(1, { query: { fetch: 'all' } })
on the server.
Create a new resource with data
which may also be an array.
POST /messages
{ "text": "I really have to iron" }
Will call messages.create({ "text": "I really have to iron" }, {})
on the server.
POST /messages
[
{ "text": "I really have to iron" },
{ "text": "Do laundry" }
]
Completely replace a single or multiple resources.
PUT /messages/2
{ "text": "I really have to do laundry" }
Will call messages.update(2, { "text": "I really have to do laundry" }, {})
on the server. When no id
is given by sending the request directly to the endpoint something like:
PUT /messages?complete=false
{ "complete": true }
Will call messages.update(null, { "complete": true }, { query: { complete: 'false' } })
on the server.
ProTip:
update
is normally expected to replace an entire resource which is why the database adapters only supportpatch
for multiple records.
Merge the existing data of a single or multiple resources with the new data
.
PATCH /messages/2
{ "read": true }
Will call messages.patch(2, { "read": true }, {})
on the server. When no id
is given by sending the request directly to the endpoint something like:
PATCH /messages?complete=false
{ "complete": true }
Will call messages.patch(null, { complete: true }, { query: { complete: 'false' } })
on the server to change the status for all read messages.
This is supported out of the box by the Feathers database adapters
Remove a single or multiple resources:
DELETE /messages/2?cascade=true
Will call messages.remove(2, { query: { cascade: 'true' } })
.
When no id
is given by sending the request directly to the endpoint something like:
DELETE /messages?read=true
Will call messages.remove(null, { query: { read: 'true' } })
to delete all read messages.