Project structure

Project structure with pythonic (Django) style. Build modules with their own controllers, routes, permissions, schemas... If you have any questions about the build or project structure please check out the documentation.

Support

Configuration

Features

To enable or disable features go to .env file and change the variables. When you start the API you will see the log that outputs enabled features

Environment start

There are 3 different starts:

npm run dev (Starts the server in development configuration to develop your application.)

npm test (Starts the server in testing configuration, runs the tests, drops the DB and stops the server.)

npm start (Starts the server in production configuration.)

Environment

To change the environment start with one of the commands above. There are 3 environment setups:

dev (you own computer)

test (testing server)

prod (production server)

I've used dotenv to configure the environment variables with preload. This means that when you start the server with npm it will load automatically the correct variables based on the start command that sets a SERVER_ENVIRONMENT variable and put them inside process.env[VARIABLE]. You can configure your server options inside this file or you can extend them. In order to extend the environment variables, follow de .env template and load them in your JS files as process.env[process.env.SERVER_ENVIRONMENT + '_your_variable'].

Remember not to commit your .env file into version control, it will expose your credentials in open source projects (add it to .gitignore)

Documentation

To generate the api documentation you need to run grunt. If you want to extend the api documentation, just follow the way that is generated the sample documentation:

Go to module (f.e Post inside server folder)

Create routes.doc.js

Describe the routes using Apidocs specification. With this way, you can separate concerns in order to get the code clear and without noise. You can use your own style because grunt will take care to read all the files to find the documentation specification.

Leafing features

Require

I've added two other ways to require libraries inside the project:

`var { Send } = rootRequire('leafing');`` With this way, you can import the Leafing features that I have added to the project without the '../../../..''

var PostRouter = moduleRequire('Post/routes'); With this other way you can import your modules without the '../../../..' because it goes to read directly to the server folder where all modules will stay.

Send

The send feature/middleware is built to generate the response after Boom or Ok and next():

{
statusCode: XXX,
message: 'message X',
data: {}
}

The middleware will know when to send an error or success because we will generate errors inside the request object of the methods callbacks/middlewares/validators/controllers using Boom or Ok. It will be explained in the following lines inside the Flow control section. You can remove this middleware inside server.js.

Form validation

The form validation middleware (see Post's 'CreateForm' for examples) validates all the required parameters for the request using Joi. If there's an error, generate the error with Boom. Then use next() even if there's no errors and you will continue the execution to the next middleware.

Flow control

All the middlewares must start with:

if(!req.error){
} else next()

and you must put your logic inside the if. That is because if req.error exists (created with Boom), it will go to the next middleware until arrives to the Send middleware. (see Post example) If you detect some error, you must use Boom to generate the error. With this way, the error will go next to the Send middleware and return an error response. Otherwise, if there's not an error and you want to send data, use Ok passing the data and the middleware will create a 200 response code, with a Success message and the data to send.

Bad way

The bad way is because if you use some promise based function like mongoose save, the next() will trigger before save. The best way is to call next() when it is done or if there's not an error comming from the upper middleware.

Feel free to use res.json or res.send and avoid this middleware. (Remember to remove it from the server.js file)

Response-Type

Using this header, you can receive the response in different ways:

application/json will send json

application/xml will send json parsed to xml

Testing

You can create tests inside every module. Mocha is prepared to run every tests.js file that founds inside server folder. To run your tests just type npm test in the shell. See Post module for examples.

Continuous integration

I've added a .travis.yml file to use continuous integration with Travis CI. This file has all the configuration needed to test your repository with Travis CI. Just signup in Travis CI web, activate your repository and push a commit. It will start running all the tests for you. You can configure the behaviour needed for your project.

Work Flow

Create module

You can add functionality to you API creating a new folder inside server folder (for example Post). It can be separated in:

controllers.js (where all logic goes)

routes.js (where all routes goes and decides which controllers-permissions-validations needs).

schemas.js (where all mongoose schemas goes)

forms.js (where all parameter validation goes (see Post))

permissions.js (where all permissions goes)

tests.js (where all tests goes)

After that, you can include your routes inside the main routes.js (./server/routes.js) calling them with the moduleRequire indicating the routes file of the module.