REST Client =========== .. note:: For directly using a Feathers REST API (via HTTP) without using Feathers on the client see the :ref:`api_client_rest_http-api` section. @feathersjs/rest-client ----------------------- |GitHub stars| |npm version| |Changelog| .. code-block:: sh $ npm install @feathersjs/rest-client --save ``@feathersjs/rest-client`` allows to connect to a service exposed through the :ref:`api_express_rest` using `jQuery `_, `request `_, `Superagent `_, `Axios `_ or `Fetch `_ as the AJAX library. .. raw:: html .. .. tip:: REST client services do emit ``created``, ``updated``, ``patched`` and ``removed`` events but only *locally for their own instance*. Real-time events from other clients can only be received by using a websocket connection. .. raw:: html .. .. 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([baseUrl]) ~~~~~~~~~~~~~~~ REST client services can be initialized by loading ``@feathersjs/rest-client`` and initializing a client object with a base URL: .. code-block:: 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’); .. raw:: html .. tip:: 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 of ``http://api.feathersjs.com`` would be available as ``app.service('api/v1/messages')``. With a base URL of ``http://api.feathersjs.com/api/v1`` it would be ``app.service('messages')``. params.headers ~~~~~~~~~~~~~~ Request specific headers can be through ``params.headers`` in a service call: .. code:: js app.service('messages').create({ text: 'A message from a REST client' }, { headers: { 'X-Requested-With': 'FeathersJS' } }); params.connection ~~~~~~~~~~~~~~~~~ Allows to pass additional options specific to the AJAX library. ``params.connection.headers`` will be merged with ``params.headers``: .. code:: js app.configure(restClient.request(request)); app.service('messages').get(1, { connection: { followRedirect: false } }); With the ``fetch`` fork `yetch `_ it can also be used to abort requests: .. code:: js const yetch = require('yetch'); const controller = new AbortController(); app.configure(restClient.fetch(yetch)); const promise = app.service('messages').get(1, { connection: { signal: controller.signal } }); promise.abort(); jQuery ~~~~~~ Pass the instance of jQuery (``$``) to ``restClient.jquery``: .. code:: js app.configure(restClient.jquery(window.jQuery)); Or with a module loader: .. code:: js import $ from 'jquery'; app.configure(restClient.jquery($)); Request ~~~~~~~ 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: .. code:: js const request = require('request'); const requestClient = request.defaults({ 'auth': { 'user': 'username', 'pass': 'password', 'sendImmediately': false } }); app.configure(restClient.request(requestClient)); Superagent ~~~~~~~~~~ `Superagent `_ currently works with a default configuration: .. code:: js const superagent = require('superagent'); app.configure(restClient.superagent(superagent)); Axios ~~~~~ `Axios `_ currently works with a default configuration: .. code:: js const axios = require('axios'); app.configure(restClient.axios(axios)); Fetch ~~~~~ Fetch also uses a default configuration: .. code:: js // In Node const fetch = require('node-fetch'); app.configure(restClient.fetch(fetch)); // In modern browsers app.configure(restClient.fetch(window.fetch)); .. _api_client_rest_http-api: HTTP API -------- 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 :doc:`../express`. 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``. .. _api-client-rest-authentication: Authentication ~~~~~~~~~~~~~~ Authenticating HTTP (REST) requests is a two step process. First you have to obtain a JWT from the :doc:`../authentication/server` by POSTing the strategy you want to use: .. code-block:: json :caption: 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: .. code:: bash 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: .. code:: bash curl -H "Content-Type: application/json" -H "Authorization: " -X POST http://localhost:3030/authentication Also see the :doc:`../authentication/jwt` and :doc:`../authentication/local` authentication chapter. find ~~~~ Retrieves a list of all matching resources from the service .. code-block:: sh 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: .. code-block:: sh 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 .. code-block:: sh GET /messages?status[$ne]=active More information about the possible parameters for official database adapters can be found :doc:`../databases/querying`. get ~~~ Retrieve a single resource from the service. .. code-block:: sh GET /messages/1 Will call ``messages.get(1, {})`` on the server. .. code-block:: sh GET /messages/1?fetch=all Will call ``messages.get(1, { query: { fetch: 'all' } })`` on the server. create ~~~~~~ Create a new resource with ``data`` which may also be an array. .. code-block:: sh POST /messages { "text": "I really have to iron" } Will call ``messages.create({ "text": "I really have to iron" }, {})`` on the server. .. code-block:: sh POST /messages [ { "text": "I really have to iron" }, { "text": "Do laundry" } ] update ~~~~~~ Completely replace a single or multiple resources. .. code-block:: sh 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: .. code-block:: sh PUT /messages?complete=false { "complete": true } Will call ``messages.update(null, { "complete": true }, { query: { complete: 'false' } })`` on the server. .. tip:: ``update`` is normally expected to replace an entire resource which is why the database adapters only support ``patch`` for multiple records. patch ~~~~~ Merge the existing data of a single or multiple resources with the new ``data``. .. code-block:: sh 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: .. code-block:: sh 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 :doc:`../databases/adapters` remove ~~~~~~ Remove a single or multiple resources: .. code-block:: sh 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: .. code-block:: sh DELETE /messages?read=true Will call ``messages.remove(null, { query: { read: 'true' } })`` to delete all read messages. .. |GitHub stars| image:: https://img.shields.io/github/stars/feathersjs/rest-client.png?style=social&label=Star :target: https://github.com/feathersjs/rest-client/ .. |npm version| image:: https://img.shields.io/npm/v/@feathersjs/rest-client.png?style=flat-square :target: https://www.npmjs.com/package/@feathersjs/rest-client .. |Changelog| image:: https://img.shields.io/badge/changelog-.md-blue.png?style=flat-square :target: https://github.com/feathersjs/rest-client/blob/master/CHANGELOG.md