DISKON TERBATAS! Masukkan kupon "skillbaru" saat checkout di kelas apa saja

Logo Koala Skodev mengetik

Skodev

Belajar coding dalam bahasa Indonesia

MENCOBA ELYSIA, FRAMEWORK BACKEND JAVASCRIPT YANG NGEBUT BANGET!

Di antara banyaknya opsi framework backend web yang tersedia, Elysia adalah salah satu framework backend yang wajib teman-teman coba untuk membuat aplikasi backend yang super ngebut.

Mencoba Elysia, Framework Backend Javascript yang Ngebut Banget!

Daftar Isi:

Apa itu Elysia?
Keunggulan Elysia
Quick Start Elysia
Hands-on Membuat REST API Sede...
Penutup

Dalam pengembangan aplikasi web, framework backend memainkan peran penting dalam menyediakan fondasi dan kerangka kerja yang robust untuk membangun aplikasi yang scalable dan maintainable. Framework backend membantu developer dalam mempermudah pengelolaan data, logika aplikasi, autentikasi, dan berbagai fungsi backend lainnya yang penting untuk aplikasi web yang modern.

Bun adalah runtime JavaScript all-in-one yang dibuat dengan tujuan untuk mempercepat pengembangan aplikasi. Bun menyediakan environment development yang ringan dan cepat untuk menjalankan Javascript dan Typescript, membuat bundling, transpiling, dan menjalankan kode lebih efisien. Dengan dukungan yang luas untuk API NodeJS dan kecepatan yang tinggi, Bun menjadi pilihan menarik bagi developer yang mencari runtime yang cepat dan efisien.

Baca Juga: Mengenal Bun, Runtime Javascript cepat

Saat ini sudah tersedia banyak opsi framework backend Javascript, tetapi kebanyakan masih berjalan di NodeJS. Nah, pada artikel kali ini aku akan membahas tentang Elysia, sebuah framework backend yang berjalan di Bun. Aku akan menjelaskan mulai dari pengenalan, keunggulan, hingga panduan praktis untuk memulai proyek dengan Elysia menggunakan Bun. Langsung saja kita ke pembahasannya ya teman-teman.

Apa itu Elysia?

Elysia adalah framework backend web yang dibangun di atas Bun. Tujuan utama dari pengembangan Elysia adalah untuk menyediakan framework yang mudah digunakan, efisien, dan memiliki performa tinggi untuk pengembangan aplikasi web modern. Elysia memanfaatkan kecepatan dan efisiensi Bun untuk memberikan pengalaman pengembangan yang optimal.

Eksplor apa itu ElysiaJS

Situs ElysiaJS

Keunggulan Elysia

  1. Performa Tinggi: Berkat Bun, Elysia dapat menjalankan aplikasi dengan performa yang sangat tinggi. Bun sebagai runtime yang cepat dan efisien memberikan keuntungan besar dalam hal kecepatan eksekusi kode.
  2. Mudah Digunakan: Elysia dirancang dengan developer experience yang sederhana, memudahkan pengembang untuk memulai dan mengembangkan proyek mereka tanpa kurva belajar yang curam.
  3. Skalabilitas: Dengan desain yang modular, Elysia memungkinkan pengembang untuk membangun aplikasi yang scalable, mendukung pertumbuhan aplikasi dari kecil hingga besar.
  4. Dukungan Typescript: Elysia mendukung Typescript secara penuh, memberikan manfaat tambahan dalam hal type safety dan pengembangan yang lebih robust.
  5. Integrasi Mulus dengan Ekosistem Javascript: Elysia dirancang untuk bekerja dengan baik dengan berbagai library dan tools dalam ekosistem Javascript, membuatnya fleksibel dan mudah diintegrasikan dengan proyek yang sudah ada.

Quick Start Elysia

Untuk memulai proyek dengan Elysia menggunakan Bun, ikuti langkah-langkah berikut:

Instalasi Bun

  1. Unduh dan Install Bun:

