Build a Node.js CRUD App Using React and FeathersJS

Build a Node.js CRUD App Using React and FeathersJS

Building a modern project requires splitting the logic into front-end and back-end code. The reason behind this move is to promote code re-usability. For example, we may need to build a native mobile application that accesses the back-end API. Or we may be developing a module that will be part of a large modular platform.

An operator, sat at an old-fashioned telephone switchboard - Build a CRUD App Using React, Redux and FeathersJS

The popular way of building a server-side API is to use Node.js with a library like Express or Restify. These libraries make creating RESTful routes easy. The problem with these libraries is that we’ll find ourselves writing a ton of repetitive code. We’ll also need to write code for authorization and other middleware logic.

To escape this dilemma, we can use a framework like Feathers to help us generate an API in just a few commands.

What makes Feathers amazing is its simplicity. The entire framework is modular and we only need to install the features we need. Feathers itself is a thin wrapper built on top of Express, where they’ve added new features — services and hooks. Feathers also allows us to effortlessly send and receive data over WebSockets.


To follow along with this tutorial, you’ll need the following things installed on your machine:

  • Node.js v12+ and an up-to-date version of npm. Check this tutorial if you need help getting set up.
  • MongoDB v4.2+. Check this tutorial if you need help getting set up.
  • Yarn package manager — installed using npm i -g yarn.

It will also help if you’re familiar with the following topics:

  • how to write modern JavaScript
  • flow control in modern JavaScript (e.g. async ... await)
  • the basics of React
  • the basics of REST APIs

Also, please note that you can find the completed project code on GitHub.

Scaffold the App

We’re going to build a CRUD contact manager application using Node.js, React, Feathers and MongoDB.

In this tutorial, I’ll show you how to build the application from the bottom up. We’ll kick-start our project using the popular create-react-app tool.

You can install it like so:

npm install -g create-react-app

Then create a new project:

# scaffold a new react project
create-react-app react-contact-manager
cd react-contact-manager

# delete unnecessary files
rm src/logo.svg src/App.css src/serviceWorker.js

Use your favorite code editor and remove all the content in src/index.css. Then open src/App.js and rewrite the code like this:

import React from 'react';

