MVC : Cara Membuat Restfull API pada konsep MVC di MERN stack


Konsep MVC sangatlah bagus untuk proses pengembangan jangka panjang dari sebuah aplikasi. konsep ini banyak digunakan bahkan di perusahaan-perusahaan besar, karena konsep dan struktur dari pengembangan sangat mudah dibaca dan di scale up. Maka pada artikel kali ini kita akan lanjut ke proses penginstallan serta proses apa saja yang harus dibuat untuk memulai pengembangan aplikasi NodeJS & ExpressJS dengan konsep MVC atau Model-View-Controller.

# Persyaratan

  • Install Text Editor, MongoDB dan NodeJS di PC kalian
  • Pemahaman tentang Javascript ES5 dan ES6
  • Pemahaman tentang NodeJS dan Express
  • Pemahaman tentang MongoDB dan mongoose

# Proses Instalasi, Setup & Pembuatan / Developing

Sebelum memulai 3 proses dibawah, saya anjurkan untuk memahami dan mempelajari semua yang ada pada persyaratan diatas, karena semua point di persyaratan diatas adalah dasar sekaligus pondasi awal untuk bisa memahami proses-proses pada artikel ini. Anda bisa melakukan pembelajaran lewat dokumentasinya langsung atau dengan menonton video di youtube mengenai tutorial pemahaman dasar dari persyaratan-persyaratan diatas.

## Installasi

Pertama anda harus install aplikasi NodeJS pada komputer anda, anda bisa pergi ke link berikut : https://nodejs.org/en, untuk mendownload nodejs sesuai system operasi yang digunakan. lalu yang kedua lakukan installasi aplikasi Visual Studio Code di PC anda. dan yang terakhir jangan lupa untuk Melakukan installasi aplikasi mongoDB. Anda bisa menggunakan MongoDB Atlas atau dengan aplikasi di lokal komputer anda yang bernama mongoDB Compass.

## Setup

Untuk memulai proses pembuatan aplikasi pertama siapkan folder kosong di file exproler di PC mu, kemudian buka folder tersebut dengan aplikasi Text editor anda dengan cara klik kanan lalu buka dengan text editor mu, disini saya menggunakan Visual Studio Code dalam penjelasan kali ini.

Setelah membuat folder dan membukannya dengan VScode, buat struktur folder dan file seperti gambar disamping ini. Terdapat 1 file bernama app.js, dan 3 folder yaitu controllers, models, dan routes. adapun juga folder views untuk membuat struktur MVC yang lengkap, namun karena pembuatan Restfull API tidak memerlukan view, maka saat ini tidak terlalu diperlukan.

Selanjutnya lakukan initiasi dengan npm untuk membuat package.json. Fungsinya adalah sebagai alat yang digunakan untuk mengelola pacakage dan dependencies. Caranya adalah dengan cara membuka terminal di VScode anda dengan cara CTRL + ~ di keyboard anda atau dengan mengklik tab terminal->new terminal pada VScode.

Lalu jalankan pertintah npm init. Lalu anda bisa mengisi seperti version, description hingga license. Secara default anda juga bisa mengkosongkan semua ini dengan menakan tombol ENTER disetiap jawaban. Namun pada contoh dibawah ada beberapa yang disesuaikan seperti Descriprion & Author.

Setelah NPM berhasil diinisiasi, selanjutnya adalah proses install dependencies. Yang harus dilakukan hanyalah dengan jalankan perintah berikut di terminal :

npm install express dotenv cors mongoose

Lalu tambahkan file .env di folder root project, dan isi dengan PORT=8080. lalu edit juga file package.json anda dengan menambahkan “dev”: “node –watch app.js” pada script dan tambahkan “type”: “module”, dibawah main. barikut adalah gambar lebih jelasnya :

dengan begitu proses setup dari aplikasi restfull API sudah selesai, selanjutnya akan ada penjelasan mengenai proses pembuatan / Developing dari kode kita.

## Pembuatan / Developing

### Setup app.js & package.json

Pada proses developing ini kita akan masuk ke dalam proses koding dari aplikasi restfull API. Hal pertama yang dilakukan adalah melakukan edit file app.js. Masukan code berikut pada app.js mu !!

import express from "express";
import dotenv from 'dotenv';
import cors from 'cors';

dotenv.config();
const app = express();
const { PORT } = process.env;

app.use(cors({
    origin: `*`,
    allowedHeaders: "Origin, X-Requested-With, Content-Type, Accept, Authorization",
    methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    optionsSuccessStatus: 200,
}));

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.get(`/`, (req, res) => {
    res.send(`Hello World`);
});

