Search by

    Terakhir diperbaharui: Oct 24, 2020

    Refactoring

    Refactoring yang akan kita lakukan meliputi:

    • Menyederhanakan code yang digunakan untuk membuat koneksi ke MongoDB
    • Memisahkan route & handler

    Sharing Koneksi Database

    Jika kita perhatikan pada code sebelumnya, proses koneksi ke MongoDB dilakukan di setiap handler. Hal ini membuat terjadi banyak duplicated code.

    MongoDB driver sendiri sudah dilengkapi dengan mekanisme connection pooling, sehingga koneksi ke database hanya perlu dilakukan sekali.

    Kita akan menggunakan object app.locals dari Express.js untuk menyimpan object collection.

    Object app.locals memiliki properties yang bersifat local untuk aplikasi. Kita bisa anggap object ini seperti global object yang valuenya bisa diakses dimanapun selama masih di dalam aplikasi Express.js.

    Step by Step

    1. Tambahkan code berikut sebelum route
    1// Connect to Database
    2
    3MongoClient.connect(url, (err, client) => {
    4 const db = client.db(dbName);
    5 const notesCollection = db.collection('notes');
    6
    7 app.locals.notesCollection = notesCollection;
    8});
    1. Update semua routes
    1const express = require('express');
    2const { MongoClient, ObjectId } = require('mongodb');
    3const bodyParser = require('body-parser');
    4
    5const app = express();
    6const port = 3001;
    7
    8// Connection URL
    9const url = 'mongodb://localhost:27017';
    10// Database Name
    11const dbName = 'dinotesDB';
    12
    13app.use(bodyParser.urlencoded({ extended: true }));
    14
    15// Connect to Database
    16
    17MongoClient.connect(url, (err, client) => {
    18 const db = client.db(dbName);
    19 const notesCollection = db.collection('notes');
    20
    21 app.locals.notesCollection = notesCollection;
    22});
    23
    24// Routes
    25
    26app.post('/note', (req, res) => {
    27 const { notesCollection } = req.app.locals;
    28 // Insert data to collection
    29 notesCollection.insertOne(req.body).then((result) => {
    30 console.log(result);
    31 });
    32
    33 res.status(200).json('Data successfully saved');
    34});
    35
    36app.get('/notes', (req, res) => {
    37 const { notesCollection } = req.app.locals;
    38
    39 // find All Notes
    40 notesCollection
    41 .find()
    42 .toArray()
    43 .then((result) => {
    44 res.status(200).json(result);
    45 });
    46});
    47
    48app.get('/note/:id', (req, res) => {
    49 const { notesCollection } = req.app.locals;
    50
    51 // find Notes based on id
    52 notesCollection.findOne({ _id: ObjectId(req.params.id) }).then((result) => {
    53 res.status(200).json(result);
    54 });
    55});
    56
    57app.put('/note/:id', (req, res) => {
    58 const { notesCollection } = req.app.locals;
    59 // update data collection
    60 notesCollection
    61 .updateOne({ _id: ObjectId(req.params.id) }, { $set: { title: req.body.title, note: req.body.note } })
    62 .then((result) => {
    63 console.log(result);
    64 });
    65
    66 res.status(200).json('Data successfully updated');
    67});
    68
    69app.delete('/note/:id', (req, res) => {
    70 const { notesCollection } = req.app.locals;
    71
    72 // delete data collection
    73 notesCollection.deleteOne({ _id: ObjectId(req.params.id) }).then((result) => {
    74 console.log(result);
    75 });
    76
    77 res.status(200).json('Data successfully deleted');
    78});
    79
    80app.listen(port, () => {
    81 console.log(`Server listening at http://localhost:${port}`);
    82});

    Memutus Koneksi ke MongoDB

    Kita tidak perlu mengatur (menyambungkan/memutus) koneksi ke MongoDB secara manual, hal ini sudah ditangani oleh MongoDB driver.

    Jadi memutus koneksi ke MongoDB bisa dibilang tidak perlu dilakukan. Tapi jika kamu tetap ingin melakukannya kamu bisa update code server.js menjadi:

    1...
    2
    3// jadikan variable db menjadi global variable
    4
    5let db;
    6
    7MongoClient.connect(url, (err, client) => {
    8 db = client.db(dbName);
    9 const notesCollection = db.collection('notes');
    10
    11 app.locals.notesCollection = notesCollection;
    12});
    13
    14...
    15
    16// tambahkan code berikut ini pada baris akhir server.js
    17
    18process.on('SIGINT', () => {
    19 db.close();
    20 process.exit();
    21});

    Memisahkan Route & Handler

    Untuk memudahkan kita mengelola route, kita jadikan route yang ada menjadi sebuah module dengan cara memindahkannya dari api/server.js ke file terpisah.

    Step by step

    1. Buat sebuah file baru bernama route.js di dalam folder api

    Struktur folder:

    1dinotes-app
    2 |--api
    3 |--routes.js
    4 |--server.js
    5 |--node_modules
    6 |--public
    7 |--src

    Kita akan tambahkan express.Router, route handler yang digunakan untuk mengatur route di sebuah aplikasi Express.js.

    1. Pindahkan semua route ke dari api/server.js ke api/routes.js kemudian ganti app dengan router:
    1const express = require('express');
    2const { ObjectId } = require('mongodb');
    3
    4const router = express.Router();
    5
    6router.post('/note', (req, res) => {
    7 const { notesCollection } = req.app.locals;
    8 // Insert data to collection
    9 notesCollection.insertOne(req.body).then((result) => {
    10 console.log(result);
    11 });
    12
    13 res.status(200).json('Data successfully saved');
    14});
    15
    16router.get('/notes', (req, res) => {
    17 const { notesCollection } = req.app.locals;
    18
    19 // find All Notes
    20 notesCollection
    21 .find()
    22 .toArray()
    23 .then((result) => {
    24 res.status(200).json(result);
    25 });
    26});
    27
    28router.get('/note/:id', (req, res) => {
    29 const { notesCollection } = req.app.locals;
    30
    31 // find Notes based on id
    32 notesCollection.findOne({ _id: ObjectId(req.params.id) }).then((result) => {
    33 res.status(200).json(result);
    34 });
    35});
    36
    37router.put('/note/:id', (req, res) => {
    38 const { notesCollection } = req.app.locals;
    39 // update data collection
    40 notesCollection
    41 .updateOne({ _id: ObjectId(req.params.id) }, { $set: { title: req.body.title, note: req.body.note } })
    42 .then((result) => {
    43 console.log(result);
    44 });
    45
    46 res.status(200).json('Data successfully updated');
    47});
    48
    49router.delete('/note/:id', (req, res) => {
    50 const { notesCollection } = req.app.locals;
    51
    52 // delete data collection
    53 notesCollection.deleteOne({ _id: ObjectId(req.params.id) }).then((result) => {
    54 console.log(result);
    55 });
    56
    57 res.status(200).json('Data successfully deleted');
    58});
    59
    60module.exports = router;
    1. Import module routes ke file server.js
    1const express = require('express');
    2const { MongoClient } = require('mongodb');
    3const bodyParser = require('body-parser');
    4
    5const routes = require('./routes');
    6
    7const app = express();
    8const port = 3001;
    9
    10// Connection URL
    11const url = 'mongodb://localhost:27017';
    12// Database Name
    13const dbName = 'dinotesDB';
    14
    15app.use(bodyParser.urlencoded({ extended: true }));
    16
    17// Connect to Database
    18
    19MongoClient.connect(url, (err, client) => {
    20 const db = client.db(dbName);
    21 const notesCollection = db.collection('notes');
    22
    23 app.locals.notesCollection = notesCollection;
    24});
    25
    26// Routes
    27
    28app.use('/', routes);
    29
    30app.listen(port, () => {
    31 console.log(`Server listening at http://localhost:${port}`);
    32});

    Sekarang kita pindahkan semua route handler ke file api/handler.js.

    1. Buat sebuah file bernama handler.js di dalam folder api.

    2. Kemudian pindahkan semua route handler ke file api/handler.js

    1/* eslint-disable no-console */
    2const { ObjectId } = require('mongodb');
    3
    4exports.addNote = (req, res) => {
    5 const { notesCollection } = req.app.locals;
    6 // Insert data to collection
    7 notesCollection.insertOne(req.body).then((result) => {
    8 console.log(result);
    9 });
    10
    11 res.status(200).json('Data successfully saved');
    12};
    13
    14exports.getAllNotes = (req, res) => {
    15 const { notesCollection } = req.app.locals;
    16
    17 // find All Notes
    18 notesCollection
    19 .find()
    20 .toArray()
    21 .then((result) => {
    22 res.status(200).json(result);
    23 });
    24};
    25
    26exports.getNote = (req, res) => {
    27 const { notesCollection } = req.app.locals;
    28
    29 // find Notes based on id
    30 notesCollection.findOne({ _id: ObjectId(req.params.id) }).then((result) => {
    31 res.status(200).json(result);
    32 });
    33};
    34
    35exports.updateNote = (req, res) => {
    36 const { notesCollection } = req.app.locals;
    37 // update data collection
    38 notesCollection
    39 .updateOne({ _id: ObjectId(req.params.id) }, { $set: { title: req.body.title, note: req.body.note } })
    40 .then((result) => {
    41 console.log(result);
    42 });
    43
    44 res.status(200).json('Data successfully updated');
    45};
    46
    47exports.deleteNote = (req, res) => {
    48 const { notesCollection } = req.app.locals;
    49
    50 // delete data collection
    51 notesCollection.deleteOne({ _id: ObjectId(req.params.id) }).then((result) => {
    52 console.log(result);
    53 });
    54
    55 res.status(200).json('Data successfully deleted');
    56};
    1. Update api/routes.js:
    1const express = require('express');
    2
    3const router = express.Router();
    4
    5const { addNote, getAllNotes, getNote, updateNote, deleteNote } = require('./handler');
    6
    7router.post('/note', addNote);
    8router.get('/notes', getAllNotes);
    9router.get('/note/:id', getNote);
    10router.put('/note/:id', updateNote);
    11router.delete('/note/:id', deleteNote);
    12
    13module.exports = router;

    Sekarang kita memiliki tiga file yang memiliki tugasnya masing-masing:

    • handler.js, mengatur semua route handler
    • routes.js, mengatur semua route
    • server.js, file utama dari server yang bertugas untuk load middleware, module, mengatur koneksi ke database dan menjalankan http server