npm package: @otw/rest-route
Description: express util to normalize and conventionalize creation of RESTful routes
Author: Thomas Juster
Latest version: 1.0.0

# @otw/rest-route

Table Of Contents:
- [Motivation](#motivation)
- [JavaScript Usage](#javascript-usage)
- [TypeScript Usage](#typescript-usage)

## Motivation

Conventionalize route naming.

Let the developer manage the rest.

## JavaScript Usage

```js
// routes/tags.js
const { createRestRoute } = require('@otw/rest-route')

// NOTE: request, response and next come from express
exports.tagsRoute = createRestRoute({
  basePath: '/v1', // optional
  singular: 'tag',
  plural: 'tags',
  before: [
    // path is optional, middleware is mandatory
    { path: '/search', middleware: (request, response, next) => parseQueryParams(request, response, next) }
    { middleware: someAuthMiddleware }
  ],

  // at least one of the methods below must be defined
  async getOne (request, response, next, id) {
    /* GET /tags/<id> */
    const data = { id: 1, name: 'first tag' }

    // either return an object containing the status and the data.
    return { status: 200, data }
    // OR use yourself the express response api and return nothing.
    response.status(200).json({ id: 1, name: 'first tag' })
  },
  getMany: async (request, response, next) => { /* GET /resources */ },
  getOne: async (request, response, next, id) => { /* GET /resources/<id> */ },
  find: async (request, response, next) => { /* GET /resources/search?... */ },
  createMany: async (request, response, next) => { /* POST /resources */ },
  replaceOne: async (request, response, next, id) => { /* PUT /resources/<id> */ },
  updatePartiallyOne: async (request, response, next, id) => { /* PATCH /resources/<id> */ },
  deleteOne: async (request, response, next, id) => { /* DELETE /resources/<id> */ },
}))

// app.js
const express = require('express')
const app = express()
const { tagsRoute } = require('./routes/tags')
app.use(tagsRoute)
```

## TypeScript Usage

```ts
// routes/tags.ts

import { createRestRoute, RouteResponse } from '@otw/rest-route'

// NOTE: request, response and next come from express
export const tagsRoute = createRestRoute({
  basePath: '/v1', // optional
  singular: 'tag',
  plural: 'tags',
  before: [
    // path is optional, middleware is mandatory
    { path: '/search', middleware: (request, response, next) => parseQueryParams(request, response, next) }
    { middleware: someAuthMiddleware }
  ],

  // at least one of the methods below must be defined
  async getOne (request, response, next, id): RouteResponse<{ id: number, name: string }> {
    /* GET /tags/<id> */
    const data = { id: 1, name: 'first tag' }

    // either return an object containing the status and the data.
    return { status: 200, data }
    // OR use yourself the express response api and return nothing.
    response.status(200).json({ id: 1, name: 'first tag' })
  },
  async getMany (request, response, next): RouteResponse<DataShape> { /* GET /resources */ },
  async getOne (request, response, next, id): RouteResponse<DataShape> { /* GET /resources/<id> */ },
  async find (request, response, next): RouteResponse<DataShape> { /* GET /resources/search?... */ },
  async createMany (request, response, next): RouteResponse<DataShape> { /* POST /resources */ },
  async replaceOne (request, response, next, id): RouteResponse<DataShape> { /* PUT /resources/<id> */ },
  async updatePartiallyOne (request, response, next, id): RouteResponse<DataShape> { /* PATCH /resources/<id> */ },
  async deleteOne (request, response, next, id): RouteResponse<DataShape> { /* DELETE /resources/<id> */ },
})
```