Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@mersocarlin/node-server

mersocarlin12MIT1.1.0TypeScript support: included

Enhanced fastify server cookie-parser, cors, helmet, rate-limiter and opt-in Mongo DB connection.

api, backend, fastify, node, rest, server

readme

@mersocarlin/node-server

npm version

Enhanced fastify server with cookie-parser, cors, helmet, rate-limiter and opt-in Mongo DB connection.

Motivation

Whenever I write a new node server, I end up creating the same boilerplate using similar express middleware: cookie-parser, helmet, cors, express-rate-limit... not to mention the default error handler for express apps.

Just thought about extracting all that into a single package so I can focus only on the api routes + business logic of my node-server and leave common config to be handled somewhere else.

Install

yarn add @mersocarlin/node-server
npm i @mersocarlin/node-server

What's included

  • fastify-cookie
  • fastify-cors
  • fastify-helmet
  • fastify-rate-limit
  • mongoose connection (opt-in)
  • basic repository for CRUD entities

Usage

import { FastifyInstance } from 'fastify'
import { createServer } from '@mersocarlin/node-server'

/**
 * Setup custom routes and/or plugins
 **/

function onRegisterPlugins(fastifyInstance: FastifyInstance) {
  fastifyInstance.post('/signin', async () => {
    return {
      loggedIn: true,
    }
  })

  fastifyInstance.get('/users/:userId', async (request) => {
    return {
      id: request.params.userId,
    }
  })
}

import { createServer } from '@mersocarlin/node-server'

const fastifyServer = createServer({
  appName: 'my-custom-server',
  onRegisterPlugins,
  version: '1.0.0',
})

async function startServer() {
  try {
    await testFastifyServer.listen(PORT, '0.0.0.0')
  } catch (err) {
    testFastifyServer.log.error(err)
    process.exit(1)
  }
}

Note: If you have a single node-server you might not need this package at all. In my case though, I have a few APIs spread across different repos and I realised they all share the same initial config.

Mongo repository

Create Entity types

import { Document } from 'mongoose'

interface IEntity {
  name: string
  value: string
}

// Used for querying DB
interface IEntityQuery {
  name?: string
  value?: string
}

interface IMyDocument extends Document {
  name: string
  value: string
}

Create schema and model

import mongoose, { Schema } from 'mongoose'

const MySchema = new Schema({
  name: { type: String, required: true },
  value: { type: String, required: true },
})

const myModel = mongoose.model<IMyDocument>('mymodel', MySchema)

Create repository and start CRUD

import { createRepository } from '@mersocarlin/node-server'

const modelRepository = createRepository<IMyDocument, IEntityQuery, IEntity>(
  myModel
)

// Save to DB
const dbEntity = await modelRepository.create({
  name: 'Test',
  value: 'Some value',
})

// Update
await modelRepository.update(dbEntity._id, {
  name: 'New Name',
  value: dbEntity.value,
})

// List
const allEntities = await modelRepository.find({})
const byName = await modelRepository.find({ name: 'New name' })

// Delete
await modelRepository.remove(dbEntity._id)

Response Time

Built-in

import { createServer } from '@mersocarlin/node-server'
import appRoutes from 'path/to/appRoutes.js'

const app = createServer({
  appName: 'my-custom-server',
  onResponseTime: ({ duration, requestName }) => {
    console.log(`${requestName} took ${duration}ms`)
  },
  routesHandler: appRoutes,
  version: '1.0.0',
})

API

createServer

Prop Type Default Description
appName String | Your server or app name. Ex: my-rest-service
healthcheckPath String /healthcheck Defines healthcheck endpont for node server
mongoDBConfig Object | Defines Mongo DB configuration for database connection
onResponseTime Function | Custom callback to track response time of each request
onRegisterPlugins Function | Custom callback setup your custom routes and plugins
rateLimitConfig Object { windowMs: 15 * 60 * 1000, max: 100 } Rate limit config as described in https://www.npmjs.com/package/express-rate-limit
version String | Your server's version printed out in healthcheckPath endpoint