DDD/Clean Architecture inspired boilerplate for Node web APIs

Overview

Node API boilerplate

An opinionated boilerplate for Node web APIs focused on separation of concerns and scalability.

Features

Multilayer folder structure
Code organization inspired by DDD and Clean Architecture focused on codebase scalability.
Instant feedback and reload
Use Nodemon to automatically reload the server after a file change when on development mode, makes the development faster and easier.
Ready for production
Setup with PM2 process manager ready to go live on production. It's also out-of-box ready to be deployed at Heroku, you can read more about it here.
Scalable and easy to use web server
Use Express for requests routing and middlewares. There are some essential middlewares for web APIs already setup, like body-parser, compression, CORS and method-override.
Database integration
Sequelize, an ORM for SQL databases, is already integrated, you just have to set the authentication configurations.
Prepared for testing
The test suite uses Mocha/Chai and is prepared to run unit, integration and functional tests right from the beginning. There are helpers to make it easy to make requests to the web app during the tests and for cleaning the database after each test. A FactoryGirl adapter for Sequelize is setup to make your tests DRY as well, and the tests generate code coverage measurement with Istanbul. You should read about the Chai plugins that are setup by default too.
Dependency injection
With Awilix, a practical dependency injection library, the code will not be coupled and it'll still be easy to resolve automatically the dependencies on the runtime and mock them during the tests. It's even possible inject dependencies on your controllers with the Awilix Express adapter. Click here if you want to read more about how to use dependency injection with this boilerplate.
CLI integration
Both the application and Sequelize have command-line tools to make it easy to work with them. Check the Scripts section to know more about this feature.
Logging
The Log4js logger is highly pluggable, being able to append the messages to a file during the development and send them to a logging service when on production. Even the requests (through morgan) and queries will be logged.
Linter
It's also setup with ESLint to make it easy to ensure a code styling and find code smells.

Quick start

