HomeAbout MeContact

Simpler Node.js REST API structure with express-formidable

By Daniele Molinari
Published in Tutorials
June 21, 2022
2 min read
Simpler Node.js REST API structure with express-formidable

Which is the optimal structure for a REST API? Do you really need to bother about HTTP methods? Do we really need PUT and DELETE?

HTTP methods

First of all: do we really need PUT and DELETE?

Most REST API courses will tell you to match CRUD actions with HTTP methods: GET for getting data, POST for creating data, PUT or PATCH for editing data, DELETE for removing data.

The simple answer is no. There is no reason why you, as backend developer, should be limiting the capabilities of your API just to match HTTP methods.

There is no need to force a single HTTP method (such as POST) either. Why would you? Such a choice does not add value and it does not add security to your API.

The optimal solution is the easiest one: just support them all.

const Express = require('express');

const app = new Express();

// API for a library of books
app.use('/books/add', (req, res) => res.status(200).json({ message: 'added' }) );
app.use('/books/edit', (req, res) => res.status(200).json({ message: 'edited' }) );
app.use('/books/remove', (req, res) => res.status(200).json({ message: 'removed' }) );
app.use('/books/search', (req, res) => res.status(200).json({ message: 'list results' }) );

It will be up to the frontend developer to choose whether to send a GET, POST, PUT, PATCH or DELETE request to each endpoint, causing less confusion and delivering more value with less code.

Naysayers will note that this breaks the RESTful pattern.

It does not. All actions relevant to books are still grouped under the “books” path and there is a specific request for each action. That’s the only thing that matters.

Introducing express-formidable

There are several ways to send data to an express backend:

  • FormData
  • urlencoded
  • JSON payload
  • multipart/form-data (generally used for uploading files)

Normally, you would have to use a different body parser for each one of these formats. For example body-parser and multer.

Formidable, on the other hand, is an all-in-one package! Just add it to your project to support all possible configurations:

const Express = require('express');
const formidable = require('express-formidable');

const app = new Express();

app.use(formidable());

Now, when you send data to the backend (whether FormData, urlencoded or JSON), you can access it from the req.fields object:

const Express = require('express');
const formidable = require('express-formidable');

const app = new Express();

app.use(formidable());

app.use('/login', (req, res) => {
    const username = req.fields.username;
    const password = req.fields.password;
});

Also, when you send files to the backend (with multipart/form-data), you can access them from the req.files object:

const Express = require('express');
const formidable = require('express-formidable');

const app = new Express();

app.use(formidable());

app.use('/upload', (req, res) => {
    const file = req.files.file; // assuming that "file" is the FormData key
    const sameFileDifferentSyntax = req.files['file'];
});

Folder structure

In my opinion, the best way to group routes in ExpressJS is to use index.js as folder indexes. Let’s see this via example.

Let’s say that we have a books CRUD API and an authors CRUD API. We are going to have the following routes:

  • /api/v1/routes/books/add
  • /api/v1/routes/books/edit
  • /api/v1/routes/books/remove
  • /api/v1/routes/books/search
  • /api/v1/routes/authors/add
  • /api/v1/routes/authors/edit
  • /api/v1/routes/authors/remove
  • /api/v1/routes/authors/search

We are then going to organize our routes in the following way:

  • routes - folder containing all routes
    • books - folder for book routes
      • index.js - index file for this folder
      • add.js - add a book
      • edit.js - edit a book
      • remove.js - remove a book
      • search.js - search through books
    • authors - folder for author routes
      • index.js - index file for this folder
      • add.js - add an author
      • edit.js - edit an author
      • remove.js - remove an author
      • search.js - search through authors

This is what an index file looks like:

const express = require('express');
const add = require('./add');
const edit = require('./edit');
const remove = require('./remove');
const search = require('./search');

const router = express.Router();

router.use('/add', add);
router.use('/edit', edit);
router.use('/remove', remove);
router.use('/search', search);

module.exports = router;

Wrapping up

As you can see, the best API structure is one where objects have a clearly recognizable path (as folders on disk too), but there are no constraints on HTTP methods and data payload format. express-formidable comes to our rescue with parsing data formats.

You can check out the full example source code here: Github repo link (express-api-structure)


Tags

#node#express#formidable
Previous Article
Approaching the Metaverse - What to expect?
Daniele Molinari

Daniele Molinari

Lead Software Engineer

Topics

Personal Growth
Tutorials
Insights

Quick Links

About MeContact Me

Social Media