Lernen Sie diese sicherheitsorientierte JS-Laufzeitumgebung anhand eines praktischen Beispielprojekts kennen.

Deno ist eine JavaScript-Laufzeitumgebung, die auf V8 basiert, der gleichen JavaScript-Engine, die auch Google Chrome antreibt. Der ursprüngliche Erfinder von Node.js hat Deno erstellt, um einige der Mängel und Sicherheitsbedenken von Node.js zu beheben.

Obwohl es relativ neu ist, hat Deno als sichere und moderne JavaScript-Laufzeitumgebung an Popularität gewonnen. Sein Fokus auf Sicherheit, die Unterstützung moderner Sprachfunktionen und entwicklerfreundliche Tools machen es zu einer attraktiven Wahl. Sie können damit serverseitige Anwendungen, Befehlszeilentools und andere JavaScript-/TypeScript-Projekte erstellen, beispielsweise eine einfache API.

Deno installieren

Bevor Sie Deno verwenden können, müssen Sie es herunterladen und installieren. Die Installation von Deno variiert je nach Betriebssystem.

Unter macOS und Linux können Sie Deno installieren, indem Sie diesen Befehl ausführen:

curl -fsSL https://deno.land/x/install/install.sh | sh

Unter Windows können Sie Deno mit Powershell installieren, indem Sie diesen Befehl verwenden:

irm https://deno.land/install.ps1 | iex

Sie können bestätigen, dass Ihre Installation erfolgreich war, indem Sie den folgenden Befehl ausführen:

deno --version

Der obige Befehl sollte die Deno-Version auf der Konsole ausgeben.

Wenn Sie VS Code als IDE verwenden, können Sie es herunterladen Denos VS Code-Erweiterung um IntelliSense hinzuzufügen und so Ihre Produktivität und Entwicklungserfahrung bei der Arbeit mit Deno-Projekten zu verbessern.

Erstellen Sie nach erfolgreicher Installation der Erweiterung eine .vscode Ordner im Stammverzeichnis Ihres Projekts und erstellen Sie einen Settings.json Datei darin.

Fügen Sie als Nächstes den folgenden Codeblock hinzu Settings.json Datei zum Aktivieren von IntelliSense:

{
"deno.enable": true,
"deno.unstable": true,
}

Herstellen einer Verbindung zu einer Datenbank

Für dieses Tutorial verwenden Sie MongoDB als Datenbank, um Daten aus Ihrer API beizubehalten.

Um Ihre Deno-App mit einer MongoDB-Datenbank zu verbinden, erstellen Sie eine db.js Datei in Ihrem Projektstammverzeichnis und fügen Sie den folgenden Codeblock hinzu:

// 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;

Im Gegensatz zu Node.js, das davon abhängt Paketmanager Wie der Node Package Manager (npm) oder Yarn verfügt Deno über ein integriertes Paketverwaltungssystem zum Importieren und Verwalten von Abhängigkeiten direkt von URLs.

Beispielsweise wird der obige Codeblock importiert MongoClient von der URL https://deno.land/x/[email protected]/mod.ts, was zum Paket führt.

Verwenden Sie dann den importierten Deno MongoDB-Treiber (MongoClient) stellt Deno eine Verbindung zwischen Ihrer Anwendung und einer lokalen MongoDB-Datenbank her.

In Live-Szenarien ist es sicherer, Ihre Datenbankanmeldeinformationen in einem zu speichern .env Datei, anstatt sie wie oben beschrieben im Klartext zu speichern.

Erstellen eines Datenbankmodells

Obwohl es möglich ist mit einer MongoDB-Datenbank interagieren Ohne ein Datenbankmodell kann dies zu unstrukturiertem und weniger wartbarem Code führen.

Um dies zu vermeiden, erstellen Sie eine TodoModel.ts Datei im Stammverzeichnis Ihres Projekts und strukturieren Sie Ihre Daten, indem Sie der Datei den folgenden Codeblock hinzufügen:

import db from"./db.ts";

interface Todo {
title: string;
description: string;
completed?: boolean;
}

const Todo = db.collection("todos");

exportdefault Todo;

Der obige Codeblock definiert eine Schnittstelle Machen das die Struktur eines einzelnen Aufgabenelements darstellt. Mithilfe der Todo-Schnittstelle wird dann eine Todo-Sammlung erstellt, indem die von Ihrer zuvor erstellten MongoDB-Instanz bereitgestellte Sammlungsmethode aufgerufen wird.

Erstellen eines Servers mit Oak

Oak ist eine Middleware für Denos nativen HTTP-Server. Es wurde von Koa inspiriert, einem Alternative zu Express.js.

