{"id":2870,"date":"2020-03-26T21:22:37","date_gmt":"2020-03-26T21:52:37","guid":{"rendered":"https:\/\/ultering.com\/it4us\/?p=2870"},"modified":"2022-06-24T13:54:59","modified_gmt":"2022-06-24T14:24:59","slug":"2870","status":"publish","type":"post","link":"https:\/\/ultering.com\/it4us\/?p=2870","title":{"rendered":"NODE.JS: SEQUELIZE: EVOLVING PERSISTENCE AND CREATING BUSINESS LAYER &#8211; 3RD STEP"},"content":{"rendered":"<p>Revision 2022.<\/p>\n<h2><\/h2>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_73 counter-hierarchy ez-toc-counter ez-toc-white ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a125f43642bc\" class=\"ez-toc-cssicon-toggle-label\"><span class><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\" \/><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\" \/><\/svg><\/span><\/span><\/label><input type=\"checkbox\" id=\"ez-toc-cssicon-toggle-item-6a125f43642bc\" checked aria-label=\"Toggle\"><nav><ul class=\"ez-toc-list ez-toc-list-level-1 \"><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#TARGET\" title=\"TARGET\">TARGET<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#FAST_START_FOR_THE_IMPATIENT\" title=\"FAST START FOR THE IMPATIENT\">FAST START FOR THE IMPATIENT<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#GENERAL_NOTES\" title=\"GENERAL NOTES\">GENERAL NOTES<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Why_Using_OO\" title=\"Why Using OO?\">Why Using OO?<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#REFACTORING_THE_PERSISTENCE\" title=\"REFACTORING THE PERSISTENCE\">REFACTORING THE PERSISTENCE<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Creating_UserDB_%E2%80%93_Users_Specific_Class\" title=\"Creating UserDB &#8211; User&#8217;s Specific Class\">Creating UserDB &#8211; User&#8217;s Specific Class<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Refactoring_the_PgSeqlDB_Class\" title=\"Refactoring the PgSeqlDB Class\">Refactoring the PgSeqlDB Class<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Testing_the_new_design\" title=\"Testing the new design\">Testing the new design<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#ADDING_THE_BUSINESS_LAYER\" title=\"ADDING THE BUSINESS LAYER\">ADDING THE BUSINESS LAYER<\/a><ul class=\"ez-toc-list-level-3\"><li class=\"ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Refactoring_appjs\" title=\"Refactoring app.js\">Refactoring app.js<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Creating_the_Business_Layer\" title=\"Creating the Business Layer\">Creating the Business Layer<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-3\"><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Testing\" title=\"Testing\">Testing<\/a><\/li><\/ul><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#Conclusion\" title=\"Conclusion\">Conclusion<\/a><\/li><li class=\"ez-toc-page-1 ez-toc-heading-level-2\"><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/ultering.com\/it4us\/?p=2870\/#SOURCE_CODE\" title=\"SOURCE CODE\">SOURCE CODE<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"TARGET\"><\/span>TARGET<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This tutorial is the 3rd step of the <a href=\"https:\/\/ultering.com\/it4us\/?p=2729\">series<\/a> and its code evolves from the <a href=\"https:\/\/ultering.com\/it4us\/?p=2010\">2nd step<\/a>.<\/p>\n<p>The target is to apply Object-Oriented and MVC architecture concepts.<\/p>\n<p>The controller (the router) delivers to a business layer that accesses the persistence.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"FAST_START_FOR_THE_IMPATIENT\"><\/span>FAST START FOR THE IMPATIENT<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>&#8211; Help for linux (debian\/ubuntu) install:<\/strong><br>\n<a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/ultering_sequelize_tutorial_debian_install.txt\">ultering_sequelize_tutorial_debian_install<\/a><\/p>\n<p>After installing check the windows install below.<\/p>\n<p><strong>&#8211; Database user setup (just in the case):<br>\n<a href=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/postgres_user_setup.txt\">postgres_user_setup<\/a><\/strong><\/p>\n<p><strong><br>\n&#8211; Windows install:<br>\n<\/strong><\/p>\n<p>1. Download source code from:<\/p>\n<p><strong><a href=\"https:\/\/github.com\/alsdias\/node_sequelize_ultering_ml40643_3rd_step\">node_sequelize_ultering_ml40643_3rd_step<\/a><\/strong><\/p>\n<p>2. Use the same node_modules dir created from <a href=\"https:\/\/ultering.com\/it4us\/?p=1953\">1st step<\/a>.<br>\nYou may move it to save time and disk space.<br>\nRemember, node_modules must be under project&#8217;s root, in this case it is &#8220;node&#8221; dir.<br>\nIf you don&#8217;t have it, you may create it from this sequence of commands:<\/p>\n<pre class>npm install --save express express-generator\nnpm install - -save nodemon\nnpm install --save sequelize sequelize-cli\nnpm install --save pg pg-hstore\nnpm install --save sequelize sequelize-cli dotenv\nnpm install --save serve-favicon\nnpm audit fix --force\n<\/pre>\n<p>3. Go to app root dir and edit the config.json user config dir.<br>\nSwitch the database configuration for your respective choice (dev\/local, cloud, etc.).<\/p>\n<p>4. Go to the app root dir and edit run.bat.<br>\nSet the APP_ENV envvar to match your choice.<\/p>\n<p>rem SET APP_ENV=dev<br>\nSET APP_ENV=cloud<\/p>\n<p>5. Run the app:<br>\nrun.bat<\/p>\n<p>6. Point to:<br>\nhttp:\/\/localhost:3000\/<\/p>\n<p>If you have gone through the 2nd step, users table will be available and populated:<br>\nhttp:\/\/localhost:3000\/users<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7084\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02.jpg\" alt width=\"806\" height=\"546\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02.jpg 806w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02-300x203.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02-768x520.jpg 768w\" sizes=\"(max-width: 806px) 100vw, 806px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-7084 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20806%20546%22%3E%3C%2Fsvg%3E\" alt width=\"806\" height=\"546\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20806%20546%22%3E%3C%2Fsvg%3E 806w\" sizes=\"(max-width: 806px) 100vw, 806px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02.jpg 806w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02-300x203.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02-768x520.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/sequelize_tutorial_3rd_02.jpg\"><\/p>\n<p>&nbsp;<\/p>\n<h2><strong>GENERAL NOTES<br>\n<\/strong><\/h2>\n<p>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&#8217;s implementations. In this case, switch the configuration to match your choice, for instance, the &#8220;dialect&#8221; property value must be replaced by the new value from your choice.<\/p>\n<p>2.<strong> <em>IMPORTANT<\/em><\/strong>:<br>\n<strong>To protect clarity and keep the tutorial concise, the sequence and topics are provided in order to accomplish the main tutorial&#8217;s goal.<\/strong><br>\n<strong>Of course, some details may cause some discomfort to the reader depending on his own knowledge and understanding.<\/strong><\/p>\n<p><strong>3. The code available for download was implemented using Node.js v.16. Please, use the same version.<\/strong><\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Why_Using_OO\"><\/span>Why Using OO?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Although projects in JavaScript or C++ may be implemented without object-orientation, also making it possible to mix concepts, a better approach for the project&#8217;s clarity sake is to separate styles by layers accordingly to the contexts.<\/p>\n<p>Within this thought, a project structure may use <a href=\"https:\/\/www.geeksforgeeks.org\/mvc-design-pattern\/\">MVC<\/a> model making room for another design pattern using a specific additional layer without interfering with each other.<\/p>\n<p>This tutorial uses the OO (Object-Oriented) approach because it is one of the best choices to implement a project that may grow but is not the unique one.<br>\nOO helps to handle cohesion and avoid repeating code everywhere, keeping just one place to make maintenance easier.<br>\nThe project&#8217;s structure gets a very concise approach making much recommended for team working.<\/p>\n<p>OO is also extremely handful to treat domain relations, offering straight mapping for the growing complexity of a project.<br>\nThe cost of using OO is very low, providing powerful flexibility.<br>\nRemembering that JavaScript OO syntax is so straight, it is easy to use.<\/p>\n<h2><\/h2>\n<h2><span class=\"ez-toc-section\" id=\"REFACTORING_THE_PERSISTENCE\"><\/span>REFACTORING THE PERSISTENCE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Using the code from the 2nd step, we will evolve to a better approach.<br>\nIn the previous step, the PgSeqlDB class was useful just for the <em>User table<\/em>.<br>\nIn a real project we have hundreds of tables.<br>\nThat way, we need to split the common code to be shared with all tables from the specialized code for each one.<br>\nThis complies with cohesion pattern.<br>\nCheck <a href=\"https:\/\/docs.microsoft.com\/en-us\/archive\/msdn-magazine\/2008\/october\/patterns-in-practice-cohesion-and-coupling\">cohesion\/coupling Microsoft doc.<\/a><br>\nThe immediate advantage is that you type less and maintenance becomes easier and faster.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Creating_UserDB_%E2%80%93_Users_Specific_Class\"><\/span>Creating UserDB &#8211; User&#8217;s Specific Class<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The central idea is to move the specific implementation created for User instance to its own file.<br>\nThe common code to be used by all persistence&#8217;s classes remains in the PgSeqlDB class.<\/p>\n<p>echo. &gt; models\\persistence\\UserDB.js<\/p>\n<p>&nbsp;<\/p>\n<pre class>\/**\n * @File   : UserDB.js\n * @Author :  ()\n * @Link   : \n * @Date   : 17\/06\/2022 16:20:20\n *\/\n\nconst PgSeqlDB = require('.\/PgSeqlDB');\nvar Sequelize = require('sequelize');\n\n\/**\n * Database service using Sequelize and PostgreSQL for User table.\n *\n * @class UserDB\n *\/\nclass UserDB {\n\n    dbconfig;\n    createTable = false;\n    populate = false;\n    pgSeqlDB;\n    userModel;\n    sequelize;\n\n    \/\/ pgSeqlDB.showConfig();\n\n    constructor() {\n        this.pgSeqlDB = new PgSeqlDB(this.createTable);\n        this.dbconfig = this.pgSeqlDB.dbconfig;\n        this.sequelize = this.pgSeqlDB.sequelize;\n        this.defineUserModel();\n        this.syncDb(this.createTable);\n    }\n\n    setCreateTable(createTable) {\n        this.createTable = createTable;\n    }\n\n    setPopulate(populate) {\n        this.populate = populate;\n    }\n\n    defineUserModel() {\n        this.userModel = this.sequelize.define('User', {\n            id: {\n                type: Sequelize.INTEGER,\n                allowNull: false,\n                autoIncrement: true,\n                primaryKey: true\n            },\n            username: Sequelize.STRING,\n            password: Sequelize.STRING\n        }, {\n            tableName: 'user', \/\/ this will define the table's name\n            \/\/timestamps: false           \/\/ this will deactivate the timestamp columns\n        });\n\n    }\n\n    \/**\n     * @param  {boolean} createTable if true, creates the tables.\n     *\/\n    syncDb(createTable) {\n        this.sequelize.sync({\n                force: createTable\n            })\n            .then(function (err) {\n                \/\/console.log('[INFO]: sequelize sync done');\n            }, function (err) {\n                console.log('An error occurred while creating the table:', err);\n            });\n    }\n\n\n    insertUser(name, pass) {\n        this.userModel.create({\n            username: name,\n            password: pass\n        }).then(function (user) {\n            console.log('[INFO]: ' + user.dataValues.username + ' persisted');\n        });\n    }\n\n    populate() {\n        this.insertUser(\"John Doe\", \"secret1\");\n        this.insertUser(\"Mary Doe\", \"secret2\");\n        this.insertUser(\"Jane Doe\", \"secret3\");\n    }\n\n    showConfig() {\n        console.log(this.dbconfig);\n    }\n\n    findById(id) {\n        this.userModel.findByPk(id).then(function (user) {\n            console.log('------------------------------------------');\n            console.log('\\n[INFO]: found: ' + user.id + \", \" + user.username + '\\n');\n        });\n    }\n\n    findByName(name) {\n        this.userModel.findAll({\n            where: {\n                username: name\n            }\n        }).then(function (data, err) {\n            if (!data) {\n                console.log('------------------------------------------');\n                console.log('[FAIL]: user instance not found due to: ' + err);\n                console.log('------------------------------------------');\n            } else {\n                console.log('------------------------------------------');\n                \/\/console.log(data);\n                for (let u in data) {\n                    console.log(data[u].dataValues);\n                }\n                console.log('------------------------------------------');\n            }\n        })\n    }\n\n    findAll(res) {\n        this.userModel.findAll().then(function (data, err) {\n            if (!data) {\n                console.log('------------------------------------------');\n                console.log('[FAIL]: user instance not found due to: ' + err);\n                console.log('------------------------------------------');\n            } else {\n                let list = [];\n                for (let u of data) {\n                    list.push(u.dataValues);\n                }\n                return res.render('users', {\n                    title: 'USERS',\n                    users: list\n                });\n\n            }\n        })\n    }\n    \/\/ \n}\n\nmodule.exports = UserDB;\n<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p><strong>DESIGN NOTE:<\/strong><\/p>\n<p>Observe this snippet:<\/p>\n<div>\n<div>&nbsp; &nbsp; constructor() {<\/div>\n<div>&nbsp; &nbsp; &nbsp; &nbsp; <strong>this.pgSeqlDB = new pgSeqlDB(createTable);<br>\n&#8230;<\/strong><\/div>\n<div><span data-preserver-spaces=\"true\">Instead of extending a class using inheritance, it may be referenced, a recommended design practice: &#8220;<\/span><a class=\"_e75a791d-denali-editor-page-rtfLink\" href=\"https:\/\/en.wikipedia.org\/wiki\/Composition_over_inheritance\" target=\"_blank\" rel=\"noopener noreferrer\"><span data-preserver-spaces=\"true\">Favor Aggregation\/Composition over Inheritance<\/span><\/a><span data-preserver-spaces=\"true\">&#8220;.<br>\n<\/span>See more at:<br>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Composition_over_inheritance\">Composition over inheritance Wikipedia<\/a><br>\n<a href=\"https:\/\/netobjectivesthoughts.com\/advice-from-the-gof-favor-composition-over-inheritance\/\">Advice from the GoF: Favor Composition Over Inheritance<\/a><\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Refactoring_the_PgSeqlDB_Class\"><\/span>Refactoring the PgSeqlDB Class<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The PgSeqlDB class will remain with the code that is shared among all other persistence classes.<\/p>\n<p>Replace the previous code with this one:<\/p>\n<p>&nbsp;<\/p>\n<pre class>var Dbconfig = require('..\/..\/config\/config.json');\nvar Sequelize = require('sequelize');\n\n\/**\n * Database service using Sequelize and PostgreSQL.\n *\n * @class PgSeqlDB\n *\/\nclass PgSeqlDB {\n\n    dbconfig;\n    sequelize;\n\n    static configuration() {\n        \/\/ process.env.APP_ENV captures what was set in the run.bat in the line: SET APP_ENV=dev\n        if (process.env.APP_ENV == 'dev') {\n            console.log('[INFO]: database configuration set to development.')\n            return Dbconfig.development;\n        } else if (process.env.APP_ENV == 'prod') {\n            console.log('[INFO]: database configuration set to production.');\n            return Dbconfig.production;\n        } else if (process.env.APP_ENV == 'cloud') {\n            console.log('[INFO]: database configuration set to cloud.');\n            return Dbconfig.cloud;\n        } else if (process.env.APP_ENV == 'test') {\n            console.log('[INFO]: database configuration set to test environment.')\n            return Dbconfig.test;\n        }\n        console.log('[WARN]: database configuration not defined, assuming default (dev): ' + Dbconfig.development.database);\n        return Dbconfig.development;\n    }\n\n\n    constructor() {\n        this.dbconfig = PgSeqlDB.configuration();\n        this.sequelize = this.connection(this.dbconfig);\n    }\n\n\n    connection(config) {\n        let sequelize = new Sequelize({\n            username: config.username,\n            password: config.password,\n            database: config.database,\n            host: config.host,\n            port: config.port,\n            dialect: config.dialect\n        });\n        sequelize.authenticate(config).then(function () {\n            console.log('[INFO]: database authenticated');\n        }, function (err) {\n            console.log('[EXCP]: database authentication failed due to: ' + err)\n        });\n        return sequelize;\n    }\n\n\n};\n\n\nmodule.exports = PgSeqlDB;\n<\/pre>\n<p>&nbsp;<\/p>\n<pre class>module.exports = PgSeqlDB;\n<\/pre>\n<h3><span class=\"ez-toc-section\" id=\"Testing_the_new_design\"><\/span>Testing the new design<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Run the app (run.bat).<br>\nPoint to:<br>\nhttp:\/\/localhost:3000\/users<\/p>\n<p>The view shall render exactly in the same way.<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-6967\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11.jpg\" alt width=\"1000\" height=\"541\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11.jpg 1000w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11-300x162.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11-768x415.jpg 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-6967 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201000%20541%22%3E%3C%2Fsvg%3E\" alt width=\"1000\" height=\"541\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201000%20541%22%3E%3C%2Fsvg%3E 1000w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11.jpg 1000w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11-300x162.jpg 300w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11-768x415.jpg 768w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_11.jpg\"><\/p>\n<h2><span class=\"ez-toc-section\" id=\"ADDING_THE_BUSINESS_LAYER\"><\/span>ADDING THE BUSINESS LAYER<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>We&#8217;ve refactored the persistence layer.<br>\nNow, we need to refactor the router because it is accessing the persistence layer.<br>\nA good approach is to create a business layer that handles the use cases, abstracting the router from a concern that doesn&#8217;t belong to it.<br>\nIn this case, the business layer reflects the needs of use cases and it is responsible to access the persistence layer.<\/p>\n<p>In a simple project like this it would seem useless additional complexity but in a real project makes the difference.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Refactoring_appjs\"><\/span>Refactoring app.js<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Comment the previous code.<br>\nThe commented code is useful to help us understand the changes.<\/p>\n<p><noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-6987\" src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12.jpg\" alt width=\"603\" height=\"506\" srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12.jpg 603w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12-300x252.jpg 300w\" sizes=\"(max-width: 603px) 100vw, 603px\"><\/noscript><img decoding=\"async\" class=\"alignnone size-full wp-image-6987 lazyload\" src=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20603%20506%22%3E%3C%2Fsvg%3E\" alt width=\"603\" height=\"506\" srcset=\"data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20603%20506%22%3E%3C%2Fsvg%3E 603w\" sizes=\"(max-width: 603px) 100vw, 603px\" data-srcset=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12.jpg 603w, https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12-300x252.jpg 300w\" data-src=\"https:\/\/ultering.com\/it4us\/wp-content\/uploads\/rin544c_2nd_step_12.jpg\"><\/p>\n<div><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Creating_the_Business_Layer\"><\/span>Creating the Business Layer<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>cd node<br>\nmkdir models\\business<br>\necho. &gt; models\\business\\UserSvc.js<\/p>\n<div>Edit UserSvc.js and add the code below:<\/div>\n<div><\/div>\n<div><strong>UserSvc.js<\/strong><\/div>\n<div>\n<p>&nbsp;<\/p>\n<pre class>\/**\n * @File   : userSvc.js\n * @Author :  ()\n * @Link   : \n * @Date   : 16\/06\/2022 22:27:12\n *\/\n\nconst UserDB = require('..\/persistence\/UserDB');\n\nclass UserSvc {\n\n    userDB;\n    createTable = false;\n    populate = false;\n\n    constructor() {\n        this.userDB = new UserDB();\n    }\n\n    setCreateTable(createTable) {\n        this.createTable = createTable;\n    }\n\n    setPopulate(populate) {\n        this.populate = populate;\n    }\n\n    async list(res) {\n        return await this.userDB.findAll(res);\n    }\n\n\n    async findById(id) {\n        return await this.userDB.findById(id);\n    }\n\n    async findByName(name) {\n        return await this.userDB.findByName(name);\n    }\n\n    async findAll(res) {\n        return this.userDB.findAll(res);\n    }\n\n}\n\nmodule.exports = UserSvc;\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Testing\"><\/span>Testing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Run the app (run.bat).<br>\nPoint to:<br>\nhttp:\/\/localhost:3000\/users<\/p>\n<p>It is supposed to render as usual.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Now we have completed the most important concepts, implemented them and tested.<br>\nIt is time to upgrade our skill applying them on a more complex use case that it will be seen on the next step.<\/p>\n<p>&nbsp;<\/p>\n<h2><span class=\"ez-toc-section\" id=\"SOURCE_CODE\"><\/span>SOURCE CODE<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><strong>Source code to download on GitHub <\/strong>using&nbsp; Node.js v.16<strong>, <a href=\"https:\/\/github.com\/alsdias\/node_sequelize_ultering_ml40643_3rd_step\">node_sequelize_ultering_ml40643_3rd_step<\/a><\/strong><\/p>\n<p><a href=\"https:\/\/ultering.com\/it4us\/?p=6999\"><strong>Next<\/strong><\/a><\/p>\n<p><a href=\"https:\/\/ultering.com\/it4us\/?p=2010\"><strong>Previous<\/strong><\/a><\/p>\n<p><strong>INDEX<\/strong>:<br>\n<a href=\"https:\/\/ultering.com\/it4us\/?p=2729\">NODE.JS: SEQUELIZE SERIES<\/a><\/p>\n<p>&nbsp;<\/p>\n<!--CusAds0-->\n<div style=\"font-size: 0px; height: 0px; line-height: 0px; margin: 0; padding: 0; clear: both;\"><\/div>","protected":false},"excerpt":{"rendered":"<p>Revision 2022. TARGET This tutorial is the 3rd step of the series and its code evolves from the 2nd step. The target is to apply Object-Oriented and MVC architecture concepts. The controller (the router) delivers to a business layer that accesses the persistence. &nbsp; FAST START FOR THE IMPATIENT &#8211; Help for linux (debian\/ubuntu) install: &#8230; <a href=\"https:\/\/ultering.com\/it4us\/?p=2870\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> &#8220;NODE.JS: SEQUELIZE: EVOLVING PERSISTENCE AND CREATING BUSINESS LAYER &#8211; 3RD STEP&#8221;<\/span> &raquo;<\/a><\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[152,17,26,206,143],"tags":[],"class_list":["post-2870","post","type-post","status-publish","format-standard","hentry","category-dp","category-database","category-javascript","category-node-js","category-web-design"],"_links":{"self":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/2870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2870"}],"version-history":[{"count":6,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/2870\/revisions"}],"predecessor-version":[{"id":7131,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=\/wp\/v2\/posts\/2870\/revisions\/7131"}],"wp:attachment":[{"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ultering.com\/it4us\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}