A REST API server

Our database connector will now function as a full fledged REST API server. We need only add a HTTP server to it.

HTTP servers. Feathers is currently tied into the popular HTTP server framework Express. Future versions will support multiple frameworks, starting with koa.

Working example

Implementing a REST API server

This is our previous example with the database method calls removed, and with an Express server added.


// Example - Create REST API

const expressServerConfig = require('../common/expressServerConfig');
const expressMiddleware = require('../common/expressMiddleware');
const rest = require('feathers-rest');
const NeDB = require('nedb');
const path = require('path');
const service = require('feathers-nedb');

const app = expressServerConfig()
  .configure(rest())
  .configure(services)
  .configure(expressMiddleware);

const server = app.listen(3030);
server.on('listening', () => console.log(`Feathers application started on port 3030`));

function services() {
  this.use('/users', service({ Model: userModel() }));
}

function userModel() {
  return new NeDB({
    filename: path.join('examples', 'step', 'data', 'users.db'),
    autoload: true
  });
}

The Express server common/expressServerConfig.js is configured as follows.


const bodyParser = require('body-parser');
const compress = require('compression');
const cors = require('cors');
const path = require('path');
const feathers = require('feathers');

module.exports = () => {
  const app = feathers()
    .use(compress())
    .options('*', cors())
    .use(cors())
    .use('/', feathers.static(path.join(__dirname, 'public')))
    .use(bodyParser.json())
    .use(bodyParser.urlencoded({ extended: true }));

  return app;
};

The Express middleware common/expressMiddleware/index.js handles logging, pages not found, and general errors.

'use strict';

const handler = require('feathers-errors/handler');
const notFound = require('./not-found-handler');
const logger = require('./logger');

module.exports = function() {
  const app = this;

  app.use(notFound());
  app.use(logger(app));
  app.use(handler());
};

Boilerplate. The server configuration and middleware are standard Express. They have little to do with Feathers other than to feed REST requests to it.

Running the server

We can now make REST API calls to the server.

In the previous example we created 3 user items and then printed the user file. We can now do the same thing, but using REST, with curl commands:

printf "\nPOST Jane Doe\n"
curl -H "Content-Type: application/json" -X POST -d '{"email":"jane.doe@gmail.com","password":"X2y6","role":"admin"}' http://localhost:3030/users
printf "\nPOST John Doe\n"
curl -H "Content-Type: application/json" -X POST -d '{"email":"john.doe@gmail.com","password":"i6He","role":"user"}' http://localhost:3030/users
printf "\nPOST Judy Doe\n"
curl -H "Content-Type: application/json" -X POST -d '{"email":"judy.doe@gmail.com","password":"7jHw","role":"user"}' http://localhost:3030/users
printf "\nGET all users\n"
curl -X GET http://localhost:3030/users

First, start the server by running node ./examples/step/01/rest/1.js on one terminal.

Then run the curl commands with ./examples/step/01/rest/curl-requests.sh on another terminal.

Results

That console displays:

feathers-guide$ ./examples/step/01/rest/curl-requests.sh
POST Jane Doe
{"email":"jane.doe@gmail.com","password":"X2y6","role":"admin","_id":"sbkXV7LVkMhx1NyY"}
POST John Doe
{"email":"john.doe@gmail.com","password":"i6He","role":"user","_id":"uKhqOp4R4hABw9oO"}
POST Judy Doe
{"email":"judy.doe@gmail.com","password":"7jHw","role":"user","_id":"pvcmh9X2i9VZgqWJ"}
GET all users
[
 {"email":"judy.doe@gmail.com","password":"7jHw","role":"user","_id":"pvcmh9X2i9VZgqWJ"},
 {"email"::"jane.doe@gmail.com","password":"X2y6","role":"admin","_id":"sbkXV7LVkMhx1NyY"},
 {"email":"john.doe@gmail.com","password":"i6He","role":"user","_id":"uKhqOp4R4hABw9oO"}
]

Feathers. REST API calls are automatically converted into Feathers database method calls like the users.create() and users.find() methods we used in the previous example. How's that for convenience?

Is anything wrong, unclear, missing?

Leave a comment.

results matching ""

    No results matching ""