When I started using NodeJS as an REST API on the server side, I struggled a lot with the question 'How should the folder structure look like?'.
Of course there's not a perfect or 100% correct solution but after reading some articles regarding this question, I found a folder structure that fits my needs quite good. So today I'd like to show you how I structure my REST APIs.
Used node modules:
Let's have a look at the structure
nodejs-api-structure └───dist │ └───node_modules │ └───src │ │ README.md │ ...
This structure is nothing special and shouldn't be new to you.
So the interesting part is the structure of the "src" folder on which our focus lies.
So what do we have in here?
nodejs-api-structure └───src │ └───config │ └───rest │ │ │ └───components │ │ │ └───middleware │ │ │ │ routes.ts │ │ server.ts │ └───services │ index.ts
From here on, we'll always work from the top of the directory down.
nodejs-api-structure └───src │ └───config │ globals.ts │ permissions.ts
This directory includes configuration files. This could be for example:
- Global variables
- ACL permissions config
- SMTP config
nodejs-api-structure └───src │ └───rest │ └───components │ └───article │ └───auth │ └───country │ └───user │ index.ts
Here we have the "heart" of our API. Each component consists of its own routes, controller and model and takes care of the data flow for itself.
Lets take an example
nodejs-api-structure └───src │ └───rest │ └───components │ └───user │ controller.ts │ model.ts │ routes.ts
controller: (imports user model)
- Handle incoming requests
- Interact with our database
- Send the response data
- The database model for the corresponding component
routes: (imports user controller)
- API endpoints of the component (Example: '/user/:id')
- Authorization of incoming requests (via JWT)
- Validation of the permission required for the action (ACL)
- Calls its corresponding controller (user controller)
Each file consists of one class that is exported. Of course, you can add here more component specific stuff like config or services files.
All components routes are collected in ./src/rest/components/index.ts where the single router of each component is initialized.
nodejs-api-structure └───src │ └───rest │ └───middleware │ auth.ts │ compression.ts
This folder includes all the API's middlewares like authentication, compression etc.
nodejs-api-structure └───src │ └───rest │ routes.ts
Here we initialize the collected components routes from ./src/rest/components/index.ts
and all middlewares from ./src/rest/middleware/ *.ts
nodejs-api-structure └───src │ └───rest │ server.ts
Here we declare everything required for our express server
- Import middlware / component routes
- Error Handling
nodejs-api-structure └───src │ └───services │ auth.ts │ helper.ts │ mail.ts │ task.ts
- Inits our passport strategies imported from auth component
- Passport authorization
- ACL authorization
- Contains helper methods for password hashing, UUIDs...
- Sending mails and rendering mail templates
- Includes internal tasks
nodejs-api-structure └───src │ index.ts
Here we initialize our express server and the database connection.
Last but not least a complete overview of the folder structure
nodejs-api-structure └───src │ └───config │ │ globals.ts │ │ permissions.ts │ └───rest │ │ │ └───components │ │ │ │ │ └───article │ │ │ │ │ └───user │ │ │ controller.ts │ │ │ model.ts │ │ │ routes.ts │ │ │ └───middleware │ │ │ auth.ts │ │ │ compression.ts │ │ │ │ routes.ts │ │ server.ts │ └───services │ index.ts
That's it! I hope this is a little help for people who struggled with the same question and didn't know where or how to start. I think there are still many things you can do better or in a more efficient way. Especially testing, what I didn't cover here.
I'm currently working on a side project. Here you can see this folder structure (in a small modified way) in action. Have a look!