Baaaes is an opinionated, fully fleshed-out API server boilerplate based on ExpressJS and Sequelize with working examples and tests - you just have to jump in and modify it to your needs. It makes extensive use of async
/await
to eliminate callback hell completely and make Javascript your bae.
- Download the zip package and unzip it somewhere (cloning is not recommended for normal use)
- Run
npm install
- Copy
.env.example
to.env
and add your Postgres DB configuration - If you need HTTPS support, run
npm run makecert
You should be ready to go now! Start the server with npm start
and run tests with npm test
.
The basic code was created with express-generator
, then the following changes were made:
- Complete conversion to native Node ES6 syntax.
- HTTPS support included, and you can generate self-signed certificates for development by running
npm run makecert
. Note that you will see warning messages; use Let's encrypt and a real domain name to avoid this. - CORS support baked in with configuration examples.
- Differentiated environments (
development
,test
andproduction
) defined by theAPP_ENV
environment variable. - Handlebars templates for HTML views.
- Sequelize as ORM, along with an example model implementation making extensive use of the
async
/await
pattern to minimize frustration. - Example API routes with fully working RESTful CRUD endpoints, also using
async
/await
! - Mocha integration tests for the example API. And guess what? We're using
async
/await
for that too!
Let's face it, working with databases in Node has always been frustrating (to say the least). Node 7 introduces native support for async
/await
, which is nothing more than syntatic sugar on top of the Promise pattern. This means that if your code uses promises, you can use async
/await
right now!
So instead of writing an API route like this...
// GET /products
// Returns a JSON array containing all available product objects
router.get('/', (req, res) => {
models.Product.findAll()
.then((result) => {
res.json(result)
})
.catch((error) => {
res.status(400).json(error)
})
})
...you can write this instead!
router.get('/', async (req, res) => {
try {
res.json(await models.Product.findAll())
}
catch(error) {
res.status(400).json(error)
}
})
Note how you can use try
/catch
for async error handling - and YES, IT WORKS! π
Baaaes expects a Postgres database up and running, but you can modify the code to use any other database supported by Sequelize. You'll have to install the corresponding npm
packages and modify the .env
file. Relevant documentation here.
Out of the box, Baaaes uses URI-style configuration for database connections, but you can use as many environment variables as you want (e.g. DB_USER
, DB_PASS
, DB_HOST
and so on). Just make sure to keep you test database separated; all data is destroyed every time the test suite runs!
The objective of Baaaes is not to prescribe how you should organize your project, but showing one particular way to do it (hence opinionated).
If you already know what you're doing, you can configure Express, Sequelize, Knex, Mongo and whatever else you're using however you want. Still, it can be useful to take a peek at some of this code to inform your decisions.
This is one of the reasons I've decided against making Baaaes into a code generation package (such as express-generator
). The other reason is it would be too much like creating yet another Javascript framework, and NOBODY wants that.
NOBODY.
- Authentication middleware example
- JWT example
- Bake in Let's Encrypt
- Example NGINX configuration
- Clustering
- HTTP/2
- Koa version
Copyright (c) 2017 Fabio Neves
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.