After working with many backend projects, I realized that structuring the app is equally important as the choice of tech stack and fractal app structure is always my choice.

Fractal pattern conveys that similar patterns recur progressively and the same thought process is applied to the structuring of codebase i.e All units repeat themselves.

Note: To code a fractal pattern and see it visually, check here and don’t forget to follow me on Github.

Now, let's start with the crux,

App Root Structure

The root folder always remains the same in any case of API’s structuring.

So, At root level we have -:

1. app is where our main app code goes and will discus in depth under the app structure below.

2. docs(optional) is for documentation purpose.

3. lib(optional) is where the complied app code goes which is used for production env.

4. migrations is where all the table schema. I personally use knex.js and a self made ORM name tabel written on top of it.

Some of migration files (They are automatically generate from CLI)

5. node_modules you already know it 😃.

6. tests are where we write all our unit tests.

The structuring of the tests folder is like the actions or routes under the app folder and will be explained in the app structure section.

7. config and config.sample.js are where all of our configuration related to database, authentication, external API keys, etc are stored.

If you are wondering why we have two such files, then config.sample.js goes to your repository so that other developers can know the file shape and can use to form their local config.js file.

Also, we can also have a config.production for a production environment.

Note: config can be a separate folder too, that can have separate sub configs files for database, external Api’s key etc but it feel overkill to me.

8. eslintrc is where the lint logic goes. Read more here.

9. migrate is the file that passes our configuration from config.js to ORM and helps us run migration from CLI, check the code here.

10. gitignore is where we path to folder or filename that we don’t want to push on repository.

11. package.json — you already know it 😃.

Note: We will discuss only the app folder structure because other are straight forward. If you need any help or want to understand anything in code base then hit me up.

The app Structure

app folder

1. server.js is the file that starts your server and will have all middleware that is required for request parsing like bodyparser, cors, multer and errorhandlers etc and finally we add routes middleware.

Sample code for server.js

2. routes will have sub-files or sub-folders made as per the entities in the project.

routes folder

The index.js under routes looks like as shown below. It has request handler middlewares and a catch-all route.

index.js under routes

Note: We can abstract a big entity like teams in a folder and can call it as teams which can then have sub subfolder like members, contacts, dashboard etc. under routes.

Fractal pattern structuring in routes

A file under routes is where all request handler or sub-routes are written and the only purpose of them is to either call the action that is responsible for that route or the sub-route folder.

auth.js under routes

Note: signup, login, logout, refresh and forgetpassword in above image all are actions that are defined under action folder.

3. Most of the time, the actions folder will have the same the same structuring as the routes folder.

actions folder

Each file in actions is for business logic i.e all code that store, get, change real entities either in database tables or doing queuing functions like enqueue and dequeue, etc all happen here.

Sample code for auth file for signup action

Note: Actions can call other actions too.

4. So, middlewares, utils, helpers, tasks will follow the same way of structuring as action or routes do i.e main entity will act as a root folder and then will have subfolder as per sub-entities and repeat.

5. tasks.js is used for running tasks from CLI created under task folder like database seed, clean database, etc.

6. nsqd(optional) is use case specific for distributed messaging.

Note: NSQ is one the best i have used for distributed messaging it works great with no pain in production.

utils and helpers can be merged if need, i love to keep them separate so that i can reuse utils as its more generic in all projects

Why fractal