const App = () => 
  return (
      <h1>Contact Manager</h1>

export default App;

Run yarn start from the react-contact-manager directory to start the project. Your browser should automatically open http://localhost:3000 and you should see the heading “Contact Manager”. Quickly check the console tab to ensure that the project is running cleanly with no warnings or errors, and if everything is running smoothly, use Ctrl + C to stop the server.

Build the API Server with Feathers

Let’s proceed with generating the back-end API for our CRUD project using the feathers-cli tool:

# Install Feathers command-line tool
npm install @feathersjs/cli -g

# Create directory for the back-end code
# Run this command in the `react-contact-manager` directory
mkdir backend
cd backend

# Generate a feathers back-end API server
feathers generate app

? Do you want to use JavaScript or TypeScript? JavaScript
? Project name backend
? Description contacts API server
? What folder should the source files live in? src
? Which package manager are you using (has to be installed globally)? Yarn
? What type of API are you making? REST, Realtime via
? Which testing framework do you prefer? Mocha + assert
? This app uses authentication No

# Ensure Mongodb is running
sudo service mongod start
sudo service mongod status

● mongod.service - MongoDB Database Server
   Loaded: loaded (/lib/systemd/system/mongod.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2020-01-22 11:22:51 EAT; 6s ago
 Main PID: 13571 (mongod)
   CGroup: /system.slice/mongod.service
           └─13571 /usr/bin/mongod --config /etc/mongod.conf

# Generate RESTful routes for Contact Model
feathers generate service

? What kind of service is it? Mongoose
? What is the name of the service? contacts
? Which path should the service be registered on? /contacts
? What is the database connection string? mongodb://localhost:27017/contactsdb

# Install email and unique field validation
yarn add mongoose-type-email

Let’s open backend/config/default.json. This is where we can configure our MongoDB connection parameters and other settings. Change the default paginate value to 50, since front-end pagination won’t be covered in this tutorial:

  "host": "localhost",
  "port": 3030,
  "public": "../public/",
    "default": 50,
    "max": 50
  "mongodb": "mongodb://localhost:27017/contactsdb"

Open backend/src/models/contact.model.js and update the code as follows:


module.exports = function (app) {
  const modelName = 'contacts';
  const mongooseClient = app.get('mongooseClient');
  const  Schema  = mongooseClient;
  const schema = new Schema({
    name : 
        type: String,
        required: [true, 'First Name is required']
        type: String,
        required: false
    email : 
      type: mongooseClient.SchemaTypes.Email,
      required: [true, 'Email is required']
    phone : 
      type: String,
      required: [true, 'Phone is required'],
        validator: function(v) 
          return /^+(?:[0-9] ?)6,14[0-9]$/.test(v);
        message: 'VALUE is not a valid international phone number!'
    timestamps: true


  return  mongooseClient.model(modelName,  schema);

Mongoose introduces a new feature called timestamps, which inserts two new fields for you — createdAt and updatedAt. These two fields will be populated automatically whenever we create or update a record. We’ve also installed the mongoose-type-email plugin to perform email validation on the server.

Now, open backend/src/mongoose.js and change this line:

 useCreateIndex: true, useNewUrlParser: true 


 useCreateIndex: true, useNewUrlParser: true, useUnifiedTopology: true 

This will squash an annoying deprecation warning.

Open a new terminal and execute yarn test inside the backend directory. You should have all the tests running successfully. Then, go ahead and execute yarn start to start the back-end server. Once the server has initialized, it should print 'Feathers application started on localhost:3030' to the console.

Launch your browser and access the URL http://localhost:3030/contacts. You should expect to receive the following JSON response:


Test the API with Postwoman

Now let’s use Postwoman to confirm all of our endpoints are working properly.

First, let’s create a contact. This link will open Postwoman with everything set up to send a POST request to the /contacts endpoint. Make sure Raw input enabled is set to on, then press the green Send button to create a new contact. The response should be something like this:

  "_id": "5e36f3eb8828f64ac1b2166c",
    "first": "Tony",
    "last": "Stark"
  "phone": "+18138683770",
  "email": "",
  "createdAt": "2020-02-02T16:08:11.742Z",
  "updatedAt": "2020-02-02T16:08:11.742Z",
  "__v": 0

Now let’s retrieve our newly created contact. This link will open Postwoman ready to send a GET request to the /contacts endpoint. When you press the Send button, you should get a response like this:

  "total": 1,
  "limit": 50,
  "skip": 0,
  "data": [
      "_id": "5e36f3eb8828f64ac1b2166c",
        "first": "Tony",
        "last": "Stark"
      "phone": "+18138683770",
      "email": "",
      "createdAt": "2020-02-02T16:08:11.742Z",
      "updatedAt": "2020-02-02T16:08:11.742Z",
      "__v": 0

We can show an individual contact in Postwoman by sending a GET request to http://localhost:3030/contacts/<_id>. The _id field will always be unique, so you’ll need to copy it out of the response you received in the previous step. This is the link for the above example. Pressing Send will show the contact.

We can update a contact by sending a PUT request to http://localhost:3030/contacts/<_id> and passing it the updated data as JSON. This is the link for the above example. Pressing Send will update the contact.

Finally we can remove our contact by sending a DELETE request to the same address — that is, http://localhost:3030/contacts/<_id>. This is the link for the above example. Pressing Send will delete the contact.

Postwoman is an very versatile tool and I encourage you to use it to satisfy yourself that your API is working as expected, before moving on to the next step.

Continue reading
Build a Node.js CRUD App Using React and FeathersJS
on SitePoint.

Leave a Reply

Your email address will not be published. Required fields are marked *