Kunjungi situs resmi Bun di Situs Resmi Bun dan ikuti petunjuk instalasi sesuai dengan sistem operasi yang kalian gunakan.

curl -fsSL https://bun.sh/install | bash
  1. Verifikasi Instalasi Bun:

Setelah instalasi selesai, pastikan Bun telah terinstal dengan benar dengan menjalankan perintah berikut di terminal:

bun --version

Membuat Proyek Elysia

  1. Inisialisasi Proyek Baru:

Buat direktori baru untuk proyek kalian dan inisialisasi proyek dengan Bun.

mkdir elysia-project

cd elysia-project

bun init

Screenshot init bun

  1. Install Dependencies:

Install Elysia dan @elysiajs/swagger sebagai dependensi dalam proyek kalian.

bun add elysia @elysiajs/swagger
  1. Menambahkan Scripts pada package.json

Tambahkan kode di bawah ini pada file package.json kalian.

"scripts": {
	"dev": "bun --watch src/index.ts",
	"build": "bun build src/index.ts",
	"start": "NODE_ENV=production bun src/index.ts"
},

Script diatas merujuk pada tahapan-tahapan berbeda dalam mengembangkan sebuah aplikasi:

Struktur Proyek Elysia

Setelah menginisialisasi proyek, struktur direktori proyek akan terlihat seperti ini:

elysia-project/
	├── node_modules/
	├── src/
	│ └── index.ts
	├── .gitignore
	├── bun.lockb
	├── package.json
	├── README.md
	└── tsconfig.json

Hands-on Membuat REST API Sederhana dengan Elysia

Sekarang, kita akan membuat REST API sederhana menggunakan Elysia. Disini aku akan menggunakan bahasa Typescript dan studi kasus yang akan kita gunakan adalah API CRUD (Create, Read, Update, Delete) untuk mengelola kontak. Berikut merupakan langkah-langkahnya:

Membuat API CRUD Kontak

  1. Definisikan types

Buat file types.d.ts pada root project dan tambahkan type untuk kontak.

type Contact {
	id: number;
	name: string;
	email: string;
}
  1. Buat file db.ts di folder src

File ini akan berperan sebagai pusat operasi CRUD dari API kontak. Tambahkan kode di bawah ini pada file db.ts.

const contacts: Contact[] = [];
let nextId = 1;

export class ContactDB {
    async getContacts(): Promise<Contact[]> {
        return contacts;
    }

    async getContact(id: number): Promise<Contact | undefined> {
        return contacts.find(c => c.id === id);
    }

    async addContact(contact: Omit<Contact, 'id'>): Promise<Contact> {
        const newContact = { ...contact, id: nextId++ };
        contacts.push(newContact);

        return newContact;
    }

    async updateContact(id: number, updatedContact: Omit<Contact, 'id'>): Promise<string | undefined> {
        const contactIndex = contacts.findIndex(c => c.id === id);
        if (contactIndex !== -1) {
            contacts[contactIndex] = { ...updatedContact, id };

            return "success";
        } else {
            return undefined;
        }
    }

    async removeContact(id: number): Promise<string | undefined> {
        const contactIndex = contacts.findIndex(c => c.id === id);
        if (contactIndex !== -1) {
            contacts.splice(contactIndex, 1);

            return "success";
        } else {
            return undefined;
        }
    }
}
  1. ** Buat plugin instance contactApi pada file index.ts**

Buat plugin instance contactApi pada file index.ts untuk mengelompokkan route dengan prefix /api.

..
import { Elysia } from 'elysia';
..
const contactApi = new Elysia({ prefix: '/api' })
...
  1. Endpoint untuk Menambah Kontak

Tambahkan endpoint untuk menambah kontak baru pada contactApi.

