Membuat Web CRUD dengan Nodejs dan Mysql

Membuat Web CRUD dengan Nodejs dan Mysql
Konten Halaman

Membangun website sederhana menggunakan tech stack nodejs, expressjs, mysql database dan html render menggunakan ejs(Embedded JavaScript templating) template engine untuk merender di sisi server.

contoh tutorial disini menggunakan studi kasus membangun website blog sederhana dan menggunakan frame css bootstrap.

Di postingan tutorial ini berisikan gambaran penjelasan tentang project app dari simple_crud_expressjs yang ada di https://github.com/SigitNurhanafi/simple_crud_expressjs

Install Nodejs dan Mysql

Di post tutorial ini saya menggunakan sistem operasi Windows 10, bagi yang sama menggunakan Windows 10 dan masih belum menginstall nodejs bisa mengikuti Cara Install NodeJS di Windows .

Untuk Mysql database menggunakan bundle dari XAMPP untuk lengkapnya bisa mengikuti Cara Install MySQL di Windows.

Install Expressjs dan library lainnya

Pastikan Nodejs dan npm sudah bisa berjalan melalui CMD

  • inisialisi npm di folder project
npm init -y
  • install library ExpressJs, ejs, mysql2
npm install express mysql mysql2 validator --save

Penjelasan:

  • npm install : npm adalah manajemen library untuk nodejs yang membutuhkan koneksi internet ketika lakukan penginstalan sedangkan kata install artinya untuk melakukan instalasi sebuah library.
  • express : adalah framework web minimalis nodejs untuk membangun aplikasi berbasis website.
  • mysql2: adalah sebuah library mysql untuk melakukan komunikasi dengan database mysql.
  • ejs : adalah library untuk merender HTML disisi server.
  • validator : adalah library untuk validasi setiap inputan dari user.
  • --save: kata ini untuk melakukan perintah menyimpan daftar dependencies library ingin digunakan ke dalam file package.json .

Template Bootstrap 4

Untuk template Bootstrap menggunakan template example bisa dilihat disini Example Bootstrap Template Blog

atau kalian bisa langsung download dengan cara klik tombol example https://getbootstrap.com/docs/4.0/examples/ atau bisa klik disini bentuknya dalam zip kemudian diekstrak dan ambil bagian folder blog di dalamnya.

Struktur database Mysql

Struktur databasenya yang digunakan hanya satu table yaitu post

Membuat Database Untuk MongoDB

CREATE DATABASE `simple_crud`;

Create Table post

kolomnya yang dibuat yaitu id, title, content, slug_id, dan created_at

CREATE DATABASE IF NOT EXISTS `simple_crud`;
USE `simple_crud`;

CREATE TABLE IF NOT EXISTS `post` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` tinytext,
  `content` text,
  `slug_id` varchar(225) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `slug_id` (`slug_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Pengkodean Nodejs dan Expressjs

Test untuk persiapan menjalankan Nodejs dan mysql

isi pengkodean di index.js dalam tahap awal ini untuk mengetes apakah ExpressJS sudah berjalan tanpa error.

// index.js

const express = require('express');

const app = express();
const port = 3030;

app.use(express.static('public'));

app.get('/', (req, res) =>
  res.send('belajar membangun Web CRUD di nodejs mysql')
);

app.listen(port, () => console.log(`App listening to port ${port}`));

lalu jalankan perintah node index.js di console anda yang sebelumnya menjalankan perintah instalasi library cara menjalankan nodejs di windows cmd

lanjut kita akses ke http://localhost:3030 maka jika tanpa error output akan seperti ini menjalankan epxressjs di port 3030

Koneksi Nodejs ke Mysql

berikut ini isi pengkodean melakukan koneksi dari nodejs ke mysql melakukan koneksi biasa tanpa menggunakan pooling

const mysql = require('mysql');

// Konfigurasi koneksi nodejs ke mysql
let dbCon = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'simple_crud',
});

// Membuat koneksi nodejs ke mysql
dbCon.connect((err) => {
  if (err) {
    console.log('Membuat koneksi nodejs ke mysql gagal', err);
  } else {
    console.log('Membuat koneksi nodejs ke mysql berhasil ');
  }
});

