{"id":13514564,"url":"https://github.com/rasouza/node-clean-architecture","last_synced_at":"2025-03-31T03:31:01.342Z","repository":{"id":38333324,"uuid":"273806751","full_name":"rasouza/node-clean-architecture","owner":"rasouza","description":"Clean Architecture implementation written in NodeJS","archived":false,"fork":false,"pushed_at":"2023-10-11T16:47:15.000Z","size":749,"stargazers_count":298,"open_issues_count":0,"forks_count":44,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-11-01T18:37:23.300Z","etag":null,"topics":["architecture","backend","clean-architecture","nodejs"],"latest_commit_sha":null,"homepage":"https://rasouza.github.io/node-clean-architecture","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rasouza.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-06-21T00:26:54.000Z","updated_at":"2024-10-06T06:58:44.000Z","dependencies_parsed_at":"2024-01-13T19:24:43.710Z","dependency_job_id":"c7cb8bea-588e-464f-aae8-6f793a22fa56","html_url":"https://github.com/rasouza/node-clean-architecture","commit_stats":null,"previous_names":[],"tags_count":5,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasouza%2Fnode-clean-architecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasouza%2Fnode-clean-architecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasouza%2Fnode-clean-architecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasouza%2Fnode-clean-architecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rasouza","download_url":"https://codeload.github.com/rasouza/node-clean-architecture/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246413377,"owners_count":20773053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["architecture","backend","clean-architecture","nodejs"],"created_at":"2024-08-01T05:00:57.856Z","updated_at":"2025-03-31T03:30:57.667Z","avatar_url":"https://github.com/rasouza.png","language":"HTML","funding_links":[],"categories":["HTML"],"sub_categories":[],"readme":"![Code Coverage](https://img.shields.io/badge/coverage-96%25-green?style=flat-square)\n\n# Node Clean Architecture\n\n![Preview](preview.png)\n\n## Table of Contents\n- [Node Clean Architecture](#node-clean-architecture)\n  - [Table of Contents](#table-of-contents)\n  - [Libs](#libs)\n  - [Installation](#installation)\n  - [Testing](#testing)\n  - [Clean Architecture](#clean-architecture)\n    - [Folder structure](#folder-structure)\n    - [The Dependency Rule](#the-dependency-rule)\n    - [Typical Request](#typical-request)\n  - [Troubleshooting](#troubleshooting)\n    - [Log `connected to MongoDB database!` doesn't appear](#log-connected-to-mongodb-database-doesnt-appear)\n    - [I'm getting `EADDRINUSE` upon application start](#im-getting-eaddrinuse-upon-application-start)\n\n\nThis backend implements a [RESTful](https://restfulapi.net/) CRUD interface for users and complies with Eric Evan's [DDD](https://en.wikipedia.org/wiki/Domain-driven_design) and Uncle Bob's [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) which is briefly explained here in the document. \n\nIt also exposes a `/docs/` endpoint for further reference and `/coverage/` for test coverage.\n\n## Libs\n* [Restify](http://restify.com/)\n* [Mongoose](https://mongoosejs.com/)\n* [Lodash FP](https://github.com/lodash/lodash/wiki/FP-Guide) Functional Programming version\n* [Awilix](https://github.com/jeffijoe/awilix) as Dependency Injection container\n* [dotenv](https://www.npmjs.com/package/dotenv)\n\n## Installation\n\n```\ndocker-compose up -d\ncp .env.example .env\nnpm start\n```\nYou should get\n```\nrestify listening at http://[::]:8080\nconnected to MongoDB database!\n```\nAccess http://localhost:8080/docs/ and http://localhost:8080/coverage/\n\n## Testing\n\n```\nnpm test\n```\nIt uses an in-memory DB to run tests so you don't need to have mongodb up and running\n\n## Clean Architecture\n\n![Cleab Architecture](https://blog.cleancoder.com/uncle-bob/images/2012-08-13-the-clean-architecture/CleanArchitecture.jpg)\n\n### Folder structure\n```\n\n\n└ application                   → Application services layer\n    └ use_cases                 → Application business rules \n└ domain                        → Enterprise core business layer such as domain model objects (Aggregates, Entities, Value Objects) and repository interfaces\n└ infrastructure                → Frameworks, drivers and tools such as Database, the Web Framework, mailing/logging/glue code etc.\n    └ config                    → Application configuration files, modules and services\n        └ container.js          → Module that manage service implementations by environment\n    └ database                  → Database ORMs middleware\n        └ schemas               → Mongoose schemas\n    └ repositories              → Implementation of domain repository interfaces\n    └ webserver                 → Restify Web server configuration (server, routes, plugins, etc.)\n        └ server.js             → Restify server definition\n└ ports/http                    → Adapters and formatters for use cases and entities to external agency such as Database or the Web\n    └ UserController.js         → Restify route handlers\n    └ routes.js                 → Restify route definitions\n    └ errors.js                 → Standard errors for the whole application\n └ index.js                     → Main application entry point\n ```\n\n ### The Dependency Rule\n\n\u003eThe overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.\n\nExtracted from https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html#the-dependency-rule\n\n### Typical Request\n\n![Request](architecture.jpg)\n\n## Troubleshooting\n\n### Log `connected to MongoDB database!` doesn't appear\nThe backend uses its own database (`users`) to run its business logic, so you need to ensure this database is created with proper user credentials. The script `mongo-init.js` is run when `docker-compose up` runs for the first time. \n\nCheck in `docker-compose logs mongo` to see if something unusual is happening\n\n### I'm getting `EADDRINUSE` upon application start\nYou need port `8080` to be free in order to boot up the application. Check if it's already in use and shut the application down before you `npm start` again\n\n\u003cdiv align=\"center\"\u003e\n\n# Stack Report\n![](https://img.stackshare.io/repo.svg \"repo\") [rasouza/node-clean-architecture](https://github.com/rasouza/node-clean-architecture)![](https://img.stackshare.io/public_badge.svg \"public\")\n\u003cbr/\u003e\u003cbr/\u003e\n|28\u003cbr/\u003eTools used|3\u003cbr/\u003eContributors|10/11/23 \u003cbr/\u003eReport generated|06/06/22\u003cbr/\u003eLast commit date|\n|------|------|------|------|\n\u003c/div\u003e\n\n## \u003cimg src='https://img.stackshare.io/languages.svg'/\u003e Languages (2)\n\u003ctable\u003e\u003ctr\u003e\n  \u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/1209/javascript.jpeg' alt='JavaScript'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript\"\u003eJavaScript\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/6727/css.png' alt='CSS 3'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/CSS3\"\u003eCSS 3\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## \u003cimg src='https://img.stackshare.io/frameworks.svg'/\u003e Frameworks (1)\n\u003ctable\u003e\u003ctr\u003e\n  \u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/7609/24939410.png' alt='Fastify'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://www.fastify.io/\"\u003eFastify\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003ev3.9.2\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## \u003cimg src=''/\u003e Data (1)\n\u003ctable\u003e\u003ctr\u003e\n  \u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/1231/0TXzZU7W_400x400.jpg' alt='Mongoose'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://mongoosejs.com/\"\u003eMongoose\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003ev5.10.3\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## \u003cimg src='https://img.stackshare.io/devops.svg'/\u003e DevOps (7)\n\u003ctable\u003e\u003ctr\u003e\n  \u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/8067/default_90dcb1286af7685c68df319c764b80704df1155b.png' alt='Dotenv'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://github.com/motdotla/dotenv\"\u003eDotenv\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/3337/Q4L7Jncy.jpg' alt='ESLint'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://eslint.org/\"\u003eESLint\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/1046/git.png' alt='Git'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://git-scm.com/\"\u003eGit\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/830/jest.png' alt='Jest'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://facebook.github.io/jest/\"\u003eJest\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003ev28.1.0\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/5848/44mC-kJ3.jpg' alt='Yarn'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://yarnpkg.com/\"\u003eYarn\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/5577/preview.png' alt='nodemon'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"http://nodemon.io/\"\u003enodemon\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003ev2.0.4\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/1120/lejvzrnlpb308aftn31u.png' alt='npm'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://www.npmjs.com/\"\u003enpm\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Other (2)\n\u003ctable\u003e\u003ctr\u003e\n  \u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/4631/default_c2062d40130562bdc836c13dbca02d318205a962.png' alt='Shell'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Shell_script\"\u003eShell\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003ctd align='center'\u003e\n  \u003cimg width='36' height='36' src='https://img.stackshare.io/service/10156/12867925.png' alt='semantic-release'\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003esemantic-release\u003c/a\u003e\u003c/sub\u003e\n  \u003cbr\u003e\n  \u003csub\u003e\u003c/sub\u003e\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\n## \u003cimg src='https://img.stackshare.io/group.svg' /\u003e Open source packages (15)\u003c/h2\u003e\n\n## \u003cimg width='24' height='24' src='https://img.stackshare.io/service/1120/lejvzrnlpb308aftn31u.png'/\u003e npm (15)\n\n|NAME|VERSION|SOURCE FILE|\n|------|------|------|\n|[@semantic-release/git](https://github.com/semantic-release/git)|v10.0.1|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[@types/jest](http://definitelytyped.org/)|v28.1.1|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[cross-env](https://github.com/kentcdodds/cross-env)|v7.0.3|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[dotenv](https://github.com/motdotla/dotenv)|v8.2.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-config-standard](https://github.com/standard/eslint-config-standard)|v16.0.2|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import)|v2.22.1|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)|v26.5.3|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-plugin-node](https://github.com/mysticatea/eslint-plugin-node)|v11.1.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-plugin-promise](https://github.com/xjamundx/eslint-plugin-promise)|v4.2.1|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[eslint-plugin-standard](https://github.com/standard/eslint-plugin-standard)|v5.0.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[mongoose](https://mongoosejs.com)|v5.10.3|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[nyc](https://github.com/istanbuljs/nyc)|v15.1.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[pino](http://getpino.io)|v6.9.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[pino-pretty](https://github.com/pinojs/pino-pretty)|v4.3.0|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n|[semantic-release](https://github.com/semantic-release/semantic-release)|v19.0.2|[yarn.lock](https://github.com/rasouza/node-clean-architecture/blob/master/yarn.lock)|\n\n\u003cbr/\u003e\n\u003cdiv align='center'\u003e\n\nGenerated via [Stack Reports](https://stackshare.io/stack-report)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasouza%2Fnode-clean-architecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frasouza%2Fnode-clean-architecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasouza%2Fnode-clean-architecture/lists"}