Raddy Website Design & Development Tutorials

Using Node.js with MySQL – CRUD | XAMPP / PhpMyAdmin

By Raddy in NodeJs ·

In this article, you are going to learn how to use MySQL using Node.js and Express. We are going to create a very basic Beer API and have a look at how we can Get records, Post records, Delete records and Update.

The connection pool wasn’t used correctly, but it shouldn’t cause any problems.

Before you get started with this project make sure that you have a MySQL database that you can use. I will be using XAMPP and phpMyAdmin for this example.

Watch full video or continue with the article

To test the get, post, delete and put methods I am using Postman.

Project Structure

We’ll keep this project simple and straight to the point. Normally if we were building a big project we would probably separate our files in views, layouts, partials, components and so on (see example here). Let’s start building our project:

📂 node_modules - automatically generated
🌍 app.js
📜 package-lock.json
📜 package-json

Install Packages

The packages that you need to be installed for your applications are Express, mysql and the body-parser. I’ve also included Nodemon so I don’t have to restart the server every time I make changes.

* NOTE The Body-Parser is no longer required *

Installing packages:

npm install express mysql body-parser

Your package.json file should look similar to mine. Of course, you might have a newer version of the packages if you are doing this in the future.

{
  "name": "nodejs-crud",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mysql": "^2.18.1"
  }
}

Restarting the local server

Let’s include Nodemon in our package.json file so we don’t have to restart the server every time we make changes. Add the following line inside “scripts”:

npm install --save-dev nodemon

To setup out application to run with nodemon just add the “start” line under scripts in your package.json file.

  "scripts": {
    "start": "nodemon app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

This is how the final document should look like.

{
  "name": "nodejs-crud",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1",
    "mysql": "^2.18.1"
  }
}

App.js

To get started, let’s require all packages at the top of our App.js file and set our listening port to be either the environment port (that’s if you are going to publish the app) or set the port to be 5000 as a default.

const express = require('express')
const bodyParser = require('body-parser')
const mysql = require('mysql')

const app = express()
const port = process.env.PORT || 5000;

// Parsing middleware
// Parse application/x-www-form-urlencoded
// app.use(bodyParser.urlencoded({ extended: false })); // Remove 
app.use(express.urlencoded({extended: true})); // New
// Parse application/json
// app.use(bodyParser.json()); // Remove
app.use(express.json()); // New

// MySQL Code goes here

// Listen on enviroment port or 5000
app.listen(port, () => console.log(`Listening on port ${port}`))

Start our local server

At this point you should have a working application and to test that you can run your project by going to your command line / PowerShell and do the following command:

npm start

Hopefully, everything should be working just fine and you won’t have any errors.

Now go to your browser and test your website on – localhost:5000

If you get the following message “Cannot Get / ” we are good to go!

Node.js Cannot Get Error

How to Node.js MySQL CRUID API

Before we start writing out MySQL code we need to make sure that we have a database that we can work with.

MySQL create new database

Now go into your newly created database nodejs_beers and add a few table columns.

PhpMyAdmin Table fields

You can also use the following command to create your table. Go to SQL and paste the query there.

CREATE TABLE `nodejs_beers`.`beers` ( `id` BIGINT NOT NULL AUTO_INCREMENT , `name` VARCHAR(255) NOT NULL , `tagline` VARCHAR(255) NOT NULL , `description` TEXT NOT NULL , `image` VARCHAR(50) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;
PhpMyAdmin Created Table

Connect Node.js with MySQL database

It’s time to make the connection to our database and our table (beers). As we are using the NPM packaged ‘mysql’ you should always refer to their documentation as versions change and so the code.

Pooling connections

Rather than creating and managing connections one-by-one, we can use connection pooling using mysql.createPool(config)Read more about connection pooling.

Note that I didn’t use the Connection pool properly, but everything should still work as expected. Update coming soon.

Create a pool and use it directly:

const pool  = mysql.createPool({
    connectionLimit : 10,
    host            : 'localhost',
    user            : 'root',
    password        : 'password',
    database        : 'nodejs_beers'
})

Now let’s get the list of all beers in our database:

// Get all beers
app.get('', (req, res) => {
    pool.getConnection((err, connection) => {
        if(err) throw err
        console.log('connected as id ' + connection.threadId)
        connection.query('SELECT * from beers', (err, rows) => {
            connection.release() // return the connection to pool

            if (!err) {
                res.send(rows)
            } else {
                console.log(err)
            }

            // if(err) throw err
            console.log('The data from beer table are: \n', rows)
        })
    })
})

Note: You probably need to insert a few records to get a result.

You can also limit the results by adding LIMIT and the number of rows you want to return:

'SELECT * from beers LIMIT 2'

Get beer by ID

For example, you could pass an ID of 1 this: http://localhost:5000/1 and this should return the row with the ID of 1. I hope this makes sense. It’s a basic SELECT statement.

// Get an beer
app.get('/:id', (req, res) => {
    pool.getConnection((err, connection) => {
        if(err) throw err
        connection.query('SELECT * FROM beers WHERE id = ?', [req.params.id], (err, rows) => {
            connection.release() // return the connection to pool
            if (!err) {
                res.send(rows)
            } else {
                console.log(err)
            }
            
            console.log('The data from beer table are: \n', rows)
        })
    })
});

Delete a record

// Delete a beer
app.delete('/:id', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        connection.query('DELETE FROM beers WHERE id = ?', [req.params.id], (err, rows) => {
            connection.release() // return the connection to pool
            if (!err) {
                res.send(`Beer with the record ID ${[req.params.id]} has been removed.`)
            } else {
                console.log(err)
            }
            
            console.log('The data from beer table are: \n', rows)
        })
    })
});

