Ismerje meg ezt a biztonságra összpontosító JS-futási környezetet egy gyakorlati példaprojekt segítségével.

A Deno egy JavaScript futtatókörnyezet, amely V8-ra épül, ugyanaz a JavaScript-motor, amely a Google Chrome-ot is működteti. A Node.js eredeti készítője azért hozta létre a Denót, hogy orvosolja a Node.js néhány hiányosságát és biztonsági aggályát.

Bár viszonylag új, a Deno biztonságos és modern JavaScript futtatókörnyezetként vált népszerűvé. A biztonságra való összpontosítás, a modern nyelvi funkciók támogatása és a fejlesztőbarát eszközök vonzó választássá teszik. Használhatja szerveroldali alkalmazások, parancssori eszközök és egyéb JavaScript/TypeScript projektek létrehozására, például egy egyszerű API-ra.

Deno telepítése

A Deno használatához le kell töltenie és telepítenie kell. A Deno telepítése az operációs rendszertől függően változik.

MacOS és Linux rendszeren a következő parancs futtatásával telepítheti a Deno-t:

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

Windows rendszeren a Deno a Powershell segítségével telepíthető a következő paranccsal:

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

Az alábbi parancs futtatásával ellenőrizheti, hogy a telepítés sikeres volt:

deno --version

A fenti parancsnak ki kell nyomtatnia a Deno verziót a konzolra.

Ha VS Code-ot használ IDE-ként, letöltheti A Deno VS Code kiterjesztése az IntelliSense hozzáadásához, növelve a termelékenységet és a fejlesztési tapasztalatokat, amikor Deno projektekkel dolgozik.

A bővítmény sikeres telepítése után hozzon létre a .vscode mappát a projekt gyökérkönyvtárában, és hozzon létre egy settings.json fájlt benne.

Ezután adja hozzá az alábbi kódblokkot a settings.json fájl az IntelliSense engedélyezéséhez:

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

Csatlakozás egy adatbázishoz

Ebben az oktatóanyagban a MongoDB-t fogja használni adatbázisként az API-ból származó adatok megőrzéséhez.

A Deno alkalmazás MongoDB adatbázishoz való csatlakoztatásához hozzon létre egy db.js fájlt a projekt gyökérkönyvtárába, és adja hozzá az alábbi kódblokkot:

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

Ellentétben a Node.js-szel, amely attól függ csomagkezelők A Node Package Managerhez (npm) vagy a fonalhoz hasonlóan a Deno beépített csomagkezelő rendszerrel rendelkezik a függőségek közvetlenül az URL-ekből történő importálására és kezelésére.

Például a fenti kódblokk importál MongoClient az URL-ből https://deno.land/x/[email protected]/mod.ts, ami a csomaghoz vezet.

Ezután az importált Deno MongoDB illesztőprogram segítségével (MongoClient), a Deno kapcsolatot hoz létre az alkalmazás és a helyi MongoDB adatbázis között.

Élő forgatókönyvek esetén biztonságosabb, ha az adatbázis hitelesítő adatait egy .env fájlt, ahelyett, hogy egyszerű szövegben tárolná őket, ahogy fentebb.

Adatbázismodell készítése

Miközben lehetséges kölcsönhatásba lép egy MongoDB adatbázissal adatbázismodell nélkül ez strukturálatlan és kevésbé karbantartható kódhoz vezethet.

Ennek elkerülése érdekében hozzon létre a TodoModel.ts fájlt a projekt gyökérkönyvtárába, és strukturálja az adatokat az alábbi kódblokk hozzáadásával a fájlhoz:

import db from"./db.ts";

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

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

exportdefault Todo;

A fenti kódblokk interfészt határoz meg Csinálni amely egyetlen feladatelem szerkezetét reprezentálja. Ezután a Todo felület használatával létrehoz egy Todo-gyűjteményt a korábban létrehozott MongoDB-példány által közzétett gyűjtési metódus meghívásával.

Szerver készítése tölgyből

Az Oak egy köztes szoftver a Deno natív HTTP-kiszolgálójához. A Koa ihlette, amely egy az Express.js alternatívája.

