- Published on
CRUD REST API Node.js Menggunakan Express.js dan MongoDB
Terkait tulisan saya yang kemarin Deploy Otomatis Node.js Dengan Menggunakan Github Actions di tulisan kali ini saya ingin membuat tutorial CRUD API aplikasi daftar yang ingin dilakukan (to-do list app) menggunakan Node.js dengan Web Framework Express.js dan MongoDB sebagai database.
Persiapan
Sebelumnya, daftar tool yang saya gunakan saat membuat tutorial ini yaitu:
node.js v15.0.1
npm v7.0.3
yarn v1.22.5
mongodb v3.6.3
Okee... langsung saja kita buat direktori baru dan inisiasi package.json untuk project nya
mkdir nodejs-todo-app
cd nodejs-todo-app
yarn init -y
Kemudian install paket yang dibutuhkan
yarn add express dotenv cors mongoose
Sebelum masuk ke langkah-langkahnya kita buat file .env dulu pada root direktori
PORT=1337
MONGODB=mongodb://localhost:27017/nama_database
Kita buat mundur saja yaa langkah demi langkah nya... yaitu dimulai dari membuat model, handler / controller (Proses untuk Create, Read, Update, Delete) kemudian route dan main file nya yaitu index.js.
Buat Model
Yang pertama kita buat model untuk project nya, disini kita menggunakan library mongoose untuk komunikasi ke MongoDB nya
Kita buat folder models pada direktori root
mkdir models
Kemudian buat file models/todo.js
// models/todo.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const model = new Schema({
// field ini berisi tentang kegiatan yang ingin dilakukan
text: {
type: String,
required: true
},
// field ini berisi apakah kegiatan sudah dilakukan belum
checked: {
type: Boolean,
required: true
}
}, {
// opsi ini opsional sih
// berfungsi agar membuat tanggal dibuat dan tanggal diupdate otomatis setiap pembuatan atau pembaruan dokumen
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
});
module.exports = mongoose.model('todos', model);
Buat Handler
Yang kedua kita buat handler untuk memproses create, read, update dan delete data nya
Kita buat folder handlers pada direktori root
mkdir handlers
Kemudian buat file handlers/todo.js, dan import model yang sudah kita buat tadi
// handlers/todo.js
const modelTodo = require('../models/todo');
// Proses Create
// Proses Read All
// Proses Read By ID
// Proses Update
// Proses Delete
Create
Tambahkan fungsi create dengan menambahkan kode berikut
// Proses Create
exports.create = async (req, res) => {
// ambil data dari nama field text dan checked
const { text, checked } = req.body;
try {
// kirim respon error jika field text atau checked tidak ditemukan
if (text === undefined || checked === undefined) {
return res.status(422).json({ message: 'Parameter yang dimasukkan tidak lengkap.' });
}
// buat dokumen baru
const todo = await modelTodo.create({ text, checked });
// kirim respon dengan payload nya dokumen yang baru dibuat
return res.status(201).json(todo);
}
catch (error) {
console.log(error);
return res.status(500).json(error);
}
}
Read All
Tambahkan fungsi read all atau mengambil semua data yang ada dengan menambahkan kode berikut
// Proses Read All
exports.getAll = async (req, res) => {
try {
// ambil semua data
const todos = await modelTodo.find();
// disini jika kita tidak menambahkan .status(xxx) maka respon kodenya 200
return res.json(todos);
}
catch (error) {
console.log(error);
return res.status(500).json(error);
}
}
Read By ID
Tambahkan fungsi read by id atau mengambil data berdasarkan id dengan menambahkan kode berikut
// Proses Read By ID
exports.getOne = async (req, res) => {
// kita ambil parameter id dari url
const { id } = req.params;
try {
// jika parameter id tidak ada, kirim respon error
if (id === undefined) {
return res.status(422).json({ message: 'Parameter id tidak ditemukan.' });
}
// ambil data berdasar id
const todo = await modelTodo.findOne({ _id: id });
// jika data tidak ditemukan kirim respon status 404
if ( ! todo) {
return res.status(404).json({ message: 'Data tidak ditemukan.' });
}
return res.json(todo);
}
catch (error) {
console.log(error);
return res.status(500).json(error);
}
}
Update
Proses update ini hampir sama dengan proses create, bedanya kita perlu mengambil parameter id untuk mencari dokumen yang ingin diubah
// Proses Update
exports.update = async (req, res) => {
try {
// ambil parameter id
const { id } = req.params;
// ambil data dari nama field text dan checked
const { text, checked } = req.body;
// kirim respon error jika field text atau checked tidak ditemukan
if (text === undefined || checked === undefined) {
return res.status(422).json({ message: 'Parameter yang dimasukkan tidak lengkap.' });
}
// update data
const todo = await modelTodo.updateOne(
{
_id: id
},
{
text,
checked
});
// jika tidak ada perubahan pada suatu dokumen, berarti dokumen tidak ditemukan
// kirim respon status 404
if (todo.nModified === 0) {
return res.status(404).json({ message: 'Data tidak ditemukan.' });
}
return res.json({ message: 'Sukses.' });
}
catch (error) {
console.log(error);
return res.status(500).json(error);
}
}
Delete
Yang terakhir adalah proses delete
// Proses Delete
exports.delete = async (req, res) => {
// ambil parameter id
const { id } = req.params;
try {
// hapus data
const todo = await modelTodo.deleteOne({ _id: id });
// jika tidak ada dokumen yang berhasil dihapus, berarti data tidak ditemukan
// kirim respon status 404
if (todo.deletedCount === 0) {
return res.status(404).json({ message: 'Data tidak ditemukan.' })
}
return res.json({ message: 'Sukses.' });
}
catch (error) {
console.log(error);
return res.status(500).json(error);
}
}
Buat Route
Langkah selanjutnya kita buat routing nya, dengan membuat direktori routes dan membuat file index.js dan todo.js
mkdir routes
Buat file routes/todo.js
// routes/todo.js
const express = require('express');
const router = express.Router();
// import handler yang sudah kita buat tadi
const todoHandler = require('../handlers/todo');
// route ini mengarah ke http://localhost:1337/todos
router.route('/')
// route untuk proses Read All
.get(todoHandler.getAll)
// route untuk proses Create
.post(todoHandler.create);
// route yang ini mengarah ke http://localhost:1337/todos/:id
router.route('/:id')
// route untuk proses Read By ID
.get(todoHandler.getOne)
// route untuk proses Update
.put(todoHandler.update)
// route untuk proses Delete
.delete(todoHandler.delete);
module.exports = router;
Kemudian buat file routes/index.js
// routes/index.js
const express = require('express');
const router = express.Router();
// import route todo.js yang sudah kita buat tadi
const todoRoutes = require('./todo');
// route ini mengarah ke http://localhost:1337/
router.get('/', async (req, res) => {
res.json({ message: 'Halo!' });
});
// route yang ini mengarah ke http://localhost:1337/todos
router.use('/todos', todoRoutes);
module.exports = router;
Buat Main File
Yang terakhir kita buat main file untuk menjalankan server kita. buat file index.js pada root direktori project kita
// ./index.js
// untuk meload file .env
require('dotenv').config()
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const port = process.env.PORT || 1337;
const dbUrl = process.env.MONGODB;
// Import file route index.js yang sudah kita buat tadi
// jika ingin mengimport file index.js didalam folder, kita hanya perlu memanggil nama folder nya saja
const routes = require('./routes');
const app = express();
// buka koneksi ke mongodb
const mongooseOptions = {
useNewUrlParser: true,
useUnifiedTopology: true
};
mongoose.connect(dbUrl, mongooseOptions);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
// mongodb berhasil terkoneksi
console.log('MongoDB berhasil tersambung!');
});
// selesai membuka koneksi
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(routes);
app.listen(port, () => {
console.log('The magic happen on port :' + port);
});
Jalankan Server
Terakhir kita coba jalankan servernya bisa menggunakan node, pm2 atau nodemon
$ node index.js
The magic happen on port :1337
MongoDB berhasil tersambung!
Jika sudah muncul pesan tersebut, berarti sudah berhasil jalan servernya.
Testing
Nahh kita bisa test API nya dengan menggunakan postman, curl atau httpie.
Kebetulan saya sudah buatkan collection untuk postman supaya bisa memudahkan testing kalian, collection nya bisa diunduh disini.
Untuk repo project ini bisa dicek di github saya.
dahh sementara gitu aja, see yaa~