app.listen(PORT, () => {
    console.log(`\n\tListening on http://localhost:${PORT}\n`);
});

Kode ini mendemonstrasikan pembuatan server web sederhana menggunakan Express.js. Dimulai dengan mengimpor modul-modul penting: express untuk membuat server, dotenv untuk mengelola Environtment Variable, dan cors untuk kebijakan Cross-Origin Resource Sharing (CORS). Dengan dotenv.config(), server dapat mengambil konfigurasi dari file .env, yang memungkinkan penyimpanan informasi sensitif seperti nomor port.

Setelah aplikasi Express dibuat dan port ditentukan, middleware CORS diterapkan untuk mengizinkan permintaan dari berbagai sumber karena pada CROS origin: `*`, berarti mengizinkan seluruh sumber apapun untuk mengakses API ini, anda juga bisa menetapkan url tertuntu untuk membuat akses API terbatasi. Ini penting untuk mendukung komunikasi lintas asal (cross-origin) dalam pengembangan aplikasi web. Middleware tambahan digunakan untuk menguraikan payload JSON dan URL-encoded dari permintaan yang masuk, memastikan data dari klien dapat diproses dengan benar.

Server ini memiliki satu route GET pada root URL (/) yang mengirimkan respon “Hello World” sebagai cara untuk menguji fungsionalitas dasar server. Akhirnya, server dijalankan pada port yang ditentukan, dan pesan konfirmasi ditampilkan di konsol untuk memastikan server berjalan dengan benar. Secara keseluruhan, kode ini menunjukkan langkah-langkah dasar untuk membangun dan mengatur server Express dengan konfigurasi CORS dan middleware yang diperlukan.

Selanjutnya untuk melakukan test anda bisa mengetik perintah ini pada terminal, dan akan muncul keterangan server berjalan seperti gambar dibawah, dan ketika link localhost yang diberikan dijalankan di :

npm run dev

### Routing

Selanjutnya buat file bernama index.js dan folder bernama apis di folder/directory routes. Ini berfungsi untuk membuat routing dari aplikasi express yang dijalankan di app.js. Lalu buat file Home.js didalam directory apis.

ini adalah proses pembagian routing dari setiap API agar lebih rapih. Pembagian ini biasanya dipisahkan dengan folder dan file seperti ini dan biasanya dipisahkan jika halaman dari API yang digunakan berbeda.

Misalkan pada gambar disamping semua routing API yang ada di Home.js adalah route dari semua API yang digunakan di halaman Home di Front End.

jadi jika ada halaman lain misalkan halaman About di front end maka pada bagian backend API diharuskan untuk memisahkan bagiannya, dengan cara membuat file baru misal About.js

Selanjutkan isi index.js dan Home.js dengan code berikut, seperti gambar diatas :

# index.js
import express from "express";
import Home from "./apis/Home.js";
const app = express();

app.use("/v1", Home);

export default app;
# Home.js
import { Router } from "express";
const route = Router();

import HomeController from "../../controllers/v1/HomeController.js";

// ROUTING
route.get("/", HomeController.index);

export default route;

### Controllers

Sebelum membuat controller lakukan update terlebih dahulu terhadap file app.js di root directory / directory terluar project. hal yang ditambahkan adalah import routers yang mengarah ke routing dan menggunakan routers tersebut. berikut adalah update dari kode di app.js :

import express from "express";
import dotenv from 'dotenv';
import cors from 'cors';

import routers from './routes/index.js';

dotenv.config();
const app = express();
const { PORT } = process.env;

app.use(cors({
    origin: `*`,
    allowedHeaders: "Origin, X-Requested-With, Content-Type, Accept, Authorization",
    methods: "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    optionsSuccessStatus: 200,
}));

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use(`/`, routers);

app.listen(PORT, () => {
    console.log(`\n\tListening on http://localhost:${PORT}\n`);
});

Selanjutnya adalah proses mehubungkan route ke controller. Yang harus dilakukan adalah membuat directory v1 di directory controllers. Lalu buat file bernama HomeController.js. Ini adalah Controller dari halaman Home. Pembuatan file controller dibuat seperti pada routing, yaitu berdasarkan halaman yang digunakan di Front End.

Berikut kode yang ada di HomeController.js :

const HomeController = {

    async index(req, res, next) {
        res.status(200).json({
            code: 200,
            status: "success",
            halaman: "HomeController"
        });
    },

}

export default HomeController