...
import { ContactDB } from './db';
...
.post(
        "/contacts",
        async ({ db, body }: { db: ContactDB, body: Contact }) => {
            const id = (await db.addContact(body)).id

            return { success: true, message: `Contact ${id} added` };
        },
        {
            detail: {
                summary: 'Add contact',
                description: 'Add contact to the database',
                requestBody: {
                    content: {
                        'application/json': {
                            schema: {
                                type: 'object',
                                properties: {
                                    name: { type: 'string' },
                                    email: { type: 'string' }
                                },
                                example: {
                                    name: 'Wahyu',
                                    email: 'wahyu@example.com'
                                },
                                required: ['name', 'email']
                            }
                        }
                    }
                },
                responses: {
                    200: {
                        description: 'Success',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: true
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact 1 added'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    },
                    400: {
                        description: 'Bad Request',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: false
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Invalid request'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    }
                }
            }
        }
    )
    ...
  1. Endpoint untuk Mendapatkan Semua Kontak

Tambahkan endpoint untuk mendapatkan list semua kontak pada contactApi.

...
.get('/contacts',
        async ({ db }: { db: ContactDB }) => {
            const contacts = await db.getContacts();
            return {
                success: true,
                data: contacts
            };
        },
        {
            detail: {
                summary: 'Get contacts',
                description: 'Get all contacts from the database',
                responses: {
                    200: {
                        description: 'Success',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean'
                                        },
                                        data: {
                                            type: 'array',
                                            items: {
                                                $ref: '#/components/schemas/Contact'
                                            },
                                            example: [{
                                                id: 1,
                                                name: 'Wahyu',
                                                email: 'wahyu@example.com'
                                            }]
                                        }
                                    },
                                    required: ['success', 'data']
                                }
                            }
                        }
                    }
                }
            }
        }
    )
    ...
  1. Endpoint untuk Mendapatkan Kontak Berdasarkan ID

Tambahkan endpoint untuk mendapatkan kontak berdasarkan ID pada contactApi.

...
.get('/contacts/:id',
        async ({ db, params }: { db: ContactDB, params: { id: string } }) => {
            const id = parseInt(params.id);
            if (id === undefined) {
                return { success: false, message: 'Invalid request' };
            }

            const contact = await db.getContact(id);
            if (contact === undefined) {
                return { success: false, message: 'Not found' };
            }

            return { success: true, data: contact };
        },
        {
            detail: {
                summary: 'Get contact by ID',
                description: 'Get contact from the database by ID',
                parameters: [
                    {
                        name: 'id',
                        in: 'path',
                        description: 'Contact ID',
                        required: true,
                        schema: {
                            type: 'number'
                        }
                    }
                ],
                responses: {
                    200: {
                        description: 'Success',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean'
                                        },
                                        data: {
                                            type: 'object',
                                            properties: {
                                                id: {
                                                    type: 'number'
                                                },
                                                name: {
                                                    type: 'string'
                                                },
                                                email: {
                                                    type: 'string'
                                                }
                                            },
                                            example: {
                                                id: 1,
                                                name: 'Wahyu',
                                                email: 'wahyu@example.com'
                                            },
                                            required: ['id', 'name', 'email']
                                        }
                                    },
                                    required: ['success', 'data']
                                }
                            }
                        }
                    },
                    404: {
                        description: 'Not Found',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: false
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact not found'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    }
                }
            }
        }
    )
    ...
  1. Endpoint untuk Mengupdate Kontak

Tambahkan endpoint untuk mengupdate kontak berdasarkan ID pada contactApi.