Add a beer

// Add beer
app.post('', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        
        const params = req.body
        connection.query('INSERT INTO beers SET ?', params, (err, rows) => {
        connection.release() // return the connection to pool
        if (!err) {
            res.send(`Beer with the record ID  has been added.`)
        } else {
            console.log(err)
        }
        
        console.log('The data from beer table are:11 \n', rows)

        })
    })
});

Update a record

// Update a record / beer
app.put('', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        console.log(`connected as id ${connection.threadId}`)

        const { id, name, tagline, description, image } = req.body

        connection.query('UPDATE beers SET name = ?, tagline = ?, description = ?, image = ? WHERE id = ?', [name, tagline, description, image, id] , (err, rows) => {
            connection.release() // return the connection to pool

            if(!err) {
                res.send(`Beer with the name: ${name} has been added.`)
            } else {
                console.log(err)
            }

        })

        console.log(req.body)
    })
})

And that’s all. You should now be able to read, write, update and delete data.

Final App.js document

const express = require('express')
const bodyParser = require('body-parser')
const mysql = require('mysql')

const app = express()
const port = process.env.PORT || 5000;

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// MySQL
const pool  = mysql.createPool({
    connectionLimit : 10,
    host            : 'localhost',
    user            : 'root',
    password        : 'password',
    database        : 'nodejs_beers'
})
   
// Get all beers
app.get('', (req, res) => {
    pool.getConnection((err, connection) => {
        if(err) throw err
        console.log('connected as id ' + connection.threadId)
        connection.query('SELECT * from beers', (err, rows) => {
            connection.release() // return the connection to pool

            if (!err) {
                res.send(rows)
            } else {
                console.log(err)
            }

            // if(err) throw err
            console.log('The data from beer table are: \n', rows)
        })
    })
})

// Get an beer
app.get('/:id', (req, res) => {
    pool.getConnection((err, connection) => {
        if(err) throw err
        connection.query('SELECT * FROM beers WHERE id = ?', [req.params.id], (err, rows) => {
            connection.release() // return the connection to pool
            if (!err) {
                res.send(rows)
            } else {
                console.log(err)
            }
            
            console.log('The data from beer table are: \n', rows)
        })
    })
});

// Delete a beer
app.delete('/:id', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        connection.query('DELETE FROM beers WHERE id = ?', [req.params.id], (err, rows) => {
            connection.release() // return the connection to pool
            if (!err) {
                res.send(`Beer with the record ID ${[req.params.id]} has been removed.`)
            } else {
                console.log(err)
            }
            
            console.log('The data from beer table are: \n', rows)
        })
    })
});

// Add beer
app.post('', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        
        const params = req.body
        connection.query('INSERT INTO beers SET ?', params, (err, rows) => {
        connection.release() // return the connection to pool
        if (!err) {
            res.send(`Beer with the record ID  has been added.`)
        } else {
            console.log(err)
        }
        
        console.log('The data from beer table are:11 \n', rows)

        })
    })
});


app.put('', (req, res) => {

    pool.getConnection((err, connection) => {
        if(err) throw err
        console.log(`connected as id ${connection.threadId}`)

        const { id, name, tagline, description, image } = req.body

        connection.query('UPDATE beers SET name = ?, tagline = ?, description = ?, image = ? WHERE id = ?', [name, tagline, description, image, id] , (err, rows) => {
            connection.release() // return the connection to pool

            if(!err) {
                res.send(`Beer with the name: ${name} has been added.`)
            } else {
                console.log(err)
            }

        })

        console.log(req.body)
    })
})


// Listen on enviroment port or 5000
app.listen(port, () => console.log(`Listening on port ${port}`))

Download

Thank you for reading this article. Please consider subscribing to my YouTube Channel.