Pada controller terdapat https status code yaitu 200, status dan nama halaman atau tempat API. ini akan memudahkan proses debuging nantinya, jika ada error kita akan tahu error tersebut dimana, karena 3 object ini kedepannya akan wajib ditambahkan setiap kali membuat endpoint.

Selamat !!!, anda telah berhasil membuat simple rest API dengan menggunakan express. Setelah selesai anda bisa melakukan testing dengan menjalankan npm run dev lalu buka http://localhost:8080/v1 di browser, dan jika berhasil maka tampilan akan seperti gambar dibawah.

### Membuat Models & Koneksi ke Database MongoDB

Sebelum membuat models di project kita, buka aplikasi mongoDB anda disini saya menggunakan mongoDB Compass. Buat collection baru di mongoDB dengan nama belajar_mvc dan dokumen bernama mahasiswa dan tambahkan data kedalamnya. berikut adalah data json sederhana yang harus di insert :

/** 
* Paste one or more documents here
*/
{
  "_id": {
    "$oid": "66594f8372ec392e3952ac40"
  },
  "nama": "Raie Aswajjillah",
  "nim": 1234567890,
  "jurusan": "Informatika"
}

Anda juga bisa menambahkan bebrapa data lain agar lebih banyak lagi.

Nama Database, Dokumen, serta isi data bisa bebas, namun kedepannya harus disesuaikan di project kita. Setelah melakukan create database/collection, copy connection string database anda dan pastekan kedalam .env project.

Seletelah melakukan setup database, selanjutnya adalah proses koneksi project kita ke database mongodb. Caranya adalah dengan update .env seperti dibawah hasil copy connection string tadi, dan buat directory baru bernama db dan buat file baru didalamnya bernama conn.js yang berarti connection. Fungsinya adalah untuk melakukan koneksi ke database. Berikut kode yang harus dimasukan :

# .env
PORT = 8080

MONGODB_HOST="mongodb://127.0.0.1:27017/"
MONGODB_DB="belajar_mvc"
# conn.js
import mongoose from "mongoose";
import dotenv from 'dotenv';

dotenv.config();
const { MONGODB_HOST, MONGODB_DB } = process.env;

mongoose.connect(MONGODB_HOST + MONGODB_DB)
mongoose.pluralize(null);

export default mongoose;

Selanjutnya adalah proses Membuat Models. Pada setup ini hal yang pertama adalah buat index.js di dalam directory models. Lalu buat juga directory baru di dalam direcotry models yaitu schemas dan buat file baru di dalam nya yaitu MahasiswaSchemas.js.

index.js berufungsi sebagai tempat export seluruh model/schema yang ada didalam directory schemas. setiap kali membuat struktur directory baru di usahakan untuk melakukan re-export semua file tersebut ke dalam satu file bernama index.js. hal ini bisa berguna untuk memudahkan proses import atau penggunaan dari setiap file yang jenisnya sama namun lebih dari satu file. seperti models, routes, seeders, migrations, dan lainnya.

Setelah membuat file dan folder, edit file index.js dan MahasisawSchemas.js seperti pada gambar berikut :

# models/index.js
import mongoose from "../db/conn.js";

// Import Models
import MahasiswaModel from "./schemas/MahasiswaSchemas.js";

// Export Models
export const mongooseModels = {
    MahasiswaModel
};

const db = { ...mongoose, ...mongooseModels };
export default db;
# MahasiswaSchemas.js
import mongoose from "../../db/conn.js";

const MahasiswaSchema = new mongoose.Schema({
  nama: String,
  nim: Number,
  jurusan: String,
});

const MahasiswaModel = mongoose.model("mahasiswa", MahasiswaSchema);

export default MahasiswaModel;

### Melakukan QUERY di controller

pada tahap akhir ini kita akan melakukan query terhadap model yang telah kita buat tadi, karena proses koneksi dan pembuatan model telah selesai, sekarang kita bisa melakukan query sebagai hasil dari Endpoint kita, pada tahap ini kita bisa bebas melakukan jenis query, seperti FIND, CREATE, UPDATE, DELETE, dll. namun pada artikel ini saya akan memperlihatkan cara melakukan FIND atau melakukan GET terhadap data yang ada di database mongoDB.

Pertama yang harus anda lakukan adalah pergi ke controllers/v1/HomeController.js, lalu ubah isi dari controller menjadi :

# HomeController.js
import db from "../../models/index.js"

