|
1 | | -# node-express-api |
| 1 | +# Template API using ExpressJS |
| 2 | + |
| 3 | +## Setup project locally |
| 4 | + |
| 5 | +### Setup development environment |
| 6 | + |
| 7 | +1. Clone this project (or use it as template to create another repository inside the GitHub) |
| 8 | +2. Open the project's directory either on a terminal or inside an IDE (like Visual Studio Code) |
| 9 | +3. **[Follow this step only if you opened the project inside the IDE]** Open a terminal inside the IDE |
| 10 | +4. Run the command `nvm use`. This command gets the node's version located inside the `.nvmrc` file and use it inside the terminal. |
| 11 | +5. Run the command `npm i` in order to install all dependencies and devDependencies. |
| 12 | +6. Copy-Paste the content of the `.env.example` inside the git-ignored `.env` file. |
| 13 | + |
| 14 | +### Setup the app's information |
| 15 | + |
| 16 | +#### Package.json |
| 17 | + |
| 18 | +Inside the `package.json` file you can modify the following key-value pairs with your app's (api) information: |
| 19 | + |
| 20 | +1. "name" |
| 21 | +2. "version" |
| 22 | +3. "description" |
| 23 | +4. "keywords" |
| 24 | +5. "homepage" |
| 25 | +6. "bugs" |
| 26 | +7. "repository" |
| 27 | +8. "license" |
| 28 | +9. "author" |
| 29 | + |
| 30 | +You could also add scripts that you want inside the `scripts` object of the `package.json` file. |
| 31 | + |
| 32 | +#### docker-compose.yml |
| 33 | + |
| 34 | +Inside the `docker-compose.yml` file you can modify the following values inside the postgres database container configuration. |
| 35 | + |
| 36 | +- Inside the `services` configuration you can change the name of the postgres database service (`mainDb`) to whatever you want as database docker container's service name. |
| 37 | +- As container name for the service `mainDb` (`container_name: api_dev_db`) you could change the `api_dev_db` to whatever you want as the service's docker name. |
| 38 | +- Also you could modify the `api_dev_db` inside the `volumes` configuration to whatever you want (don't forget to change it inside the `mainDb`'s service volumes and general volumes configuration inside the docker-compose file both). |
| 39 | + |
| 40 | +#### .env.example / .env (Environment Variables files configuration) |
| 41 | + |
| 42 | +Inside the `.env.example` and `.env` files you could find the following environment variables already configured: |
| 43 | + |
| 44 | +- `NODE_ENV`: This variable could only get three (3) values, `development` | `production` | `test`, depends on the running environment for the API. If you run the API locally, then prefer the `development` value. For testing purposes prefer the `test` value and for the production deployment use the `production` value. |
| 45 | +- `APPLICATION_NAME`: This variable contains the application's name that will also appears to every response as copyrighting process. |
| 46 | +- `APPLICATION_PROVIDER`: This variable contains the application's provider (usually the company or the organization that develops or developed for the current API). |
| 47 | +- `HOME_PAGE_URL`: This variable contains the application's or provider's homepage url. |
| 48 | +- `SERVER_PROT`: The port that the server runs (default and suggested for the BackEnd API is **8080**). |
| 49 | +- `BACKEND_URL`: The URL that the API runs (use either the locally distributed link -for the localhost- or the production's link). |
| 50 | +- `BACKEND_API_URL`: The URL that the API runs (use either the locally distributed link -for the localhost- or the production's link). This should also contains the prefix for the api routes-endpoints. |
| 51 | +- `SESSION_SECRET`: This variable contains a unique string with more than 32 characters inside it (suggested format is a UUID string) that is used by the system to establish the decryption of the express session's cookie. |
| 52 | + |
| 53 | +The following Environment Variables also being used by the docker compose file to construct the `mainDb` service: |
| 54 | + |
| 55 | +- `POSTGRES_HOST`: Host for Postgres database (use **localhost**, IPv4, IPv6 or a physical address domain like **https://tsalmas.com**). |
| 56 | +- `POSTGRES_PORT`: Network port that exported by the Postgres database and used by the docker services and the current API infrastructure to establish connection using Sequelize ORM for the database. |
| 57 | +- `POSTGRES_USER`: Authorized user that have admin or permitted/limited access and used by the system to execute queries inside the database. |
| 58 | +- `POSTGRES_PASSWORD`: Password for authorized user as explained before. You could also leave it blank if your user is root and doesn't have password to be authorized for the database usage. It is not suggested to leave it blank for production purposes, only for development environment. |
| 59 | +- `POSTGRES_DB`: Database name. |
| 60 | +- `DB_DIALECT`: This is used by Sequelize ORM to configure dialect being used by the ORM to setup the queries. For PostgresDB the value should be `postgres`. For other values, you could search [here](https://sequelize.org/docs/v6/other-topics/dialect-specific-things/). |
| 61 | +- `DB_MIGRATION_STORAGE`: This variable's value used by Sequelize ORM to define storage for migrations. Leave it as is `sequelize`, is the suggested option. |
| 62 | +- `DB_MIGRATION_STORAGE_TABLE_NAME`: This variable is define the table name that is been created inside the database and saved the executed migrations. You could modify it what whatever value you want. |
| 63 | +- `DB_SEEDER_STORAGE`: This variable's value used by Sequelize ORM to define storage for seeders. Leave it as is `sequelize`, is the suggested option. |
| 64 | +- `DB_SEEDER_STORAGE_TABLE_NAME`: This variable is define the table name that is been created inside the database and saved the executed seeders. You could modify it what whatever value you want. |
| 65 | + |
| 66 | +You could also add whatever variable you want to add inside. |
| 67 | + |
| 68 | +#### server/src/app.ts |
| 69 | + |
| 70 | +You could modify with your own copyrighting the code block that runs when the server is starting (`<express-server>.listen(...)`). |
| 71 | + |
| 72 | +## Run the app |
| 73 | + |
| 74 | +### Locally |
| 75 | + |
| 76 | +```bash |
| 77 | +nvm use |
| 78 | +npm run server:dev |
| 79 | +``` |
| 80 | + |
| 81 | +You can see you app running on port defined inside the environment variables inside the file `.env`. You could now ping to `https://<server-address>:<SERVER_PORT>`. If the configured port is already taken by another procedure in you system, the server will fail to start and open. |
| 82 | + |
| 83 | +### Build for production |
| 84 | + |
| 85 | +```bash |
| 86 | +nvm use |
| 87 | +npm run server:prod |
| 88 | +``` |
| 89 | + |
| 90 | +You can see you app running on port defined inside the environment variables inside the file `.env`. You could now ping to `https://<server-address>:<SERVER_PORT>`. If the configured port is already taken by another procedure in you system, the server will fail to start and open. |
| 91 | + |
| 92 | +## Handle the ORM actions |
| 93 | + |
| 94 | +Before you run any script, please be positive that you already created the directories: |
| 95 | + |
| 96 | +- `server/src/db/migrations` This directory saves the migrations for database |
| 97 | +- `server/src/db/seeders` This directory saves the seeders for database (seeding mock data) |
| 98 | +- `server/src/models` This directory saves the Sequelize entities/models, for example create a `user.model.ts` file to create `User` entity/sequelize model. |
| 99 | + |
| 100 | +### Migrations using the Sequelize CLI |
| 101 | + |
| 102 | +#### Create migration file (this file is being created in JavaScript dialect and not Typescript) |
| 103 | + |
| 104 | +```bash |
| 105 | +nvm use |
| 106 | +npm run db:create:migration <migration-name-here> |
| 107 | +``` |
| 108 | + |
| 109 | +#### Execute all the migrations for the database |
| 110 | + |
| 111 | +```bash |
| 112 | +nvm use |
| 113 | +npm run db:migrate |
| 114 | +``` |
| 115 | + |
| 116 | +#### Undo migrations |
| 117 | + |
| 118 | +- Undo a specific migration |
| 119 | + |
| 120 | +```bash |
| 121 | +nvm use |
| 122 | +npm run db:migrate:undo <migration-name-here> |
| 123 | +``` |
| 124 | + |
| 125 | +- Undo all the migrations |
| 126 | + |
| 127 | +```bash |
| 128 | +nvm use |
| 129 | +npm run db:migrate:undo:all |
| 130 | +``` |
| 131 | + |
| 132 | +### Seeding using the Sequelize CLI |
| 133 | + |
| 134 | +#### Create seeding file (this file is being created in JavaScript dialect and not Typescript) |
| 135 | + |
| 136 | +```bash |
| 137 | +nvm use |
| 138 | +npm run db:create:seed <seeder-name-here> |
| 139 | +``` |
| 140 | + |
| 141 | +#### Execute all the seeders for the database |
| 142 | + |
| 143 | +```bash |
| 144 | +nvm use |
| 145 | +npm run db:seed |
| 146 | +``` |
| 147 | + |
| 148 | +#### Undo seeders |
| 149 | + |
| 150 | +- Undo a specific seeder |
| 151 | + |
| 152 | +```bash |
| 153 | +nvm use |
| 154 | +npm run db:migrate:undo <seeder-name-here> |
| 155 | +``` |
| 156 | + |
| 157 | +## Validate input data |
| 158 | + |
| 159 | +In order to validate the input data, this system uses Zod validation. You can create a validation schema using Zod suggested schema ways and use the `inputValidation` middleware in route definition as middleware giving the zod schema to be validated. |
| 160 | + |
| 161 | +## Provided npm scripts |
| 162 | + |
| 163 | +- `server:dev`: Runs the app locally (for development environment). |
| 164 | +- `server:prod`: Runs the deployed production server. |
| 165 | +- `db:create:migration`: Create a migration file. |
| 166 | +- `db:migrate`: Execute created and not executed -yet- migrations. |
| 167 | +- `db:migrate:undo`: Undo a specific migration. This migration should be executed. |
| 168 | +- `db:migrate:undo:all`: Undo all executed migrations at once. |
| 169 | +- `db:create:seed`: Create a seeder file. |
| 170 | +- `db:seed`: Execute created and not executed -yet- seeders. |
| 171 | +- `db:seed:uno`: Undo a specific seeder. THis seeder should be executed first. |
| 172 | +- `format`: Checks if the code format complies with prettier's configured rules. |
| 173 | +- `format:fix`: Fixes the format of the code to comply with prettier's rules. |
| 174 | +- `lint`: Checks if the code quality complies with eslint's configured rules. |
| 175 | +- `lint:fix`: Fixes the format of the code to comply with eslint's rules. |
| 176 | +- `tsc`: Checks the typescript compliance inside the application's code. |
| 177 | +- `test`: Script to run tests. Tests are not configured yet and this script too. |
| 178 | +- `prepare`: Configure the husky git's custom scripts. The pre-push script is already created by this template. |
| 179 | + |
| 180 | +## Important rules |
| 181 | + |
| 182 | +### Core modules documentation |
| 183 | + |
| 184 | +The structure of the app follows at 100% of the environment the documentations listed for modules that used by the system (for versions listed inside the `package.json` file): |
| 185 | + |
| 186 | +- [Node](https://nodejs.org/en) |
| 187 | +- [Express.js](https://expressjs.com/) |
| 188 | +- [Express-Session](https://expressjs.com/en/resources/middleware/session.html) |
| 189 | +- [Sequelize](https://sequelize.org/) |
| 190 | +- [Pino logger](https://getpino.io/#/) |
| 191 | +- [Zod](https://zod.dev/) |
| 192 | + |
| 193 | +### Project structure |
| 194 | + |
| 195 | +The structure of the project is **your choice** but the recommended is the following (for `server/src`): |
| 196 | + |
| 197 | +``` |
| 198 | +(idea from bulletproof react) |
| 199 | +
|
| 200 | +src |
| 201 | +| |
| 202 | ++-- controllers # controllers for each route |
| 203 | +| |
| 204 | ++-- routes # application routes / can also be pages |
| 205 | +| |
| 206 | ++-- assets # assets folder can contain all the static files such as images, fonts, etc. |
| 207 | +| |
| 208 | ++-- config # global configurations, exported env variables etc. |
| 209 | +| |
| 210 | ++-- hooks # shared hooks used across the entire application |
| 211 | +| |
| 212 | ++-- services # reusable libraries preconfigured for the application |
| 213 | +| |
| 214 | ++-- stores # global state stores |
| 215 | +| |
| 216 | ++-- testing # test utilities and mocks |
| 217 | +| |
| 218 | ++-- types # shared types used across the application |
| 219 | +| |
| 220 | ++-- utils # shared utility functions |
| 221 | +| |
| 222 | ++-- middlewares # shared middleware functionality |
| 223 | +| |
| 224 | ++-- interfaces # application interfaces |
| 225 | +| |
| 226 | ++-- helpers # shared helpers functionality |
| 227 | +| |
| 228 | ++-- schemas # schemas for input validation using Zod |
| 229 | +``` |
0 commit comments