This is a very basic NodeJS application for web API microservices that uses express with express-session, sequelize-typescript to connect to a SQL database and authenticate users. This example includes microservices for basic blog features: registering and authenticating of users (authors) and posting blog posts by authenticated users. The project is set up for using TypeScript and you can see some additional @types
packages that provide TS support. The app is written following the proper OOP approach using TypeScript classes with decorators and of course - declared types for each variable and function. Additionally, I've used packages like helmet and bcrypt to introduce some security to the app (check out those packages for additional options).
In order to build and run the application you must have NodeJS (v20 or higher is recommended) with npm on your machine. Having that set up, you need to navigate to the root directory of the project and run the npm install
command to install all local packages. Since the project is meant to be used with a MySQL database - you need to set up a MySQL server and create a database that you'll be using. Create your local .env
file and add the necessary variables for accessing the database (host, username, password, etc.). You can find the names of these variables in the .env.example
file. As you can see, you also need to provide a SESSION_SECRET
variable which can by any string and it's going to be used to sign the session cookie.
Additionally - make sure that your IDE has TypeScript support and the necessary plug-ins for ESLint and EditorConfig configurations to work.
Since the source code is in TypeScript, it needs to be compiled first before running. I've set up a few npm scripts that would ease that for you. All compiled files can be found in the /dist
directory which is located in the root of the project.
- Running
npm run build
will simply compile the code in JavaScript using the TypeScript CLI. - Running
npm run start
will compile the code and run it into a NodeJS server. - Running
npm run start:populate_db
will compile the code, run it into a NodeJS server, and populate the databse with examples. - Running
npm run dev
will use nodemon to directly run your project from the source without the need to compile. It also reloads the app everytime you make changes in your source and save them. This is the required command for running the app in dev environment.
You can also provide a PORT
environment variable for explicitly chosing a port for the server. Otherwise the app will default to 8080.
In the root of the project you will find the package.json
file that each node project has. You can change some properties like name, version, author, description and also add more npm scripts if needed. You have tsconfig.json
and .eslintrc
files for advanced TypeScript and ESLint configuration. The file .editorconfig
declares some rules that your IDE should apply to each newly created file. As mentioned above - you might need ESLint and editorconfig plugins for your IDE. The .env.example
file contains an example of what your environment variables should be. Create a local .env
file (it should be excluded by gitignore), copy the content of .env.example
and change the variables to suit your configuration. You can also create multiple files for different configurations (for example - .env.development
and env.production
).
The source of the project is located in the /src
folder. The project uses a modular structure - instead of having separate folders for models, controllers and routes, each module is put into its own folder with its respective model, controller and route file. It might seem weird at first but it scales well and it's a better approach if your app tends to grow bigger.
The routes.ts
file is used to register the API routes and it exports a function which takes the app object as an argument. When you add more modules, you would have to implement their route files in the same way, import them in routes.ts
and register them in the app.
The sequelize.ts
file contains the initialization of the database using Sequelize. Sequelize allows you to use a OOP approach of generating models and making queries to the database. As mentioned earlier - all the data for initializing the database is obtained from the environment file. Keep in mind that all data models should be registered here so when you make new entities, simply import the models in sequelize.ts
and add the classes to the models
argument (just like I added User and BlogPost).
The session.ts
file contains the initialization of the ExpressJS session feature for using session cookies to authenticate the users. By default sequelize store the sessions in files but we use connect-session-sequelize to override this behavior so the app will store them in the database.
The app.ts
file is the main file of the application which is being run by the node server. Here we import all main packages, including our files routes.ts
, session.ts
and sequelize.ts
. All necessary packages and configurations are being applied to the ExpressJS app and then it starts listening on the configured port.
All microservices can be accessed on the /api/
url and you can find all route definitions in the *.routes.ts
fiels of the modules. All end points work with JSON so you need to pass a content-type: application/json
header. The database is populated with 10 random users and blog-posts using the faker
package.
For exmaple, to register a user, you need to do a POST request to <server-url>/api/auth/register
and pass the following JSON structure:
{
"username": "johndoe1",
"password": "123456",
"fullName": "John Doe",
"email": "[email protected]"
}
If the registration was successful, the user should be instantly logged in with a session. A similar request is required for login but on the /api/auth/login
endpoint using username and password. If you want to log out simply do an empty POST request to /api/auth/logout
.
To create a blog post, you need to be logged in and do a POST request to <server-url>/api/blog-posts
and pass the following JSON structure:
{
"title": "My first blog post",
"description": "This is my first blog post, I'm so excited!",
"published": true
}
This should create a blog post which will be related to the currently logged user.
Add a couple of blog posts from different users then check out the different routes of the Blog Post module that allow you to do different types of queries.
The project can be used as a base on which you can upgrate and scale your application. You can use more advanced methods of authentication, for example using passport. Additionally, if you prefer different database implementation, you can easily modify the project and use PostgreSQL, MongoDB or many others (they also have dedicated official packages for ExpressJS). Of course in this case you should chose a different session store for expres-session than Sequelize.