Revision 2022.
Table of Contents
TARGET
This tutorial is the 4th step of the series and its code evolves from the 3rd step.
The target is to apply Object-Oriented and MVC architecture concepts for a Todo site using relationship, where:
Todo 1 ——– + TodoItem
One Todo may have one or more TodoItem instances.
The concepts seen before will be applied in a more complex use case.
FAST START
– Help for linux (debian/ubuntu) install:
ultering_sequelize_tutorial_debian_install
After installing check the windows install below.
– Database user setup (just in the case):
postgres_user_setup
– Windows install:
1. Download source code from GitHub:
node_sequelize_ultering_ml40643_4th_step
2. Use the same node_modules dir created from 1st step.
You may move it to save time and disk space.
Remember, node_modules must be under project’s root, in this case it is “node” dir.
3. Go to app root dir and edit the config.json user config dir.
Switch the database configuration for your respective choice (dev/local, cloud, etc.).
4. Go to the app root dir and edit run.bat.
Set the APP_ENV envvar to match your choice.
Recommended to use your local database.
ElephantSQL free plan will not work due to pool limit (see note below).
SET APP_ENV=dev
rem SET APP_ENV=cloud
Create your local PostgreSQL database instance and set its configuration in node/config/config.json file (topic #3).
It is not necessary to create the tables.
It will be created by Sequelize and populated by the app.
Just log into your local database and do:
create database DBNAME
– For instance:
create database run455_dev
5. Run the app:
run.bat
6. Point to:
http://localhost:3000/
Go to menu and choose users.
Click on populate, then list.
To access Todo use case (story), go to menu and choose Tools.
Click on populate.
Return to the menu and choose “List”.
That’s it. Have fun! 🙂
GENERAL NOTES
1. Although this tutorial uses PostgreSQL, it may be used any other database since the purpose of ORM is to provide a layer of abstraction for the database’s implementations. In this case, switch the configuration to match your choice, for instance, the “dialect” property value must be replaced by the new value from your choice.
2. IMPORTANT:
To protect clarity and keep the tutorial concise, the sequence and topics are provided in order to accomplish the main tutorial’s goal.
Of course, some details may cause some discomfort to the reader depending on his own knowledge and understanding.
3. The code available for download was implemented using Node.js v.16. Please, use the same version.
4. The “elephantsql original: error: too many connections for role” issue.?
ElephantSQL has a 5 connection limit on their free plan.
More information at:
The ‘too many connections for role’ error with Postgres on serverless
HOW TO USE THIS TUTORIAL
1. Download the code from GitHub
node_sequelize_ultering_ml40643_4th_step
2. Watch the video to get an overview.
3. Follow the “Sightseen”.
THE TUTORIAL’S APPROACH FOR A HIGHER LEVEL
The previous steps were very important to get the grips with Node.js/Express using Sequelize.
Due to its simplicity, it was possible to go step by step in a very detailed way.
We’ve followed that strategy for the 1st, 2nd, and 3rd steps.
The 4th step applies all the concepts seen before and jumps to the MVC pattern plus additional features.
If it was adopted the same strategy for this step, the tutorial would become too large, boring, and discouraging.
If you have been through the previous steps, the code will be self-explainable and the key points are described here through the “sightseen guide”.
This strategy becomes faster and straight.
THE SIGHTSEEN GUIDE
Extra Setup – The Scaffolding
Most applications require extra stuff to support them.
It is usually named “scaffolding”.
Below, it details part of it as if it was created from the 3rd step.
It is not necessary to follow it because the downloaded code is already complete.
Use it just to get acquainted with the new step and what was done to fulfill this step.
App.js cleaning
Removed the commented code from app.js from the previous step.
No more necessary. Before, it was used for testing purposes.
Utils
This step leverages the application complexity to something near the real world.
That way, we need extra support.
Created the utils package on the app’s root dir for the utility classes that will help us with common tasks shared across the project — cohesion must be in mind all the time (avoid repeating code in different places).
Persistence extra configuration
It was also created an extra file that will be used to choose if we desire to create or not the tables.
echo. > config\createdb.json
How does it work?
When necessary to create the tables, set:
{“create_db”:”true”}
and run the app.
After the first time, switch to false to preserve the data.
{“create_db”:”false”}
DTOs
It uses DTOs, a very resourceful pattern.
The dto.7z files were added to node\models .
Favicon
Favicon install procedure:
- Created the favicon image:
favicon.7z
. - Moved the favicon to the node\public\images folder.
. - Installed the favicon package:
npm install serve-favicon
. - Edited app.js and added the following snippet:
var favicon = require(‘serve-favicon’);
app.use(favicon(__dirname + ‘/public/images/favicon.ico’));
or
app.use(favicon(path.join(__dirname,’public’,’images’,’favicon.ico’));
. - Restarted the app (run.bat) and the browser.
. - Tested, pointing to:
http://localhost:3000/favicon.ico
. - Pointed to the app:
http://localhost:3000/users
TodoHelper.js
It provides extra operations to populate the todo’s database.
The app.js is set to register it:
var tdoRouter = require(‘./routes/todo’);
I usually like to organize the code by putting together similar statements.
For instance:
…
menu.esj
This is the menu shared by all pages, and it is included using the following statement:
<%- include(‘menu’) %>
Persistence for Todo use case
TodoDB
Instead of extending a class using inheritance, it may be referenced, a recommended design practice — “Favor Aggregation/Composition over Inheritance“, as mentioned previously.
Although being a good thing, it promotes an additional effort to start learning a new API.
How do I do this?
Which alternative should I choose?Sequelize is not an exception.
For instance, you may extend a class from Model or not.
Here is an example extracted from the Sequelize documentation.
The example above uses the init method.
This tutorial doesn’t use this approach.
Alternatively, the class does not extend from Model as you may check when comparing with the TodoDB.js code.
The Todo Object
This is how it looks like when retrieved by Sequelize query:
THE SERVICE LAYER
In the previous code, the database had straight access.
This is not the best approach.
Since we are following MVC pattern, the service is responsible to materialize the “use cases” (stories) and access the database.
The DbSvc.js class contains the code that is common to all services, so the other services classes extend it.
For example, the “populate” method uses a helper class and performs the database access.
Everything that concerns that feature that reflects a story remains in just one place, one layer.
Now, please compare the service with the TodoDB.js database class.
There is just database stuff, no “stories'” (use cases) stuff, so there is no leak of concern.
The database layer must deal with the database and nothing more.
Service materializes features, but it doesn’t handle the database directly but through the database layer.
The control (routes/navigation) is just a client that calls the service and everything else is transparent to it.
This is the beauty of this pattern making it easy to implement and maintain an app.
CONCLUSION
Everything shall be implemented in its own place, without having scattered code throughout the whole application that leads to confusion and madness when maintenance comes to play.
Although JavaScript and C++ are flexible languages that make possible to mix styles, we shall avoid everything that could mess with the organization that supports a secure and fast way of implementing an application.
SOURCE CODE
Source code to download on GitHub using Node.js v.16, node_sequelize_ultering_ml40643_4th_step
INDEX:
NODE.JS: SEQUELIZE SERIES
BIBLIOGRAPHY
sequelize.readthedocs.io/en/rtd/articles/getting-started/
sequelize.org/master/manual/model-instances.html
sequelize.org/master/manual/migrations.html
sequelize.org/master/manual/raw-queries.html
Brazilian system analyst graduated by UNESA (University Estácio de Sá – Rio de Janeiro). Geek by heart.