const HomeController = {

    async index(req, res, next) {
        db.MahasiswaModel.find()
            .then(async data => {
                if (data) {
                    res.status(200).json({
                        code: 200,
                        status: "success",
                        halaman: "HomeController",
                        result: data,
                    });
                } else {
                    res.status(404).json({
                        code: 404,
                        status: "failed",
                        halaman: "HomeController",
                        message: "Data not found"
                    });
                }
            })
            .catch(error => {
                res.status(500).json({
                    code: 500,
                    status: "failed",
                    halaman: "HomeController",
                    message: "Something went wrong",
                    error,
                });
            })
    },

}

export default HomeController

Pada kode diatas kita melakukan query terhadap model MahasiswaModel dengan melakukan find seluruh data di dokumen bernama mahasiswa yang ditentukan di model. Terdapat juga 3 kondisi total yaitu response success dengan http status code 200, response Data not found dengan code 404, serta kode 500 yang menandakan internal server error. Tiga kondisi diatas wajib ditambahkan kesetiap endpoint di semua controller lainnya, setiap kali kita membuat endpoint API baru.

Setelah ini lakukan test dengan menjalan kan npm run dev di terminal VScode anda.

jika tampilan hasil akhir dari response sesuai dengan gambar diatas, SELAMAT !!!, anda telah berhasil membuat simple Restfull API dengan nodeJS, express dan mongoDB serta mongoose.

Setelah ini anda dapat dapat mengembangan project Restfull API ini lebih baik lagi, misalkan dengan menambahkan fungsi seperti seeders, migrations, helpers, middlewares, utils, dan lainnya.

### Tambahan: Middlewares dengan JsonWebToken

Pada artikel ini saya akan mencontohkan penggunaan JsonWebToken, sebuah dependencies yang berfungsi sebagai proses Authentication dan Authorization di dalam project API, biasa nya fungsi ini digunakan untuk proses login atau registrasi, agar data dari database hanya bisa diakses ketika user sudah melakuakan registrasi atau melakukan login.

Hal yang pertama yang harus anda lakukan adalah membuat directory baru bernama middlewares. Lalu buat file baru bernama auth.js di dalamnya. Lalu anda juga harus membuat route dan controller baru karena proses auth ini berjalan di jenis halaman yang berbeda pada Front End. Disini buat file Auth.js di directory routes/apis dan buat file AuthController.js di controllers/v1.

Jangan lupa juga lakukan install dependencies bernama jsonwebtoken dengan cara ketikan npm install jsonwebtoken seperti gambar disamping.

Selanjutnya isi setiap file baru dan update beberapa file dengan kode berikut :

# auth.js
import express from 'express'
import jwt from 'jsonwebtoken'
const route = express.Router();


const validateToken = async (req, res, next) => {
  try {
    const secretKey = process.env.JWT_KEY;
    let token = null;
    if (req.headers.authorization) token = req.headers.authorization.split(" ")[1]; // Mengambil token dari header tab Authorization
    if (!token) {
      return res.status(401).json({
        status: 'Failed',
        halaman: 'Middleware JWT',
        message: 'Token not provided'
      });
    }
    jwt.verify(token, secretKey, (err, decoded) => {
      if (err) {
        return res.status(401).json({
          status: 'Failed',
          halaman: 'Middleware JWT',
          message: 'Invalid token or key',
          error: err.message
        });
      }
      req.userData = decoded; // Menyimpan data terdekripsi ke dalam req.userData, agar bisa digunakan di setiap controller
      next();
    });
  } catch (err) {
    return res.status(500).json({
      status: 'Something went wrong',
      halaman: 'Middleware JWT',
      error: err.message
    });
  }
}

export { validateToken, route }
# routes/index.js
import express from "express";
import Home from "./apis/Home.js";
import Auth from "./apis/Auth.js";

const app = express();

app.use("/v1", Home);
app.use("/v1", Auth);

export default app;
# routes/apis/Auth.js
import { Router } from "express";
const route = Router();

import AuthController from "../../controllers/v1/AuthController.js";

// ROUTING
route.get("/auth", AuthController.index);

export default route;
# routes/api/Home.js
import { Router } from "express";
import { validateToken } from "../../middlewares/auth.js";
const route = Router();

import HomeController from "../../controllers/v1/HomeController.js";

// ROUTING
route.get("/", validateToken, HomeController.index);

export default route;
# controllers/v1/AuthController.js
import jwt from 'jsonwebtoken';
import dotenv from 'dotenv';

dotenv.config();
const { JWT_KEY } = process.env;