module.exports = dbCon;

Penjelasan :

  • const mysql = require('mysql'); : pemanggilan library atau pustaka mysql untuk bisa melakukan komunikasi nodejs dengan mysql
  • let dbCon = mysql.createConnection({ : bagian fungsi ini adalah konfigurasi koneksi ke mysql berisi host, user, password, dan database yang bisa digunakan.
  • dbCon.connect((err) : fungsi ini pengecekan jika mysql berhasil atau gagal berkomunikasi dengan nodejs
  • module.exports = dbCon; : pada akhirnya semua fungsi yang dibuat akan diekspor atau supaya bisa digunakan di file javascript yang lain.

Menampilkan data blog di ejs template engine

template ejs bagian head

di bagian ini berisi pemanggilan CSS framework bootstrap versi 4 buat file head.ejs dengan folder path ini simple_crud\views\partials\head.ejs

<meta charset="UTF-8" />
<title>Post Simple CRUD Web</title>

<!-- CSS (load bootstrap from a CDN) -->
<link
  rel="stylesheet"
  href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css"
/>
<style>
  body {
    padding-top: 50px;
  }
</style>

Template EJS bagian header

bagian ini untuk keperluan menampilkan beberapa Menu diantaranya Home, New Post, dan Update Post. file header.ejs dengan folder di path simple_crud_expressjs\views\partials\header.ejs

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="/"> Simple CRUD </a>
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a class="nav-link" href="/"> Home </a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/create"> New Post </a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/update"> Update Post </a>
    </li>
  </ul>
</nav>

footer ini hanya untuk opsional saja ditambahkan atau tidak tidak masalah file footer.ejs dengan folder di path simple_crud_expressjs\views\partials\footer.ejs

<p class="text-center text-muted">© Copyright 2022 Simple CRUD</p>

Membuat logic untuk template EJS dan ExpressJS di NodeJS

Bagian ini kita akan membangun function dengan logic menerima data dari request yang dikirim dari form html. bagian bagian terkait MySQL dan melakukan eksekusi query dari NodeJS ke MySQL server.

Membuat function untuk EJS di NodeJS bagian home

Bagian pengkodean NodeJS yang melakukan koneksi ke MySQL maka kita panggil terlebih dahulu ke NodeJS disini kita membuat file terpisah dengan nama file mysql.js di bagian luar sejajar dengan index.js

const mysql = require('mysql');

// Konfigurasi koneksi nodejs ke mysql
let dbCon = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: '',
  database: 'simple_crud',
});

// Membuat koneksi nodejs ke mysql
dbCon.connect((err) => {
  if (err) {
    console.log('Membuat koneksi nodejs ke mysql gagal', err);
  } else {
    console.log('Membuat koneksi nodejs ke mysql berhasil ');
  }
});

module.exports = dbCon;
  • const mysql = require('mysql'); : pemanggilan library atau pustaka mysql untuk bisa melakukan komunikasi nodejs dengan mysql
  • let dbCon = mysql.createConnection({ : bagian fungsi ini adalah konfigurasi koneksi ke mysql berisi host, user, password, dan database yang bisa digunakan.
  • dbCon.connect((err) : fungsi ini pengecekan jika mysql berhasil atau gagal berkomunikasi dengan nodejs
  • module.exports = dbCon; : pada akhirnya semua fungsi yang dibuat akan diekspor atau supaya bisa digunakan di file javascript yang lain.

setelah melakukan pengkodean untuk bisa berkomunikasi dengan mysql maka selanjutnya kita menggunakan sebuah library express js untuk bisa diakses menggunakan protokol HTTP dan library EJS untuk mencetak logic javascript dan tag HTML supaya bisa diakses di browser. berikut ini potongan pengkodean awal CRUD kita yang akan dibuat:

- Bagian function ExpressJS untuk bagian Home

// Index page
// simple_crud\index.js
const express = require('express');
const databaseMysql = require('./mysql');
const app = express();
const port = 3030;

var validator = require('validator');

// untuk mendapatkan data dari post form html
app.use(express.json()); // for parsing application/json
app.use(express.urlencoded({ extended: true }));

// set view template untuk ejs di express
app.set('view engine', 'ejs');
app.use(express.static('public'));

// index list page
app.get('/', function (req, res) {
  let sql = `SELECT title, content, slug_id FROM post`;

  databaseMysql.query(sql, (error, results, fields) => {
    if (error) {
      console.log(error);
      return res.render('pages/index', {
        error: true,
        messages: 'Ada masalah koneksi Nodejs ke Mysql',
      });
    } else {
      console.log(results);

      return res.render('pages/index', {
        error: false,
        posts: results,
      });
    }
  });
});

Penjelasan:

  • const express = require('express'); : memanggil lib expressjs untuk bisa dijalankan di file nodejs ini.
  • const databaseMysql = require('./mysql'); : memanggil file konfigurasi mysql
  • const app = express(); : menyimpan function lib express js ke sebuah variabel ke berbentuk const
  • var validator = require('validator'); memanggil lib validasi untuk pengecekan dan pengkondisian sebuah data.
  • app.get( : untuk melakukan akses data dengan method GET di HTTP
  • databaseMysql.query( : di function ini proses query ke MySQL dijalankan dan hasilnya dikembalikan dari fungsi ini.
  • return res.render( : melakukan render atau pencetakan output di sisi client

- Bagian function EJS untuk bagian Home

<!DOCTYPE html>
<html lang="en">
  <head>
    <%- include('../partials/head'); %>
  </head>
  <body class="container">
    <header><%- include('../partials/header'); %></header>

    <main>
      <div class="jumbotron">
        <h1>Simple CRUD dengan Nodejs dan Mysql</h1>
        <p>Selamat datang di CRUD (Create, Read, Update, Delete) Post</p>
      </div>

      <div class="row">
        <% posts.forEach(function(post) { %>
        <div class="col-sm-6 mb-3">
          <div class="card">
            <div class="card-body">
              <h5 class="card-title"><%= post.title %></h5>
              <p class="card-text"><%= post.content.slice(0, 10)+'...' %></p>
              <a href="/read/<%= post.slug_id %>" class="btn btn-primary"
                >Lanjut Membaca</a
              >
            </div>
          </div>
        </div>
        <% }); %>
      </div>
    </main>

    <footer><%- include('../partials/footer'); %></footer>
  </body>
</html>

Penjelasan:

  • <%- include('../partials/head'); %> : melakukan import dari file EJS yang lain
  • <%= post.title %> : melakukan pencetakan data post yang dikirim dari ke template EJS
  • <%= post.content.slice(0, 10)+'...' %> : pencetakan data dan ditambah limitasi menggunakan function slice dan dikombinasikan titik ...

- Membuat function Express JS Create Post di NodeJS

di proses insert data ke Mysql bagian post

// Create page
// simple_crud\index.js
app
  .get('/create', function (req, res) {
    res.render('pages/create_post');
  })
  .post('/create', function (req, res) {
    if (
      validator.isEmpty(req.body.content) ||
      validator.isEmpty(req.body.title)
    ) {
      return res.render('pages/create_post', {
        error: true,
        messages: 'Data title atau content tidak boleh kosong',
      });
    }

    let { title, content } = req.body;

    // membuat slug dari title
    slug_id = title
      .toString()
      .toLowerCase()
      .replace(/^-+/, '')
      .replace(/-+$/, '')
      .replace(/\s+/g, '-')
      .replace(/\-\-+/g, '-')
      .replace(/[^\w\-]+/g, '');

    // query mysql insert data content mysql
    let sql = `INSERT INTO post SET ?`;

    // prepared insert data content mysql
    let data = { title, content, slug_id };

    databaseMysql.query(sql, data, (error, results, fields) => {
      if (error) {
        console.log(error);
        return res.render('pages/create_post', {
          error: true,
          messages: 'Ada masalah koneksi Nodejs ke Mysql',
        });
      }
    });

    return res.render('pages/create_post', {
      error: false,
      messages: 'Data post berhasil ditambahkan',
    });
  });

Penjelasan

  • validator.isEmpty(: melakukan pengecekan data dari lib validator
  • slug_id = title.toString().toLowerCase().replace(/^-+/, '').replace(/-+$/, '').replace(/\s+/g, '-').replace(/\-\-+/g, '-').replace(/[^\w\-]+/g, ''); : menggenerate dari title sebagai slug, yang memproses pengubahan dari spasi karakter ke -.

Membuat template EJS Create Post di NodeJS

<!DOCTYPE html>
<html lang="en">
  <head>
    <%- include('../partials/head'); %>
  </head>
  <body class="container">
    <header><%- include('../partials/header'); %></header>

    <main>
      <%if (typeof(error) !== "undefined" && error === true) { %>
      <div class="alert alert-danger" role="alert"><%= messages %></div>
      <% } %> <% if (typeof(error) !== "undefined" && error === false) { %>
      <div class="alert alert-success" role="alert"><%= messages %></div>
      <% } %>

      <form action="/create" method="post">
        <div class="form-group">
          <label for="exampleInputEmail1">title</label>
          <input name="title" class="form-control" placeholder="Enter title" />
        </div>

        <div class="form-group">
          <label for="exampleInputEmail1">content</label>
          <textarea
            name="content"
            class="form-control"
            id="exampleFormControlTextarea1"
            rows="3"
          ></textarea>
        </div>

        <button type="submit" class="btn btn-primary mb-2">Post Now</button>
      </form>
    </main>

    <footer><%- include('../partials/footer'); %></footer>
  </body>
</html>

Bagian function ExpressJS Read data MySQL di NodeJS

// Read single post page
app.get('/read/:slug_id', function (req, res) {
  let sql = `SELECT * FROM post WHERE slug_id = ? LIMIT 1`;
  let slug_id = req.params.slug_id;

  databaseMysql.query(sql, slug_id, (error, results, fields) => {
    if (error) {
      console.log(error);
      return res.render('pages/read_post', {
        error: true,
        messages: 'Postingan tidak ditemukan di Mysql',
      });
    } else {
      console.log(results[0]);
      return res.render('pages/read_post', {
        error: false,
        result: results[0],
      });
    }
  });
});

Membuat template EJS Read di Post

<!DOCTYPE html>
<html lang="en">
  <head>
    <%- include('../partials/head'); %>
  </head>
  <body class="container">
    <header><%- include('../partials/header'); %></header>

    <main role="main" class="flex-shrink-0">
      <%if (typeof(error) !== "undefined" && error === true) { %>
      <div class="alert alert-danger" role="alert"><%= messages %></div>
      <% } else { %>

      <div class="container">
        <h1 class="mt-5"><%= result.title %></h1>
        <p class="lead"><%= result.content %></p>
      </div>

      <% } %>
    </main>

    <footer><%- include('../partials/footer'); %></footer>
  </body>
</html>

Penjelasan

Bagian pengkodean proses Update Post di NodeJS

// Update post page
app
  .get('/update', function (req, res) {
    let sql = `SELECT id, title, slug_id FROM post`;

    databaseMysql.query(sql, (error, results, fields) => {
      if (error) {
        console.log(error);
        return res.render('pages/update_post', {
          error: true,
          messages: 'Ada masalah koneksi Nodejs ke Mysql',
        });
      } else {
        console.log(results);

        return res.render('pages/update_post', {
          error: false,
          posts: results,
        });
      }
    });
  })
  .get('/update/:slug_id', function (req, res) {
    let sql = `SELECT * FROM post WHERE slug_id = ? LIMIT 1`;
    let slug_id = req.params.slug_id;

    databaseMysql.query(sql, slug_id, (error, results, fields) => {
      if (error) {
        console.log(error);
        return res.render('pages/update_post', {
          error: true,
          messages: 'Postingan tidak ditemukan di Mysql',
        });
      } else {
        return res.render('pages/edit_post', {
          error: false,
          result: results[0],
        });
      }
    });
  })
  .post('/update/:slug_id', function (req, res) {
    let { title, content } = req.body;
    let sql = `SELECT * FROM post WHERE slug_id = ? LIMIT 1`;
    let slug_id = req.params.slug_id;

    databaseMysql.query(sql, slug_id, (error, results, fields) => {
      if (error) {
        console.log(error);
        return res.render('pages/update_post', {
          error: true,
          messages: 'Postingan tidak ditemukan di Mysql',
        });
      }
    });

    sql = 'UPDATE post SET title = ?, content = ? WHERE slug_id = ?';
    databaseMysql.query(
      sql,
      [title, content, slug_id],
      (error, results, fields) => {
        if (error) {
          console.log(error);
          return res.render('pages/update_post', {
            error: true,
            messages: 'Ada masalah koneksi Nodejs ke Mysql',
          });
        }
      }
    );

    sql = `SELECT * FROM post WHERE slug_id = ? LIMIT 1`;
    databaseMysql.query(sql, slug_id, (error, results, fields) => {
      if (error) {
        console.log(error);
        return res.render('pages/update_post', {
          error: true,
          messages: 'Ada masalah koneksi Nodejs ke Mysql',
        });
      } else {
        return res.render('pages/edit_post', {
          error: false,
          messages: 'Data post berhasil diupdate di Mysql',
          result: results[0],
        });
      }
    });
  });

Penjelasan

  • return res.render('pages/update_post', { error: true, messages: 'Ada masalah koneksi Nodejs ke Mysql', }); : data ini akan dikirimkan ke view EJS
  • result: results[0] : mengambil data table post pertama di MySQL karena hasil dari eksekusi hanya berisi satu saja.

Bagian pengkodean EJS view Update Post di NodeJS

<!DOCTYPE html>
<html lang="en">
  <head>
    <%- include('../partials/head'); %>
  </head>
  <body class="container">
    <header><%- include('../partials/header'); %></header>

    <main role="main" class="flex-shrink-0">
      <%if (typeof(error) !== "undefined" && error === true) { %>
      <div class="alert alert-danger" role="alert"><%= messages %></div>
      <% } else { %>

      <div class="container">
        <h1 class="mt-5"><%= result.title %></h1>
        <p class="lead"><%= result.content %></p>
      </div>

      <% } %>
    </main>

    <footer><%- include('../partials/footer'); %></footer>
  </body>
</html>

Penjelasan:

  • <%if (typeof(error) !== "undefined" && error === true) { %> : mengecek type data berinali tidak ber tipe undefined dan berisi value boolean true

function proses Delete Post di Nodejs

// Delete page page
app.get('/delete/:slug_id', function (req, res) {
  let sql = 'DELETE FROM post WHERE slug_id = ?';
  let slug_id = req.params.slug_id;

  databaseMysql.query(sql, slug_id, (error, results, fields) => {
    if (error) {
      console.log(error);
      return res.render('pages/delete_post', {
        error: true,
        messages: 'Ada masalah koneksi Nodejs ke Mysql',
      });
    } else {
      return res.render('pages/delete_post', {
        error: false,
        messages: 'Data post berhasil didelete di Mysql',
      });
    }
  });
});

penjelasan:

let sql = 'DELETE FROM post WHERE slug_id = ?'; : merupakan query mysql untuk memerintahkan delete data di tabel post dengan pengkondisian slug_id

<!DOCTYPE html>
<html lang="en">
  <head>
    <%- include('../partials/head'); %>
  </head>
  <body class="container">
    <header><%- include('../partials/header'); %></header>

    <main role="main" class="flex-shrink-0">
      <%if (typeof(messages) !== "undefined" && typeof(messages) !== "undefined"
      && error === false) { %>
      <div class="alert alert-success" role="alert"><%= messages %></div>
      <% } %>
    </main>

    <footer><%- include('../partials/footer'); %></footer>
  </body>
</html>

Penjelasan:

  • <%if (typeof(messages) !== "undefined" && typeof(messages) !== "undefined" && error === false) { %> : mengecek type data tidak berinali type undefined dan berisi value boolean false sehingga mencetak data messages

Screenshot Simple CRUD :

Tampilan Home

page Home EJS Web App CRUD simple

Tampilan Create Post

page EJS create data post

Tampilan Update Post

page EJS Update data post

source code ini bisa teman-teman lihat dan unduh atau clone di repository GitHub : https://github.com/SigitNurhanafi/simple_crud_expressjs