Kenali runtime JS yang berfokus pada keamanan ini dengan proyek contoh praktis.
Deno adalah runtime JavaScript yang dibangun di atas V8, mesin JavaScript yang sama yang mendukung Google Chrome. Pembuat asli Node.js membuat Deno untuk mengatasi beberapa kekurangan dan masalah keamanan Node.js.
Meskipun relatif baru, Deno telah mendapatkan popularitas sebagai runtime JavaScript yang aman dan modern. Fokusnya pada keamanan, dukungan untuk fitur bahasa modern, dan alat yang ramah pengembang menjadikannya pilihan yang menarik. Anda dapat menggunakannya untuk membuat aplikasi sisi server, alat baris perintah, dan proyek JavaScript/TypeScript lainnya, seperti API sederhana.
Memasang Deno
Sebelum Anda dapat menggunakan Deno, Anda harus mengunduh dan menginstalnya. Instalasi Deno bervariasi tergantung pada sistem operasi Anda.
Di macOS dan Linux, Anda dapat menginstal Deno dengan menjalankan perintah ini:
curl -fsSL https://deno.land/x/install/install.sh | sh
Di Windows, Anda dapat menginstal Deno dengan Powershell, menggunakan perintah ini:
irm https://deno.land/install.ps1 | iex
Anda dapat mengonfirmasi bahwa instalasi Anda berhasil dengan menjalankan perintah di bawah ini:
deno --version
Perintah di atas harus mencetak versi Deno ke konsol.
Jika Anda menggunakan VS Code sebagai IDE, Anda dapat mengunduh Ekstensi Kode VS Deno untuk menambahkan IntelliSense, meningkatkan produktivitas dan pengalaman pengembangan Anda saat bekerja dengan proyek Deno.
Setelah berhasil menginstal ekstensi, buat a .vscode folder di direktori root proyek Anda dan buat file pengaturan.json berkas di dalamnya.
Selanjutnya, tambahkan blok kode di bawah ini ke file pengaturan.json file untuk mengaktifkan IntelliSense:
{
"deno.enable": true,
"deno.unstable": true,
}
Menghubungkan ke Database
Untuk tutorial ini, Anda akan menggunakan MongoDB sebagai database untuk menyimpan data dari API Anda.
Untuk menghubungkan aplikasi Deno Anda ke database MongoDB, buat a db.js file di direktori root proyek Anda dan tambahkan blok kode di bawah ini ke dalamnya:
// db.js
import { MongoClient } from"https://deno.land/x/[email protected]/mod.ts";const client = new MongoClient();
try {
await client.connect("mongodb://localhost: 27017/todo");console.log("Connected to database");
} catch (err) {
console.log("Error connecting to database", err);
}const db = client.database("todo");
exportdefault db;
Tidak seperti Node.js, yang bergantung pada manajer paket seperti Node Package Manager (npm) atau benang, Deno memiliki sistem manajemen paket bawaan untuk mengimpor dan mengelola dependensi langsung dari URL.
Misalnya, blok kode di atas impor Klien Mongo dari URL https://deno.land/x/[email protected]/mod.ts, yang mengarah ke paket.
Kemudian, menggunakan driver Deno MongoDB yang diimpor (Klien Mongo), Deno membuat koneksi antara aplikasi Anda dan database MongoDB lokal.
Dalam skenario langsung, akan lebih aman untuk menyimpan kredensial database Anda dalam file .env file alih-alih menyimpannya dalam teks biasa, seperti yang dilakukan di atas.
Membuat Model Basis Data
Meskipun mungkin untuk berinteraksi dengan database MongoDB tanpa model basis data, hal itu dapat menyebabkan kode yang tidak terstruktur dan kurang dapat dipelihara.
Untuk menghindari hal ini, buatlah a TodoModel.ts file di direktori root proyek Anda dan susun data Anda dengan menambahkan blok kode di bawah ini ke file:
import db from"./db.ts";
interface Todo {
title: string;
description: string;
completed?: boolean;
}const Todo = db.collection
("todos");
exportdefault Todo;
Blok kode di atas mendefinisikan antarmuka Melakukan yang mewakili struktur item todo tunggal. Kemudian menggunakan antarmuka Todo, itu membuat koleksi Todo dengan memanggil metode pengumpulan yang diekspos oleh instance MongoDB yang Anda buat sebelumnya.
Membuat Server Dengan Oak
Oak adalah middleware untuk server HTTP asli Deno. Itu terinspirasi oleh Koa, yang merupakan alternatif untuk Express.js.
Untuk membuat server dengan Oak, buat a main.ts file di direktori root proyek Anda dan tambahkan blok kode di bawah ini ke file Anda.
// main.ts
import { Application } from"https://deno.land/x/oak/mod.ts";
import router from"./router.ts";const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());
await app.listen({ port: 8000 });
console.log("Server running on port 8000");
Blok kode di atas impor Aplikasi dari URL Oak dan membuat instance aplikasi (aplikasi) yang mendengarkan lalu lintas masuk pada port 8000.
Itu aplikasi.gunakan (router.routes()) line mendaftarkan rute router sebagai middleware di aplikasi Oak. Ini berarti bahwa aplikasi akan mencocokkan rute terdaftar dengan permintaan yang masuk, dan penangan yang sesuai akan berjalan jika ada kecocokan.
Itu app.use (router.allowedMethods()) line menangani metode HTTP yang tidak didefinisikan secara eksplisit di router. Misalnya, jika menerima permintaan dengan metode yang tidak didukung, misalnya permintaan PUT yang tidak terdaftar, Metode yang diizinkan() middleware akan secara otomatis mengirim respons yang sesuai (mis., 405 Metode Tidak Diizinkan).
Menerapkan Fungsi CRUD
Tutorial ini akan menampilkan API todo sederhana dengan fungsionalitas CRUD.
Membuat router.ts file di direktori root proyek Anda dan tambahkan blok kode di bawah ini ke file Anda:
import { Router } from"https://deno.land/x/oak/mod.ts";
import Todo from"./todoModel.ts";
import { ObjectId } from"https://deno.land/x/[email protected]/mod.ts";
const router = new Router(); // Create Router
Blok kode di atas mengimpor dan membuat instance dari router Oak. Dengan menggunakan contoh ini, Anda dapat membuat penangan rute untuk berbagai metode HTTP dengan memanggil nama masing-masing metode (mendapatkan, pos, meletakkan, menghapus).
Misalnya, blok kode di bawah ini adalah contoh bagaimana Anda bisa membuat pengendali rute GET yang mengembalikan semua dokumen dalam koleksi Todo Anda.
router
.get("/api/todos", (ctx: RouterContextapi/todos">) => {
ctx.response.body = Todo.find();
})
Untuk mengirim objek respons menggunakan Deno, Anda harus menetapkan response.body objek pada RouterContex ke objek respon. Hal yang sama berlaku untuk kode status.
Untuk menambahkan penangan rute lain, Anda dapat mengaitkannya ke penangan rute sebelumnya.
Seperti itu:
.get("/api/todo/:id", async (ctx: RouterContext<"/api/todo/:id">) => {
try {
const todo = await Todo.findOne({ _id: new ObjectId(ctx.params.id) });if (!todo) {
ctx.response.status = 404;ctx.response.body = {
msg: "Todo not found",
};return;
}ctx.response.body = todo;
} catch (error) {
ctx.response.status = 500;
ctx.response.body = {
msg: "Error getting todo",
error,
};
}
})
Blok kode di atas menentukan penangan rute GET yang mengembalikan satu item Todo yang cocok dengan id di parameter URL.
Selanjutnya, tentukan penangan rute CREATE yang menambahkan dokumen baru ke koleksi Anda:
.post("/api/todo/new", async (ctx: RouterContext<"/api/todo/new">) => {
const body = ctx.request.body();
const todo = await body.value;if (!todo) {
ctx.response.status = 400;
ctx.response.body = { msg: "Invalid data. Please provide a valid todo." };
return;
}const { title, description } = todo;
if (!(title && description)) {
ctx.response.status = 400;ctx.response.body = {
msg: "Title or description missing. Please provide a valid todo.",
};return;
}try {
await Todo.insertOne({
title: todo.title,
description: todo.description,
completed: false,
});ctx.response.status = 201;
ctx.response.body = {
msg: "Todo added successfully",
};
} catch (error) {
ctx.response.status = 500;
ctx.response.body = {
msg: "Error adding todo",
error,
};
}
})
Selanjutnya, tambahkan pengendali rute PUT yang memperbarui Todo berdasarkan pengenal parameter, dengan data yang dikirim dalam badan permintaan.
.put("/api/todo/:id", async (ctx: RouterContext<"/api/todo/:id">) => {
try {
const body = ctx.request.body();
const todo = await body.value;await Todo.updateOne(
{ _id: new ObjectId(ctx.params.id) },
{ $set: { title: todo.title, description: todo.description } }
);ctx.response.status = 200;
ctx.response.body = {
msg: "Todo updated successfully",
};
} catch (error) {
console.log(error);
ctx.response.status = 500;
ctx.response.body = {
msg: "Error updating todo",
error: error.message,
};
}
})
Terakhir, buat pengendali rute DELETE yang menghapus Todo dari koleksi MongoDB Anda:
.delete("/api/todo/:id", async (ctx: RouterContext<"/api/todo/:id">) => {
await Todo.deleteOne({ _id: new ObjectId(ctx.params.id) });ctx.response.status = 200;
ctx.response.body = {
msg: "Todo deleted successfully",
};
});
Anda dapat memulai aplikasi Deno Anda dengan perintah ini:
deno run --allow-net --allow-read --allow-env --watch main.ts
Secara default, skrip Deno tidak dapat mengakses apa pun di luar cakupannya, seperti jaringan atau sistem file. Jadi untuk memulai aplikasi Anda, Anda harus menyertakan berbagai flag untuk memberikan Deno izin yang diperlukan.
--izinkan-bersih memungkinkan Deno untuk membuat permintaan jaringan. --izinkan-baca memungkinkan Deno untuk mengakses sistem file dan membaca file. --izinkan-env memungkinkan Deno untuk mengakses variabel lingkungan. Itu --jam tangan flag memulai aplikasi Deno Anda dalam mode jam tangan.
Bermigrasi dari Node.js ke Deno
Bermigrasi dari Node.js ke Deno untuk membangun REST API dapat memberikan manfaat keamanan, produktivitas pengembang, dan manajemen ketergantungan yang signifikan. Menggunakan runtime aman Deno, dukungan TypeScript asli, dan manajemen ketergantungan yang disederhanakan, Anda dapat dengan mudah membuat REST API yang kuat dan efisien.
Namun, ekosistem Deno yang belum matang dapat membuat Anda berpikir ulang. Jika Anda memilih untuk bermigrasi, pertimbangkan baik-baik pro dan kontranya.