Um einen Server mit Oak zu erstellen, erstellen Sie einen main.ts Datei in Ihrem Projektstammverzeichnis und fügen Sie den folgenden Codeblock zu Ihrer Datei hinzu.

// 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");

Der obige Codeblock importiert Anwendung von der Oak-URL und erstellt eine Anwendungsinstanz (App), der auf eingehenden Datenverkehr auf Port 8000 lauscht.

Der app.use (router.routes()) line registriert die Routen des Routers als Middleware in der Oak-Anwendung. Das bedeutet, dass die Anwendung die registrierten Routen mit eingehenden Anfragen abgleicht und die entsprechenden Handler ausgeführt werden, wenn eine Übereinstimmung besteht.

Der app.use (router.allowedMethods()) Zeile verarbeitet HTTP-Methoden, die nicht explizit im Router definiert sind. Wenn es beispielsweise eine Anfrage mit einer nicht unterstützten Methode empfängt, beispielsweise eine nicht registrierte PUT-Anfrage, wird die erlaubteMethoden() Die Middleware sendet automatisch eine entsprechende Antwort (z. B. 405 Methode nicht zulässig).

Implementierung der CRUD-Funktionalität

In diesem Tutorial wird eine einfache Todo-API mit CRUD-Funktionalität vorgestellt.

Ein... kreieren router.ts Datei im Stammverzeichnis Ihres Projekts und fügen Sie den folgenden Codeblock zu Ihrer Datei hinzu:

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

Der obige Codeblock importiert und erstellt eine Instanz des Oak-Routers. Mit dieser Instanz können Sie Route-Handler für verschiedene HTTP-Methoden erstellen, indem Sie die jeweiligen Methodennamen aufrufen (erhalten, Post, setzen, löschen).

Der folgende Codeblock ist beispielsweise ein Beispiel dafür, wie Sie einen GET-Routenhandler erstellen können, der alle Dokumente in Ihrer Todo-Sammlung zurückgibt.

router
.get("/api/todos", (ctx: RouterContextapi/todos">) => {
ctx.response.body = Todo.find();
})

Um ein Antwortobjekt mit Deno zu senden, müssen Sie das zuweisen Antwortkörper Objekt auf dem RouterContex zum Antwortobjekt. Gleiches gilt für Statuscodes.

Um weitere Routenhandler hinzuzufügen, können Sie diese mit dem vorherigen Routenhandler verketten.

Etwa so:

.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,
};
}
})

Der obige Codeblock definiert einen GET-Routenhandler, der ein einzelnes Todo-Element zurückgibt, das mit der ID in den URL-Parametern übereinstimmt.

Definieren Sie als Nächstes einen CREATE-Routenhandler, der Ihrer Sammlung neue Dokumente hinzufügt:

.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,
};
}
})

Als nächstes fügen Sie einen PUT-Routenhandler hinzu, der ein Todo basierend auf aktualisiert Ausweis Parameter, mit den im Anfragetext gesendeten Daten.

.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,
};
}
})

Erstellen Sie abschließend einen DELETE-Routenhandler, der ein Todo aus Ihrer MongoDB-Sammlung entfernt:

.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",
};
});

Sie können Ihre Deno-App mit diesem Befehl starten:

deno run --allow-net --allow-read --allow-env --watch main.ts

Standardmäßig kann ein Deno-Skript nicht auf etwas außerhalb seines Gültigkeitsbereichs zugreifen, beispielsweise auf das Netzwerk oder das Dateisystem. Um Ihre Anwendung zu starten, müssen Sie also verschiedene Flags einfügen, um Deno die erforderlichen Berechtigungen zu erteilen.

--allow-net ermöglicht Deno, Netzwerkanfragen zu stellen. --allow-read ermöglicht Deno den Zugriff auf das Dateisystem und das Lesen von Dateien. --allow-env ermöglicht Deno den Zugriff auf Umgebungsvariablen. Der --betrachten flag startet Ihre Deno-App im Watch-Modus.

Migration von Node.js nach Deno

Die Migration von Node.js zu Deno zum Erstellen von REST-APIs kann erhebliche Vorteile in Bezug auf Sicherheit, Entwicklerproduktivität und Abhängigkeitsmanagement bringen. Mithilfe der sicheren Laufzeit von Deno, der nativen TypeScript-Unterstützung und der vereinfachten Abhängigkeitsverwaltung können Sie ganz einfach robuste und effiziente REST-APIs erstellen.

Das unausgereifte Deno-Ökosystem könnte Sie jedoch zum Umdenken veranlassen. Wenn Sie sich für eine Migration entscheiden, wägen Sie die Vor- und Nachteile sorgfältig ab.