Szerver létrehozásához az Oak segítségével hozzon létre a fő.ts fájlt a projekt gyökérkönyvtárába, és adja hozzá az alábbi kódblokkot a fájlhoz.

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

A fenti kódblokk importál Alkalmazás az Oak URL-ből, és létrehoz egy alkalmazáspéldányt (kb), amely a 8000-es porton figyeli a bejövő forgalmat.

A app.use (router.routes()) line köztes szoftverként regisztrálja az útválasztó útvonalait az Oak alkalmazásban. Ez azt jelenti, hogy az alkalmazás egyezteti a regisztrált útvonalakat a bejövő kérésekkel, és a megfelelő kezelők futnak, ha van egyezés.

A app.use (router.allowedMethods()) sor olyan HTTP metódusokat kezel, amelyek nincsenek kifejezetten definiálva az útválasztóban. Például, ha nem támogatott metódusú kérést kap, például nem regisztrált PUT kérést, a engedélyezett módszerek() a köztes szoftver automatikusan megfelelő választ küld (pl. 405 A módszer nem engedélyezett).

A CRUD funkcionalitás megvalósítása

Ez az oktatóanyag egy egyszerű teendő API-t tartalmaz CRUD funkcióval.

Hozzon létre egy router.ts fájlt a projekt gyökérkönyvtárába, és adja hozzá az alábbi kódblokkot a fájlhoz:

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

A fenti kódblokk importálja és létrehozza az Oak útválasztó példányát. Ezzel a példánysal útvonalkezelőket hozhat létre különböző HTTP metódusokhoz a megfelelő metódusnevek (kap, hozzászólás, fel, töröl).

Például az alábbi kódblokk egy példa arra, hogyan hozhat létre egy GET útvonalkezelőt, amely visszaadja a Todo gyűjteményében található összes dokumentumot.

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

Ha válaszobjektumot szeretne küldeni a Deno használatával, hozzá kell rendelnie a válasz.test objektumot a RouterContexen a válaszobjektumhoz. Ugyanez vonatkozik az állapotkódokra is.

Más útvonalkezelők hozzáadásához láncolhatja őket az előző útvonalkezelőhöz.

Például így:

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

A fenti kódblokk egy GET útvonalkezelőt határoz meg, amely egyetlen feladatelemet ad vissza, amely megegyezik az URL-paraméterek azonosítójával.

Ezután határozzon meg egy CREATE útvonalkezelőt, amely új dokumentumokat ad a gyűjteményéhez:

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

Ezután adjon hozzá egy PUT útvonalkezelőt, amely frissíti a Todo-t a id paramétert, a kérelem törzsében elküldött adatokkal.

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

Végül hozzon létre egy DELETE útvonalkezelőt, amely eltávolít egy teendőt a MongoDB gyűjteményéből:

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

A Deno alkalmazást ezzel a paranccsal indíthatja el:

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

Alapértelmezés szerint a Deno szkript nem fér hozzá semmihez, amely kívül esik a hatókörén, például a hálózathoz vagy a fájlrendszerhez. Tehát az alkalmazás elindításához különféle jelzőket kell megadnia, hogy megadja a Deno számára a szükséges engedélyeket.

--allow-net lehetővé teszi a Deno számára, hogy hálózati kéréseket tegyen. --engedély-olvasás lehetővé teszi a Deno számára a fájlrendszer elérését és a fájlok olvasását. --allow-env lehetővé teszi a Deno számára a környezeti változók elérését. A --néz zászló elindítja a Deno alkalmazást óra módban.

Migráció Node.js-ről Deno-ra

A Node.js-ről a Deno-ra való migráció a REST API-k létrehozásához jelentős biztonsági, fejlesztői termelékenységi és függőségi kezelési előnyökkel járhat. A Deno biztonságos futtatókörnyezetének, a natív TypeScript-támogatásnak és az egyszerűsített függőségkezelésnek köszönhetően könnyedén hozhat létre robusztus és hatékony REST API-kat.

Deno éretlen ökoszisztémája azonban átgondolásra késztetheti. Ha mégis a migráció mellett dönt, alaposan mérlegelje az előnyöket és hátrányokat.