Coder Social home page Coder Social logo

beuth-hapi-restful-api's Introduction

hapi Seed Project - MVC / RDMS

This project is an application skeleton for a typical hapi RESTful API. You can use it to quickly bootstrap your hapi API projects and be ready to code the core of your App within minutes.

Features

  • ES6
  • MVC file structure + base classes (a'la Rails/Laravel/Django)
  • Relational Database support (via knex.js)
    • MySQL
    • PostgreSQL
    • SQLite3
    • Schema Migrations and Seeding
  • Pre-configured environments (local, dev, staging, production)
  • Powerful payload validations via joi
  • Auto-generated documentation (lout)
  • Unit & API/REST tests examples (Jasmine2)
  • RESTful outputs
  • Improved Logging and Remote debugging
  • Healthcheck end-point
  • Gulp for workflows (ie. watch files changes and launch local server)
  • + all features and plugin's from hapi

Prerequisites

Getting started

  1. Fork this repo (top right button) and clone it form your account (replace YOUR-USERNAME)
git clone https://github.com/YOUR-USERNAME/hapijs-seed-mvc.git
cd hapijs-seed-mvc
  1. Install the dependencies
npm install
  1. Create a Database. In case of PostgreSQL, go into your psql terminal and enter:
CREATE DATABASE todo;
  1. Duplicate config/local.js.default and rename it into config/local.js. Then edit and enter your database settings (DB name goes into config/default.js).

  2. Migrate the database and seed it

gulp db:migrate
gulp db:seed
  1. Run the app
gulp

(if NODE_ENV wasn't exported, then local is going to be used)

  1. Go to: http://localhost:3000

Database Migration and Seed

Knex is taking care of migrating the DB schema and populating (seeding) the tables. The documentation is available here: http://knexjs.org/#Migrations-CLI.

Migration

Knex will keep a history of your executed migrations and save them into the DB table knex_migrations.

You have to save the migrations in database/migrations/. It's recommended to prefix the files with an incrementing number or timestamp. Otherwise it might be hard to keep track of the order the DB changes were executed.

gulp db:migrate

Rollback

You can rollback the last group of executed migrations:

gulp db:rollback

Seeds

You can populate your DB tables by executing seed files through Knex. Seed files are saved in database/seeds/.

gulp db:seed

Tests

This project has to kind of tests: UnitTest and API Tests. For both Jasmine2 is being used. If you want to execute both kind of tests at the same time, you can run:

gulp test

UnitTest's

UnitTest's are stored within the folders of the implementation and contain .spec as part of their file name. For instance src/controllers/main.controller.js and src/controllers/main.controller.spec.js. This pattern makes it easier not to forget to write tests :)

You can execute them by running:

gulp test:unit

API Tests

API Tests are stored in /tests/api and are meant to test the RESTful end-points of your App.

In order to test the server responses you have to start the server in a new terminal/tab:

cd /path/to/your/project
gulp

Then execute your API Tests by running:

gulp test:api

API Documentation

The auto-generated API documentation is provided by lout and it's based on the configuration of every route (/routes).

http://localhost:3000/docs


Build ToDo API

  1. Extend the model class: ToDoList (src/models/ToDoList.js)
/**
 * Constructor
 */
constructor() {
  let tableName = 'todo_lists'
  super(tableName)
}
  1. Extend the controller class: ToDoListsController src/controllers/todo_lists.controller.js
/**
 * Constructor
 */
constructor() {
  let notFoundMsg = `ToDo List not found`

  super(notFoundMsg)
  this.ToDoList = new ToDoList()
}

/**
 * Retrieve the list of all ToDo lists
 */
index(request, reply) {
  this.ToDoList.findAll()
    .then(reply)
    .catch((err) => reply(this.Boom.wrap(err)))
}

/**
 * Retrieve a single ToDo list
 */
view(request, reply) {
  let id = request.params.id

  this.ToDoList.findById(id)
    .then((response) => this.replyOnResponse(response, reply))
    .catch((err) => reply(this.Boom.wrap(err)))
}
  1. Export index() and view() end-points in src/routes/todo_lists.routes.js
//
// Export public end-points
//
export default [
  routes.index(),
  routes.view()
]
  1. Lets test it:
curl localhost:3000/todo-lists

curl localhost:3000/todo-lists/1
  1. Extend the controller class with create(), update() and remove(): ToDoListsController src/controllers/todo_lists.controller.js
/**
 * Create a new ToDo list
 */
create(request, reply) {
  let data = request.payload

  this.ToDoList.save(data)
    .then(reply)
    .catch((err) => reply(this.Boom.wrap(err)))
}

/**
 * Update an existing ToDo list
 */
update(request, reply) {
  let id = request.params.id
    , data = request.payload

  this.ToDoList.update(id, data)
    .then((response) => this.replyOnResponse(response, reply))
    .catch((err) => reply(this.Boom.wrap(err)))
}

/**
 * Delete a ToDo list
 */
remove(request, reply) {
  let id = request.params.id

  this.ToDoList.del(id)
    .then((response) => this.replyOnResponse(response, reply))
    .catch((err) => reply(this.Boom.wrap(err)))
}
  1. Extend ToDo List routes class with create() and update(): src/routes/todo_lists.routes.js
/**
 * Create a new ToDo list
 *
 * @return {object}
 */
create() {
  // Get route settings from parent
  let route = super.create()

  // Update end-point description (used in Documentation)
  route.config.description = 'Create a new ToDo list'

  // Add validations for POST payload
  route.config.validate.payload = {
    name: this.joi.string().required().description('ToDo list name')
  }

  return route
}

/**
 * Update an existing ToDo list
 *
 * @return {object}
 */
update() {
  // Get route settings from parent
  let route = super.update()

  // Update end-point description (used in Documentation)
  route.config.description = 'Update an existing ToDo list'

  // Add validations for POST payload
  route.config.validate.payload = {
    name: this.joi.string().description('ToDo list name')
  }

  return route
}
  1. Export create(), update() and remove() end-points in src/routes/todo_lists.routes.js
//
// Export public end-points
//
export default [
  routes.index(),
  routes.view(),
  routes.create(),
  routes.update(),
  routes.remove()
]
  1. Lets test it:
curl localhost:3000/todo-lists

curl -X PUT localhost:3000/todo-lists/1 -d name=Homework

curl -X POST localhost:3000/todo-lists -d name=Uni\ Stuff  

curl -X DELETE localhost:3000/todo-lists/1
  1. Activate tests for ToDo Lists (*.spec.js files)

  2. Find out how to continue with ToDo's ;)


More

Remote debug setup

The configuration allows to setup the TCP debug port for node remote debug functionality (5858 by default). This should be overridden when multiple micro node.js services are running on a local machine in a typical dev environment setup.

Remote debug can be used the command line using node debug or with IDEs supporting this feature.

Go to Staging/Production

Deploy your App on a server and you can use forever to run it. forever is used to run your App continuously. It will automatically restart if it crashes.

[sudo] npm install forever -g
cd /path/to/your/project

export NODE_ENV=staging
forever start index.js

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.


TL;DR :)

https://github.com/cbmono/hapijs-seed-mvc

beuth-hapi-restful-api's People

Contributors

cbmono avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.