RESTful API design

RESTful API design

There are four main kind of operations when working with a database: Create, Read, Update and Delete (CRUD). However, databases are usually not exposed directly to the clients. Instead, those operations are performed by a server side application with a client-facing API. The most common type of APIs nowadays are based on HTTP. An HTTP API can be built with complete freedom. However, guidelines for best-practice HTTP API design have been created. An API following those guidlines is called a REST (or RESTful) API.

One core concept behind a RESTful API is to use HTTP verbs (methods) and routes correctly. The usage of verbs follows the following patterns:

  • Database operation: Create ⬄ HTTP method: POST

  • Database operation: Read⬄ HTTP method: GET

  • Database operation: Update⬄ HTTP method: PUT

  • Database operation: Delete⬄ HTTP method: DELETE

Furthermore, all operations regarding a database item should have the same route, with only the method changing with respect to the operation. For example, an API managing blog articles would have the following design:

  • POST /articles ⇨ Create an article

  • GET /articles/{Article ID} ⇨ Read an article

  • PUT /articles/{Article ID} ⇨ Update an article

  • DELETE /articles/{Article ID} ⇨ Deletes an article

Here, the ID of the article is passed as a subroute of the /articles route. This is an analogy to how articles would all be stored in a directory called articles. Similary, creating an article can be seen as posting an article in the articles directory.

Practical example

Here is a simple example build with Express:

// Import the express package
const express = require('express')
const cors = require('cors')

// Import the functions related to article management
const article_controllers = require('./controllers/articles.js')

// Instanciate an express app
const app = express()

// Using the cors module to deal with Cross-Origin control
app.use(cors())

// Specify port on which the application will listen
const port = 3000

// Define routes
app.route('/articles')
  .post(article_controllers.create)

app.route('/articles/:article_id')
  .get(article_controllers.read)
  .put(article_controllers.update)
  .put(article_controllers.delete)

// Start listening on the defined port
app.listen(port, () => console.log(`Example app listening on port ${port}`))