Mengembangkan API Untuk Aplikasi Mobile dan Web Menggunakan Nodejs (Bagian Kedua)
Haloo.
Pada bagian pertama kita telah menyelesaikan konfigurasi project api menggunakan nodejs. Pada bagian ini akan sedikit mendemonstrasikan cara membuat endpoint baru. Mungkin teman-teman perlu berkunjung ke halaman resmi sequelize untuk membaca dokumentasi
Jadi apa yang akan kita buat sebagai contoh?
Untuk membuat endpoint baru, keperluannya tergantung apa yang teman-teman butuhkan. Saya akan mulai dari membuat berkas migrasi, model, seeder, controller dan route. Mirip framework lain hehe. Contoh yang akan kita buat adalah Todo API.
Migration
Buat file migrasi untuk tabel Todo.
sequelize migration:generate --name create-todo-table
Defaultnya akan seperti berikut saat file dihasilkan:
atau jika sekalian dengan modelnya, gunakan perintah berikut:
sequelize model:generate --name Todo --attributes name:string,description:text
Tabel todo ini akan memiliki kolom nama task, deskripsi. Secara otomatis, sequelize juga membuatkan field id, createdAt, updatedAt dan createdBy. Silahkan baca lebih lanjut pada halaman dokumentasi. Disini saya mengubah nama field dari camelCase menjadi snake_case sebelum menjalankan migrasi.
Pembuatan file migrasi selesai, kita jalankan sekarang untuk membuat tabel baru. Masih dengan perintah yang sama.
sequelize db:migrate
Oh ya, jika ada warning deprecation berikut, silahkan hilangkan baris “operatorsAliases”: false
pada main.js
.
(node:56371) [SEQUELIZE0004] DeprecationWarning: A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.
Seeder
Generate seeder dengan perintah berikut:
sequelize seed:generate --name todo
Untuk menjalankan seeder, gunakan perintah berikut:
sequelize db:seed:all
Model
Pada bagian migration, sudah disampaikan perintah untuk membuat model beserta dengan migrasinya. Untuk model todo ini, saya menggunakan model seperti berikut (jika sudah dilakukan pada migrasi, maka tidak perlu diulang):
sequelize model:generate --name Todo --attributes name:string,description:text
Kemudian dari berkas yang dibuat tersebut, saya ubah sehingga menjadi seperti berikut ini.
Controller
Untuk controller saya akan buat untuk create dan view saja. Controller akan dibuat di dalam folder controllers.
Route
Saatnya mendefinisikan route/endpoint dari controller yang telah dibuat. File route akan dibuat di dalam folder routes.
Penjelasan Code
Migration, seeder, model di handle oleh library sequelize. Sedangkan controller dan router di handle oleh express dan nodejs. Sementara perbedaan dari yang “biasa” digunakan namun terlihat berbeda dihandle oleh pembuat repo untuk memudahkan proses pengembangan.
Migration
queryInterface.createTable('Todo', fieldTable )
Pada kode tersebut kita akan membuat tabel baru dengan nama Todo
untuk setiap proses up
. fieldTable berupa json yang berisi key-value pair untuk nama field dan tipe datanya. Pada bagian value saya menggunakan json untuk menambahkan constraint atau properti lain untuk field tersebut. Bisa dibaca kembali pada halaman dokumentasi.
'username': {
allowNull: false,
type: Sequelize.STRING(255),
unique: true
},
Jangan lupa tambahkan aksi kebalikan dari fungsi yang akan di up
pada bagian down
. Kembali, silahkan baca dokumentasi untuk informasi lebih lengkap.
queryInterface.dropTable('Todo');
Seeder
Seeder digunakan untuk mengisi row pada tabel sehingga tidak perlu manual input satu persatu. Sama seperti migration, terdapat fungsi untuk up
dan down
pada seeder. Fungsi seeder disini digunakan untuk insert multiple record.
queryInterface.bulkInsert('tableName', [listJsonObject]);
Kebalikannya, pada fungsi down
yang dilakukan adalah menghapus semua record yang telah di-insert sebelumnya.
queryInterface.bulkDelete('tableName', null, {});
Model
Pada model hanya mendefinisikan tipe data dari setiap field yang akan diambil. Mungkin yang perlu diperhatikan adalah penggunaan hooks. Hooks pada kode digunakan untuk memberikan nilai baru pada tabel sebelum proses create ataupun update record dilakukan.
hooks: {
beforeCreate: (record, options) => {
record.created_at = Math.floor(Date.now() / 1000);
record.updated_at = Math.floor(Date.now() / 1000);
},
beforeUpdate: (record, options) =>
record.updated_at = Math.floor(Date.now() / 1000);
}
}
Controller
Berkas-berkas controller dibuat untuk memudahkan pembacaan kode dan navigasi dalam pembuatan endpoint, yah clean code lah, strukturnya rapi hehe. Setiap fungsi pada controller perlu diekspor agar dapat digunakan pada route express.
Sedikit kita bahas apa yang ada di dalam controller todo. Pertama dari bearer jika benar, kita ingin mendapatkan informasi user yang login. Cara mendapatkannya pada project ini dengan kode berikut:
let created_by = identity.getId();
lalu untuk mendapatkan json pada body ataupun param pada url, gunakan kode berikut:
// get body
let name = req.body.name;// get param
let idCat = req.params.id;
Untuk query mendapatkan semua record, gunakan findAll().
findAll()
Jika ingin memberikan kondisi pada query model, tambahkan where
pada findAll
.
findAll({
where: {
created_by: created_by
}
})
Untuk mencari sebuat record atau memeriksa apakah record tersebut tersedia, gunakan findOrCreate
.findOrCreate({
where: {
name: name,
description: description,
created_by: created_by
}
})
dan terakhir untuk memberikan response dari api, dari project ini sudah disediakan template yang ada dalam berkas components/response.js
. Berikut beberapa yang telah digunakan.
response.responseSuccess(data, res);
response.responseNotFound("", "incorrect task name", res);
response.responseNotValidate("", err.message, res);
Router
// Normal route
var express = require('express')
var app = express()
// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
res.send('hello world')
})
Penggunaan router sama seperti biasa. Namun pada route ini menggunakan middleware terlebih dahulu.
"use strict";const BearerAuthorization = require("../components/authorizationBearer");
const Express = require("express");
const Controller = require("./../controllers/TodoController");
const BASE_URL = "/v1/todo";module.exports = Express.Router({
mergeParams: true
})
.get(`${BASE_URL}/get/`, BearerAuthorization, Controller.getAll)
Sebelum code controller dieksekusi, middleware akan terlebih dahulu dijalankan, dalam hal ini adalah pengecekan bearer token ke database. Lebih lengkap tentang middleware bisa dibaca pada dokumentasi official.
Hmm, apa lagi ya? Mungkin kita coba menguji endpoint yang dibuat dulu ya. Mari kita buka kembali postman atau insomnia.
Create
Get all
BONUS: Get by id
Okee, demikian artikel ini. Semoga bermanfaat dan bisa menambah ilmu. Lain kali akan saya terjemahkan artikel ini ke dalam bahas inggris hehe.
Sampai jumpa di artikel lain.