...
.put(
        "/contacts/:id",
        async ({ db, params, body }: { db: ContactDB, params: { id: string }, body: Contact }) => {
            const id = parseInt(params.id);
            if (id === undefined) {
                return { success: false, message: 'Invalid request' };
            }

            const contact = await db.updateContact(id, body);
            if (contact === undefined) {
                return { success: false, message: 'Not found' };
            }

            return { success: true, message: `Contact ${id} updated` };
        },
        {
            detail: {
                summary: 'Update contact',
                description: 'Update contact in the database',
                parameters: [
                    {
                        name: 'id',
                        in: 'path',
                        description: 'Contact ID',
                        required: true,
                        schema: {
                            type: 'number'
                        }
                    }
                ],
                requestBody: {
                    content: {
                        'application/json': {
                            schema: {
                                type: 'object',
                                properties: {
                                    name: { type: 'string' },
                                    email: { type: 'string' }
                                },
                                example: {
                                    name: 'Wahyu Ivan',
                                    email: 'wahyu@example.com'
                                },
                                required: ['name', 'email']
                            }
                        }
                    }
                },
                responses: {
                    200: {
                        description: 'Success',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: true
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact 1 updated'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    },
                    400: {
                        description: 'Bad Request',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: false
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Invalid request'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    },
                    404: {
                        description: 'Not Found',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: false
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact not found'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    }
                }
            }
        }
    )
  1. Endpoint untuk Menghapus Kontak

Tambahkan endpoint untuk menghapus kontak berdasarkan ID pada contactApi.

...
.delete(
        "/contacts/:id",
        async ({ db, params }: { db: ContactDB, params: { id: string } }) => {
            const id = parseInt(params.id);
            if (id === undefined) {
                return { success: false, message: 'Invalid request' };
            }

            const contact = await db.removeContact(id);
            if (contact === undefined) {
                return { success: false, message: 'Not found' };
            }

            return { success: true, message: `Contact ${id} removed` };
        },
        {
            detail: {
                summary: 'Remove contact',
                description: 'Remove contact from the database',
                parameters: [
                    {
                        name: 'id',
                        in: 'path',
                        description: 'Contact ID',
                        required: true,
                        schema: {
                            type: 'number'
                        }
                    }
                ],
                responses: {
                    200: {
                        description: 'Success',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: true
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact 1 removed'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    },
                    404: {
                        description: 'Not Found',
                        content: {
                            'application/json': {
                                schema: {
                                    type: 'object',
                                    properties: {
                                        success: {
                                            type: 'boolean',
                                            example: false
                                        },
                                        message: {
                                            type: 'string',
                                            example: 'Contact not found'
                                        }
                                    },
                                    required: ['success', 'message']
                                }
                            }
                        }
                    }
                }
            }
        }
    );
  1. Buat instance Elysia baru

Buat instance Elysia baru dan tambahkan plugin contactApi, Swagger dan property ContactDB pada file index.ts. Swagger disini adalah sebuah open-source project yang memungkinkan kita untuk membuat dokumentasi API dengan mudah. Setalah itu, set server agar berjalan pada port 3000.

...
import { swagger } from '@elysiajs/swagger'
...
new Elysia()
    .use(swagger({
        documentation: {
            info: {
                title: 'Contact API',
                version: '1.0.0',
                description: 'Contact API project. Developed using Elysia framework, bun, and TypeScript.'
            }
        }
    }))
    .use(contactApi)
    .decorate('db', new ContactDB())
    .listen(3000);
  1. Menjalankan Server:

Untuk menjalankan server, gunakan perintah berikut di terminal:

bun dev

Server akan berjalan di http://localhost:3000 dan kalian sudah bisa mengakses API yang telah dibuat. Untuk melihat dokumentasi API dengan Swagger, akses endpoint /swagger. Screenshot Swagger

Untuk melihat project dan source code secara penuh: Link Github Proyek

Penutup

Elysia menawarkan solusi modern untuk pengembangan backend web dengan memanfaatkan kekuatan dan kecepatan Bun sebagai fondasinya. Dengan kemudahan integrasi dan dukungan penuh untuk Typescript, Elysia memberikan pengalaman development yang cepat dan efisien. Semoga artikel ini membantu kalian dalam memulai dan mengembangkan API menggunakan Elysia dan Bun. Selamat mencoba!

Penulis: Wahyu Ivan

/ @ivanwahyu195

Halo, saya Wahyu. Saat ini saya bekerja sebagai Software Engineer di Taksu Tech. Semoga artikel yang saya tulis bermanfaat untuk temen-temen.

Daftar newsletter skodev masukkan emailmu untuk dapat informasi menarik dari dunia koding