Notice that the boilerplate comes with a small application for user management already, you can delete it with a npm script after you understand how the boilerplate works but please do the quick start first! 😊

  1. Clone the repository with git clone --depth=1 https://github.com/talyssonoc/node-api-boilerplate
  2. Setup the database on config/database.js (there's an example file there to be used with PostgreSQL 😉 )
  3. Install the dependencies with yarn (click here if you don't have Yarn installed)
  4. Create the development and test databases you have setup on config/database.js
  5. Run the database migrations with npm run sequelize db:migrate
  6. Add some seed data to the development database with npm run sequelize db:seed:all
  7. Run the application in development mode with npm run dev
  8. Access http://localhost:3000/api/users and you're ready to go!

After playing a little bit with the boilerplate and before implementing a real application with it I recommend you to read at least the Setup and the Organization and architecture sections of our Wiki. After that you'll be able to remove the example application files running npm run cleanup

Aditional info:

  • Don't forget to run the migrations for the test environment as well (including when you create a new migration) with npm run sequelize db:migrate -- --env=test

Scripts

This boilerplate comes with a collection of npm scripts to make your life easier, you'll run them with npm run <script name> or yarn run <script name>:

  • dev: Run the application in development mode
  • start: Run the application in production mode (prefer not to do that in development)
  • test: Run the test suite
  • test:unit: Run only the unit tests
  • test:features: Run only the features tests
  • coverage: Run only the unit tests and generate code coverage for them, the output will be on coverage folder
  • lint: Lint the codebase
  • sequelize: Alias to the Sequelize CLI
  • console: Open the built-in console, you can access the DI container through the container variable once it's open, the console is promise-friendly. Click here to know more about the built-in console
  • cleanup: Removes the files from the example application

Tech

Contributing

This boilerplate is open to suggestions and contributions, documentation contributions are also important! :)

Comments
  • how would a Mapper support relationships?

    how would a Mapper support relationships?

    Hi, When you have simple data-values objects such as your User, a Mapper is pretty simple as it just maps the properties between DB model and domain.

    but how would you deal with relationships? for example, if a User can potentially have a "ReferrerUser".

    now the mapper should support both user with and without a referrer user. the problem is "lazy loading". sometimes you want just the Id of the referrer, and sometimes the actual user object, depending on the use-case.

    examples for different scenarios:

    1. create a user without referrer
    2. create a user + create its user referrer at the same time
    3. create a user with user id of the user referer (it already exists in the system)
    4. fetch user with just its referer id if exists
    5. fetch user + eagerly fetch the referrer user as a nested object

    also, what if I now also want the user to have a collection of all the users he referred? I would add "referredUsers" array to the domain the problem is that sometimes I would want to fetch just the user, and sometimes I would want to fetch the user + his referred users (eager loading). and so on ..

    moreover, in this example, the relationship is to the same type. what if the relationship is to another type? for example, if User has a relationship to "Country". now I would also need to delegate a call to CountryMapper inside UserMapper?

    lastly, when there is no 1-to-1 connection between the domain and the table persisting it, mapper might impose more difficulties to "glue" things together

    hope my concerns are clear

    opened by LiranBri 5
  • Create swagger.json for documentation

    Create swagger.json for documentation

    I created a folder called api and created a file inside, this file is swagger.yaml and can be edited with swagger project edit, for use this, just install npm install swagger -g and run swagger project edit inside of the project folder or if you are acquainted with swagger specification, just edit swagger.json inside src/interfaces/http/utils/swagger.

    For you see the docs, type http://localhost:3000/api-docs in your favorite browser.

    opened by iagocavalcante 5
  • An folder structure example needed

    An folder structure example needed

    Hey !

    I want a little help in understanding your folder and dependency injection structure :

    If I am trying to implement an external Emailing WebAPI (SendGrid), how do I organize the files along your file structure ?

    sendGrid basically has a library and I need to implement a wrapper around it. How do I do that. my solution so far is to :

    • create a database model (necessary)
    • create a sendGridFolder under interfaces where I add the sendGridWrapper
    • create an Email Folder under infra then under it create SendGrid folder and within add a new Repository sendGridRepository that must have the sendgridWrapper injected to it via the constructor as well as the Database model.
    • create a domain model named Email
    • create an operation folder under app called Email and add email operations under it ( sending, checking status, .... ) this will use the domain model

    Is this the correct way of using your approach ? if else can you please specify, in a flowchart type fashion, the steps that a basic db query coming from and API call to this system would take ? ans maybe the files that it goes through ? something like this file will call this file and the use the dependency injected right here, .....

    Thanks, you work is very good but I found it hard to understand with ease. so if you can spare some time to help me, this would be very nice.

    opened by moda20 4
  • use Heroku database in development

    use Heroku database in development

    I'm trying to initiate a project with Heroku database in development mode.

    I updated config/database.js:

      development: {
        username: 'XXXX',
        password: 'XXXXX',
        database: 'XXXXX',
        host: 'XXXXX.compute-1.amazonaws.com',
        dialect: 'postgres'
      },
    

    Loaded configuration file "config/database.js". Using environment "development".

    ERROR: connect ECONNREFUSED

    What I'm doing wrong?

    opened by lasharela 3
  • what is the use of dependency injection on repositories when we need to beforehand declare and inject those dependencies

    what is the use of dependency injection on repositories when we need to beforehand declare and inject those dependencies

    what is the use of dependency injection on repositories when we need to beforehand declare and inject those dependencies :

    while have UserModel as a possible injection when we are going to hard define that in the container injecting section and link it by Name so if I want to inject an other object I need to change it manually. ????

    opened by moda20 3
  • Update awilix to version 3

    Update awilix to version 3

    Awilix version 3 changed the way you register you class, value and function to your container.

    Would be good to update awilix-express as well but it requires more work.

    opened by lsilvs 3
  • Complete tutorial please for the best practice of PUT, DESTROY, and SHOW methods ?

    Complete tutorial please for the best practice of PUT, DESTROY, and SHOW methods ?

    could you please provide examples for PUT, DESTROY, SHOW ?

    also adding below features would be great.

    • library to return json as json api standard (i'm using serializer for now)
    • proper error handling with return http code
    enhancement 
    opened by fatkhanfauzi 3
  • Extract REPL integration to _lib folder

    Extract REPL integration to _lib folder

    The implementation for the REPL is written directly inside the integration module (https://github.com/talyssonoc/node-api-boilerplate/blob/main/src/_boot/repl.ts). We could extract it to inside the _lib folder as we do for the other integrations (https://github.com/talyssonoc/node-api-boilerplate/tree/main/src/_lib).

    good first issue 
    opened by talyssonoc 2
  • Bump sequelize from 3.30.4 to 5.15.1

    Bump sequelize from 3.30.4 to 5.15.1

    Bumps sequelize from 3.30.4 to 5.15.1.

    Release notes

    Sourced from sequelize's releases.

    v5.15.1

    5.15.1 (2019-08-18)

    Security

    • sequelize.json.fn: use common path extraction for mysql/mariadb/sqlite (#11329) (9bd0bc1)

    This fixes a security issue with sequelize.json() for MySQL. Old code was still used for formatting sub paths for json queries when used with sequelize.json() helper function

    Example of attack vector

    return User.findAll({
      where: sequelize.json("data.id')) AS DECIMAL) = 1 DELETE YOLO INJECTIONS; -- ", 1)
    });
    

    Thanks to @​Kirill89 from Snyk Security Research Team for reporting this issue.

    v5.15.0

    5.15.0 (2019-08-14)

    Features

    • associations: source and target key support for belongs-to-many (#11311) (83e263b)

    v5.14.0

    5.14.0 (2019-08-13)

    Features

    v5.13.1

    5.13.1 (2019-08-11)

    Bug Fixes

    v5.13.0

    5.13.0 (2019-08-09)

    Bug Fixes

    ... (truncated)
    Commits
    • 9bd0bc1 fix(sequelize.json.fn): use common path extraction for mysql/mariadb/sqlite (...
    • 83e263b feat(associations): source and target key support for belongs-to-many (#11311)
    • 4f09899 feat: support include option in bulkInsert (#11307)
    • de06ac3 docs(security): grammar mistakes
    • 29eb1c8 docs(security): add responsible disclosure policy (#11300)
    • 592099d fix(count): fix null count with includes (#11295)
    • 80d3625 docs(query-interface): fix typo with remove-column parameter (#11294)
    • a39c63a fix(types): return a usable type when using the sequelize.models lookup (#11293)
    • 98a4089 fix(types): use correct this value in getterMethods and setterMethods (#11292)
    • dd428a0 refactor(association): name model that association is missing from (#11290)
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by sushantdhiman, a new releaser for sequelize since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • Why do not move serialization function to domain model class?

    Why do not move serialization function to domain model class?

    I mean if User class would have method to serialize itself then you don't need to have special UserSerializer function separately and serialization setup in that case will be more transparent (because it will be made in the same place as model definition). So you can define public and protected properties of model and serialize only public properties for example

    opened by massimo-ua 2
  • Folders structure

    Folders structure

    I think the folders structure is very complicated / confusing ...

    Would be better resources folders, like :

    https://github.com/i0natan/nodebestpractices/blob/master/sections/projectstructre/breakintcomponents.md

    users products vehicles ... etc

    thanks for share this project.

    opened by duard 2
  • Bump minimist from 1.2.5 to 1.2.6

    Bump minimist from 1.2.5 to 1.2.6

    Bumps minimist from 1.2.5 to 1.2.6.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Bump validator from 13.6.0 to 13.7.0

    Bump validator from 13.6.0 to 13.7.0

    Bumps validator from 13.6.0 to 13.7.0.

    Release notes

    Sourced from validator's releases.

    13.7.0

    13.7.0

    New Features

    Fixes and Enhancements

    New and Improved Locales

    ... (truncated)

    Changelog

    Sourced from validator's changelog.

    13.7.0

    New Features

    New Features

    Fixes and Enhancements

    New and Improved Locales

    ... (truncated)

    Commits
    • 47ee5ad 13.7.0
    • 496fc8b fix(rtrim): remove regex to prevent ReDOS attack (#1738)
    • 45901ec Merge pull request #1851 from validatorjs/chore/fix-merge-conflicts
    • 83cb7f8 chore: merge conflict clean-up
    • f17e220 feat(isMobilePhone): add El Salvador es-SV locale
    • 5b06703 feat(isMobilePhone): add Palestine ar-PS locale
    • a3faa83 feat(isMobilePhone): add Botswana en-BW locale
    • 26605f9 feat(isMobilePhone): add Turkmenistan tk-TM
    • 0e5d5d4 feat(isMobilePhone): add Guyana en-GY locale
    • f7ff349 feat(isMobilePhone): add Frech Polynesia fr-PF locale
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Implement authentication with JWT

    Implement authentication with JWT

    Since JWT is the most used authentication method for APIs nowadays, it would be good to have an implementation of JWT for the boilerplate. It should be reusable across multiple HTTP abstractions (Express, Fastify, ...) with a thin integration layer to plug into a given HTTP abstraction.

    opened by talyssonoc 1
Releases(v3.0-beta)
  • v3.0-beta(Oct 4, 2021)

    This release marks the public development of the v3 of the boilerplate. Rewritten with a better architecture in mind, better structure and now in TypeScript.

    Source code(tar.gz)
    Source code(zip)
  • v2.1(Aug 3, 2018)

  • v2.0(Oct 7, 2017)

    Added:

    • The boilerplate example app now implements all the actions for the user CRUD;
    • Instead of using .then()/.catch() for handling promises now it uses ES8's async/await;
    • Serializers are now used to generate the JSON response in the controllers.

    Breaking changes:

    • This version depends on Node v7.6.0 or later because of async/await;
    • Tests are now separate into unit and features tests.
    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(May 21, 2017)

  • v1.1(Apr 10, 2017)

A simple boilerplate generator for your node express backend project! 🚀

A simple boilerplate generator for your node express backend project! ??

Gunvant Sarpate 35 Sep 26, 2022
Noderlang - Erlang node in Node.js

Noderlang allows Node.js programs to easily operate in BEAM environments

devsnek 2 Mar 31, 2022
Elegant and all-inclusive Node.Js web framework based on TypeScript. :rocket:.

https://foalts.org What is Foal? Foal (or FoalTS) is a Node.JS framework for creating web applications. It provides a set of ready-to-use components s

FoalTS 1.7k Jan 4, 2023
The most powerful headless CMS for Node.js — built with GraphQL and React

A scalable platform and CMS to build Node.js applications. schema => ({ GraphQL, AdminUI }) Keystone Next is a preview of the next major release of Ke

KeystoneJS 7.3k Jan 4, 2023
:desktop_computer: Simple and powerful server for Node.js

server.js for Node.js Powerful server for Node.js that just works so you can focus on your awesome project: // Include it and extract some methods for

Francisco Presencia 3.5k Dec 31, 2022
🚀 A RESTful API generator for Node.js

A RESTful API generator rest-hapi is a hapi plugin that generates RESTful API endpoints based on mongoose schemas. It provides a powerful combination

Justin Headley 1.2k Dec 31, 2022
wolkenkit is an open-source CQRS and event-sourcing framework based on Node.js, and it supports JavaScript and TypeScript.

wolkenkit wolkenkit is a CQRS and event-sourcing framework based on Node.js. It empowers you to build and run scalable distributed web and cloud servi

the native web 1.1k Dec 26, 2022
nact ⇒ node.js + actors ⇒ your services have never been so µ

nact ⇒ node.js + actors your services have never been so µ Any and all feedback, comments and suggestions are welcome. Please open an issue if you fin

Natalie Cuthbert 1k Dec 28, 2022
A Programming Environment for TypeScript & Node.js built on top of VS Code

Programming Environment for TypeScript & Node.js A battery-included TypeScript framework built on top of Visual Studio Code Website Kretes is a progra

Kretes 677 Dec 11, 2022
Clock and task scheduler for node.js applications, providing extensive control of time and callback scheduling in prod and test code

#zeit A node.js clock and scheduler, intended to take place of the global V8 object for manipulation of time and task scheduling which would be handle

David Denton 12 Dec 21, 2021
In-memory filesystem with Node's API

In-memory filesystem with Node's API

Vadim Dalecky 1.4k Jan 4, 2023
Micro type-safe wrapper for Node.js AMQP library and RabbitMQ management.

Micro type-safe wrapper for AMQP library and RabbitMQ management Description Section in progress. Getting Started Qupi can be installed by Yarn or NPM

Grzegorz Lenczuk 2 Oct 5, 2021
🦄 0-legacy, tiny & fast web framework as a replacement of Express

tinyhttp âš¡ Tiny web framework as a replacement of Express ?? tinyhttp now has a Deno port (work in progress) tinyhttp is a modern Express-like web fra

v 1 r t l 2.4k Jan 3, 2023
DDD/Clean Architecture inspired boilerplate for Node web APIs

Node API boilerplate An opinionated boilerplate for Node web APIs focused on separation of concerns and scalability. Features Multilayer folder struct

Talysson de Oliveira Cassiano 3k Dec 30, 2022
Personal project to a student schedule classes according his course level. Using GraphQL, Clean Code e Clean Architecture.

classes-scheduler-graphql This is a personal project for student scheduling, with classes according his course level. I intend to make just the backen

Giovanny Lucas 6 Jul 9, 2022
This is another Express + TypeScript + DDD (Domain Driven Design patterns) + IoC/DI (Inversion of control and Dependency injection) + Primsa ORM + API REST boilerplate.

Express-TS-DDD REST API This is another Express + TypeScript + DDD (Domain Driven Design patterns) + IoC/DI (Inversion of control and Dependency injec

J.D. 6 Nov 3, 2022
React Native Boilerplate - The Boilerplate contains all the basic packages, common components and, prebuilt code architecture

The Boilerplate contains all the basic packages, common components and, prebuilt code architecture. It will save developer's project setup time.

MindInventory 36 Dec 26, 2022
A boilerplate for ExpressJs projects configured with ESLint, Prettier & Airbnb Setup. The boilerplate utilises RESTful architecture and uses Mongodb.

ExpressJs-Boilerplate An ExpressJs boilerplate configured with ESLint, Prettier & Airbnb Setup. The boilerplate utilises RESTful architecture and uses

Hammas bin Farrukh 4 Mar 8, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022