More Resources:

  1. Bernard says:

    Hey Raddy I do I’ve problem when running this command in you gave in your article “nmp start” can you kindly help me with it.

    1. Raddy says:

      Hi Bernard,

      It’s “npm start” as Node Package Manager. I hope this helps.

      Raddy

    2. Julia Anna Zimtstern says:

      Hey Bernard,

      if your main has the name “index.js” you can type in the console pointed to your app directory “node index.js” ..
      Then you will probably get the output “Listening on port 5000”

      Regards,
      Julia

  2. Victor says:

    Fast, simple…
    Thanks, it worked without problems 👍🏻

    1. Raddy says:

      That’s what I like to hear! Thanks for the comment

  3. Tsopmedjio garain says:

    Nice bro ,
    Thanks

    1. Raddy says:

      Thanks for the comment, Tsopmedjio!

  4. vath says:

    Hi Raddy I do I’ve problem when running this on “INSERT beers got error SQL syntax worng format and UPDATE got undefine “can you kindly help me with it.

    1. Raddy says:

      Yes, of course! Could you share your code somehow? Maybe GitHub, or feel free to email it to me. It could be a small typo that’s breaking it for you, but we can fix it 🙂

  5. Rahul reddy says:

    hey Can u help me with full stack of vuejs and nodejs mysql crud operation?

    1. Raddy says:

      I don’t have any experience with vuejs, but there are plenty of tutorials that I’ve done on Node.js which you can use. I am thinking of trying vuejs at some point soon

  6. Danu Pratama says:

    Hello thanks for shared before, but i’m run on some issues. Its on my nodemon, its just get status “restarting due to changes”, but never status with running on port. So, its not restarting my server only “restarting due to changes” but nothing changes. Its just so confusing, i am alreday looking for answer but no one work for. If you can help please let me know?.

    1. Raddy says:

      It could be something small.

      First, make sure that you have the code below in your app.js. The second thing could be that port 5000 is taken by something else. Try port 3000 for example and restart. The last thing you can check is your console log Listening on port… Make sure that you are using slanted quotes like this: `

      const port = process.env.PORT || 5000;
      app.listen(port, () => console.log(`Listening on port ${port}`));

      If you don’t get it to work, please link a screenshot of your app.js file. I hope this works!

  7. Lionel AKE says:

    You make a great tutorial. Thank you

    1. Raddy says:

      Thank you, Lionel! I am glad that you like the tutorial

  8. nawmin says:

    can u help me?

    [nodemon] restarting due to changes…
    [nodemon] starting `node app.js`
    Listening on port 8000
    Listening on port 8000
    /home/gayashan/workspace/Log System – Backend/TestApp/app.js:27
    if(err) throw err
    ^

    Error: connect ECONNREFUSED 127.0.0.1:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1157:16)
    ——————–
    at Protocol._enqueue (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Protocol.handshake (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at PoolConnection.connect (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/mysql/lib/Connection.js:116:18)
    at Pool.getConnection (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/mysql/lib/Pool.js:48:16)
    at /home/gayashan/workspace/Log System – Backend/TestApp/app.js:26:10
    at Layer.handle [as handle_request] (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/express/lib/router/route.js:144:13)
    at Route.dispatch (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/express/lib/router/route.js:114:3)
    at Layer.handle [as handle_request] (/home/gayashan/workspace/Log System – Backend/TestApp/node_modules/express/lib/router/layer.js:95:5)
    at /home/gayashan/workspace/Log System – Backend/TestApp/node_modules/express/lib/router/index.js:284:15 {
    errno: -111,
    code: ‘ECONNREFUSED’,
    syscall: ‘connect’,
    address: ‘127.0.0.1’,
    port: 3306,
    fatal: true
    }
    [nodemon] app crashed – waiting for file changes before starting…

    1. Raddy says:

      It looks like you can’t connect to your MySQL server. I know it’s silly, but have you started Apache and MySQL? Are they all running fine? and you are doing all this locally? Double-check the port number. Is it running on 3306 or 8080? I believe that 8080 was the default.

    2. Niran says:

      I had the same problem with MAMP
      (Error: connect ECONNREFUSED 127.0.0.1:3306 )

      Turns out, for me, that all that was missing was the socketPath

      const pool = mysql.createPool({
      connectionLimit : 10,
      host : ‘localhost’,
      user : ‘root’,
      password : ‘root’,
      database : ‘nodejs_beers’,
      socketPath : ‘/Applications/MAMP/tmp/mysql/mysql.sock’
      });

      1. Raddy says:

        I appreciate you posting the solution. Thank you!

  9. nawmin says:

    im using php myAdmin doker and ubuntu os

  10. Suresh Ojha says:

    Where is the view part? Please add view part with ejs…

    1. Raddy says:

      There is no “view” part in this one. The main focus was SQL

  11. Alvin says:

    How to write link ie. http://localhost:5000/1 to insert or update or delete a record?

    I can’t get it.. thanks

    1. Raddy says:

      It would be something like this:

      // Add beer
      app.post('/:id', (req, res) => {

      connection.query('INSERT INTO beers SET ?', [req.params.id], (err, rows) => {
      // Once done, release connection
      if (error) throw error;

      if (!error) {
      // res.render('index', { rows });
      res.send(`Beer with the record ID has been added.`)
      }

      });

      });

      1. Alvin says:

        Sorry.. can you give me some example how to write url for request update query to do its job or delete query?

      2. Alvin says:

        Thanks for your reply.. but i still confuse how to write in url (Get method) to send to node.js.. ie. If i want to write delete URL

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.