/hapijs-realworld-example-app

Real World Hapi.JS + Mongoose backend implementations

Primary LanguageJavaScript

Node/Hapi.JS/Mongoose Example App

Build Status Code Climate Code Climate Coverage Code Style Hapi.JS Mongoose

Example Hapi.JS (Hapi.JS + Mongoose) codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld API spec.

Getting started

Install Node

Install Node.JS LTS version

To get the Node server running locally

  • Clone this repo
  • cd /path/where/your/cloned/the/repo
  • npm install to install all required dependencies
  • Install MongoDB Community Edition (instructions) and run it by executing mongod -d /path/where/you/want/to/store/the/data
  • Run ./generate_secret_key --encoding base64
  • npm start to start the local server
  • The API is available at http://localhost:8080/api

To get the Node server running locally with Docker

  • Install Docker
  • Clone this repo
  • cd /path/where/your/cloned/the/repo
  • Run ./generate_secret_key --encoding base64
  • docker-compose up
  • The API is available at http://localhost:8080/api

Code Overview

Dependencies

  • hapijs - The server for handling and routing HTTP requests
  • hapi-auth-jwt2 - Plugin for validating JWTs for authentication
  • jsonwebtoken - For generating JWTs used by authentication
  • mongoose - For modeling and mapping MongoDB data to javascript
  • mongoose-unique-validator - For handling unique validation errors in Mongoose. Mongoose only handles validation at the document level, so a unique index across a collection will throw an exception at the driver level. The mongoose-unique-validator plugin helps us by formatting the error like a normal mongoose ValidationError.
  • slug - For encoding titles into a URL-friendly format

Application Structure

  • lib/index.js - The entry point to our application. This file bootstrap our HapiJS server. It also requires the routes and models we'll be using in the application.
  • lib/config/ - This folder contains plugins configuration as well as a central location for configuration/environment variables.
  • lib/modules/api/* - This folder contains the routes definitions for our API.

Authentication

Requests are authenticated using the Authorization header with a valid JWT. We use one hapijs pluggin in lib/modules/auth/index.js that can be used to authenticate requests. The hapi-auth-jwt2 plugin using our application's secret and will return a 401 status code if the request cannot be authenticated. The payload of the JWT can then be accessed from request.auth.credentials.user in the endpoint.

HapiJS auth mecanism provide 3 Authentications mode:

  • The { auth: 'jwt' } set authentication to required.
  • The { auth: { mode: 'optional', strategy: 'jwt' } } config options in the same way as { auth: 'jwt' }, but will not return a 401 status code if the request cannot be authenticated (JWT must be valid).
  • The { auth: 'try', strategy: 'jwt' } similar to optional but invalid JWT will pass with request.auth.isAuthenticated set to false and request.auth.credentials set to null.

Error Handling

HapiJS use Boom for errors response that use a particular format response, so we need to reformat it, to meet the Backend API specs errors handling section. So we added a preResponse server extension, to reformat it in lib/modules/api/index.js.

Validations

We use Joi for validating request params/payload and response payload.

Documentation

We use hapi-swagger for the API endpoints documentation. Documentation available at http://localhost:8080/docs.

Contributing

PRs and issues are welcome!

  • Comment one which issue you'd like to do
  • Fork the project then get the project: Getting the project
  • Now you have your own project URL (from your fork)
git remote rename origin upstream
git remote add origin {YOUR_URL}
  • After your first change make a PR with [WIP] (work in progress) added to the title.
  • When your ready for review assign one of us

Credits

The mongoose models come from the node-express-realworld-example-app codebase.