Skip to content

wolfpilot/demotivator-rest-api

Repository files navigation

Demotivator REST API

A mostly complete example of an Express server with PostgreSQL db and a bunch of other features sprinkled on top.

Table of contents

General info

Why do today what you can put off until tomorrow?

It's a joke, of course, don't take it seriously.

The whole idea behind this was to get my hands dirty with setting up APIs: best practices, scaling, maintenance and security vulnerabilities.

Demo

For more details and full CRUD examples, see API.

Postman

screenshot

Features (done)

  • Architecture

    • MVC
    • RESTful API
    • CRUD
  • Middleware

    • Debug console logger
    • Request and error loggers with daily rotated files
    • Request body content type validation
    • Schema-based error validation
    • Rate limited
  • Config

    • Automated seeding from SQL-like files
    • Import path aliases using tsconfig-paths
    • Localised .env files using dotenv-flow

Features (TBA)

  • Prepared statements (security)
  • Request throttling (rate limitting, CAPTCHA)
  • Response document pagination (cursor)
  • Protected routes (not necessary atm.)
  • Reversible test transactions (no-stress DB testing)

Technologies

API

Either start your own server and visit http://localhost:9000 or https://wolfpilot-demotivator-rest-api.onrender.com.

Endpoints

# Quotes
  GET    /quotes     - fetch all quotes
  POST   /quotes     - create new quote
  GET    /quotes/:id - fetch single quote
  DELETE /quotes/:id - delete single quote

Examples

Simply copy-paste the following examples in your bash terminal making sure to separate newlines with "\" on Mac or "^" on Windows.

If running locally, please use "http://localhost:9000" instead. Alternatively, import the collection below in your own Postman instance and have some fun!

Run In Postman

List paginated quotes

  • GET /quotes
curl \
  -H "Content-Type: application/json" \
  -X GET \
  https://wolfpilot-demotivator-rest-api.onrender.com/quotes?limit=2\&page=4

Query params:
  limit
    # The amount of records to be fetched from the DB.
    type: string
    min: 2
    max: 100
  page
    # The index of the groupd of records being requested.
    type: string
    min: 1
    max: dynamic

Get a specific quote

  • POST /quotes
curl \
  -X GET \
  https://wolfpilot-demotivator-rest-api.onrender.com/quotes/3

Create a new quote

  • GET /quotes/:id
curl \
  -H 'Content-Type: application/json' \
  -X POST \
  -d '{
    "author": "Steven Wright",
    "text": "The light at the end of the tunnel has been turned off due to budget cuts."
  }' \
  https://wolfpilot-demotivator-rest-api.onrender.com/quotes

Body:
  # The author of the quote.
  author
    type: string
  # The quote itself.
  text
    type: string

Delete a quote

  • DELETE /quotes/:id
curl \
  -X DELETE \
  https://wolfpilot-demotivator-rest-api.onrender.com/quotes/5

Security

Although several precautions have been taken such as restricting user privileges (no "superuser" or "create role"), validating requests (ex: checking that ID strings only coerce to numbers and that they're higher than 0) and using parameterised queries, there are still plenty of improvements that can be made to a public API such as this.

Other measures that comes to mind are:

  • Prepared statements
  • Checking payloads for potentially dangerous SQL statements
  • Throttling requests to prevent flooding

For the purpose of this exercise however, I will say this is enough. If you want to destroy the 10 rows of data being stored, be my guest, Mr. Robot! Just leave me a nice message afterwards.

Getting started

Requirements

Optionally, install Postico to get a visual on your DB structure, data and execute queries.

Installation

$ git clone https://github.com/wolfpilot/demotivator-rest-api.git
$ cd demotivator-rest-api
$ yarn

Steps

# 1. Update your env config, see .env for guidance.

# 2. Start an instance of PostgreSQL

# 3. Run the API service
$ yarn start:dev

Workflow (personal notes)

PostgreSQL shell commands

"psql" to connect to your db and user
"\l" to list all databases
"\c db_name" to connect to db_name
"\dt" to inspect tables
"\du+" to see table of users
"\q" to quit

Resources

License

This project is licensed under the MIT License.

Releases

No releases published

Packages

No packages published

Languages