DEV Community

Cover image for Build a Simple Node.js Server with Full CRUD Capability
Chukwuma Anyadike
Chukwuma Anyadike

Posted on • Edited on

Build a Simple Node.js Server with Full CRUD Capability

I wanted to create a prototypical todo application for some reason. The main reason that I wanted to do this was so that I could learn to create a server using node.js. Basically I wanted to create a backend with JavaScript. It was surprisingly simple. Let's do a quick walkthrough.

The Set Up

1) Create a Directory

mkdir todos-server
Enter fullscreen mode Exit fullscreen mode

2) Create the server file in todos-server folder (in this case I call it index.js)

touch index.js
Enter fullscreen mode Exit fullscreen mode

3) Initialize NPM

npm init -y
Enter fullscreen mode Exit fullscreen mode

This creates a package.json file with the following content

{
  "name": "todos-server",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

Enter fullscreen mode Exit fullscreen mode

4) Install Express

npm install express
Enter fullscreen mode Exit fullscreen mode

After installing Express, go to the package.json file and include โ€œtypeโ€: โ€œmoduleโ€. This allows ES6 module syntax (import/export) instead of the default common.js syntax (require).

Add Server Code in index.js file and start server.

1) Write server code in index.js file.

import express from 'express'; //allows http requests
import bodyParser from 'body-parser';  //allows us to take in an incoming request body
import todoRoutes from './routes/todos.js' //see todos.js file below

const app = express();
const PORT = 5000 //this is the port we will be listening on

app.use(bodyParser.json());
app.use('/todos', todoRoutes); //specify the path and router handler

app.get('/', (req, res) => {
    res.send('HELLO FROM HOMEPAGE');
})

app.listen(PORT, () => console.log(`Server running on port: http://localhost:${PORT}`));
Enter fullscreen mode Exit fullscreen mode

2) Start the server

node index.js
Enter fullscreen mode Exit fullscreen mode

3) Install Nodemon (This is optional). It is nice because it allows you to make changes without having to manually refresh the server.

npm install nodemon
Enter fullscreen mode Exit fullscreen mode

In the package.json file under "scripts" add this line

"start": "nodemon index.js"
Enter fullscreen mode Exit fullscreen mode

Now you can start your server using this command

npm start
Enter fullscreen mode Exit fullscreen mode

Create router folder, add routing file called todos.js with routes and CRUD functions

import express from 'express';
import { v4 as uuidv4 } from 'uuid';

const router = express.Router();

// Mock database
let todos = [];

// Getting the list of todos from the mock database
router.get('/', (req, res) => {
    res.send(todos);
})

// Getting a todo from the mock database
router.get('/:id', (req, res) => {
    const id = req.params.id;
    const todo = todos.find(todo => todo.id === id);
    if (todo)
        res.send(todo);
    else res.send('Todo not found');
})

// Adding a new todo to our mock database
router.post('/', (req, res) => {
    const todo = req.body;
    todos.push({ ...todo, id: uuidv4() });
    res.send(`${todo.task} has been added to the Database`);
})

// Changing an existing todo in our mock database
router.put('/:id', (req, res) => {
    const id = req.params.id;
    const updatedTodo = req.body;
    todos = todos.map(todo => todo.id === id ? updatedTodo : todo);
    res.send(`${id} has been changed in the Database`);
})

// Deleting a todo from our mock database
router.delete('/:id', (req, res) => {
    const id = req.params.id;
    todos = todos.filter(todo => todo.id !== id)
    res.send(`${id} deleted successfully`);
})

export default router
Enter fullscreen mode Exit fullscreen mode

HTTP Requests (CRUD Functions)

  • router.get()
  • router.post()
  • router.put() or router.patch()
  • router.delete()

These HTTP requests take two arguments.
1) A path
2) A callback function with req and res as arguments

With req and res we can take advantage of requests and responses.

  • req.body allows us to retrieve information to add to or edit our database.
  • req.params.id allows retrieval of the id value of our route.
  • res.send() allows our server to send a response.

Of note, import { v4 as uuidv4 } from 'uuid' allows us to generate unique ids for each todo.

Now that the server and routing files are complete I strongly encourage you to test these HTTP requests in the browser and/or with Postman. Overall, I found that it was easy to create a backend this way. The major pitfall is that none of that data is persisted to an actual database (SQL or noSQL). However, it can be used to provide data for a front end application. Now all I have to do is write the front end appplication. That's all folks.

Top comments (0)