const AuthController = {

    async index(req, res, next) {
        try {
            const userData = {
                name: "Raie Aswajjillah",
                nim: 1234567890
            };
            
            const token = jwt.sign(
                { 
                    username: userData.name, 
                    nim: userData.nim 
                },
                JWT_KEY, { expiresIn: "1h" } // 1 hour expiration
            );

            if (token) {
                return res.status(200).json({
                    code: 200,
                    status: "success",
                    halaman: "AuthController",
                    token,
                });
            } else throw new Error('Token generation failed');

        } catch (error) {
            console.error('Error generating token:', error);
            return res.status(500).json({
                code: 500,
                status: "failed",
                halaman: "HomeController",
                message: "Something went wrong",
                error,
            });
        }
    },

}

export default AuthController

Kode AuthController.js diatas bisa dikembangkan lagi dengan proses input seperti input username dan nim, seperti halnya proses login. caranya adalah dengan melakukan query ke database apakah username & nim tersebut ada dan sesuai. Jika sesuai maka tempatkan proses jwt.sign diatas ke bagian yang sama dengan response berhasil, sehingga selain menampilkan bahwa data username & nim ada dan sesuai lakukan proses sign terhadap jwt baru dari data-data tersebut untuk menghasilkan jwt baru yang ditampilkan di response berhasil.

Terakhir update juga .env :

# .env
PORT = 8080

MONGODB_HOST="mongodb://127.0.0.1:27017/"
MONGODB_DB="belajar_mvc"

JWT_KEY=kode-rahasia

Untuk melakukan test terhadap anda bisa langsung membuka api http://localhost:8080/v1 di browser, dan jika tampilan seperti pada gambar disamping menandakan bahwa proses validasi berhasil, karena API ini diakses tanpa melakukan authorization.

Terdapat 3 kondisi yaitu jika success kita akan diarahkan ke controller lain, kedua jika token tidak ada, dan jika token salah atau jwt-key salah.

Lalu bagaimana cara agar kita bisa melakukan authorization dan akses data ?. Caranya adalah dengan menggunakan aplikasi bernama postman. Aplikasi ini adalah aplikasi yang biasa digunakan untuk proses developing pengetesan API dan lainnya dan dengan aplikasi ini juga kita bisa dengan mudah memasukan token ke header sebelum menggunakan API.

Pertama anda harus membuka aplikasi Postman, lalu klik tombol tambah untuk membuat collection baru bernama belajar-mvc, lalu buat folder Home di dalamnya dengan cara klik kanan collection -> Add folder. Lalu buat 2 requrest baru dengan cara klik kanan folder -> Add request. lalu jangan lupa ganti nama dengan cara CTRL+F2.

Selanjutnya isi URL Get Data Mahasiswa dengan http://localhost:8080/v1/, lalu pergi ke tab Authorization, pilih type ke Bearer Token, lalu isi form Token dengan {{authorization}}. seperti pada gambar dibawah

Isi juga Auth dengan http://localhost:8080/v1/auth. Ini adalah API Auth yang baru kita buat tadi, pada Request ini kita tidak perlu melakukan konfigurasi terhadap Authorization karena ini seperti bagian dari proses login, dimana API ini tidak memerlukan validasi token sebelum digunakan, karena proses sign token ada disini.

Dan terakhir pergi ke Tab Environment, Tekan Tombol +, buat Environment baru bernama belajar-mvc. Lalu didalamnya tambahkan variable baru bernama authorization

Untuk melakuakan test terhadap API, pertama tekan Send , lalu copy value dari object “token” di body response postman seperti pada gambar dibawah.

Copas kode Token JWT tersebut ke Environment -> belajar-mvc dibagian Initial value dan Current value dari variable authorization.

Dan Terakhir coba jalankan API Get Data Mahasiswa dengan mengklik tombol Send . Jika berhasil maka data yang sama akan muncul seperti pada sebelum menambahkan fungsi Auth di Project ini seperti gambar di bawah. Ini artinya anda sudah mendapat hak akses terhadap data karena anda telah melakukan Login / Authorization sebelum melakukan query data Mahasiswa di halaman Home.

AKHIRRNYAA !!!!, Anda telah berhasil membuat Restfull API + Authorization dengan JSONWebToken. Saya ucapkan terimakasih yang telah membaca artikel ini. Artikel ini adalah akhir dari series MVC kita. Sampai jumpa lagi di artikel lainnya 👋.

Ditulis oleh Backend Developer Intern at Digital Amoeba MSIB Batch 6
Raie Aswajjillah – Universitas Islam Nusantara (linkedin.com/in/raie-aswajjillah)