Clear project folders and files organization in the first but important step on a way to efficient, reliable, maintainable, extensible code, or in short, clean code. When you have 3–4 developers working on a project, it is easy to keep it clean even without any formal rules. When a team begins to grow, you need to keep an eye on it, probably even document it, otherwise you are at risk to have a trash can soon.
In this appendix, there’s an overview of the project sources, Backend API Server with Node.js, used in the tutorial. Here’s the layers representation based on a design principle of Separation of Concerns:
Let’s review the project folders and major files starting from the root:
package.json — the main project configuration file, contains running scripts aliases, npm dependencies, and other metadata.
yarn.lock — dependencies versions locker file.
jest.config.js — jest unit tests running config file.
__mocks__ — folder with mocks for npms (if no other way to mock something easily).
types/ — folder with TypeScript declarations for npms which don’t have the public ones.
config/ — all configuration files for all environments, keys, etc, which are appropriate to keep in git.
scripts/ — folder with all helper scripts for running, building, etc.
src/ — all sources files.
src/app.ts — entry point of the Node.js App.
src/config — config variables parser and interface accessor in TypeScript.
src/tests — unit tests helpers; functional and stress tests sources.
src/utils — adapters, proxies, facades, decorators for used npms/libraries.
src/api/models — object data modeling, mongoose in this project.
src/api/services — all business logic to process the incoming requests, and return the result. The data is passed in/out to the service as arguments or data structures, completely decoupled from HTTP API.
src/api/controllers — HTTP API requests to services (business logic) proxy. Each controller extracts the data from an http request, and calls the corresponding service passing the data. When a controller gets a result from a service, it composes an HTTP response. All controllers are consolidated in src/api/controllers/index.ts.
To distinguish what the controller should do and what the service, imagine that your service should work with a different from HTTP API layer, for example via WebSockets, and the data is passed using a binary protocol, like protobuf. So, if you add another layer of controllers (WebSockets + protobuf), you service should still work with both sets of controllers, HTTP API +express and WebSockets + protobuf.
A unit test file to each source file is placed in __tests__ subfolder where file is located. The name of a unit test file usually has the same name as a target source file. As a result you have a bunch of __tests__ folders in the sources directory.