Запознайте се с този ориентиран към сигурността JS runtime с практически примерен проект.

Deno е среда за изпълнение на JavaScript, изградена на V8, същата JavaScript машина, която захранва Google Chrome. Първоначалният създател на Node.js създаде Deno, за да се справи с някои от недостатъците и опасенията за сигурността на Node.js.

Въпреки че е сравнително нов, Deno придоби популярност като сигурно и модерно време за изпълнение на JavaScript. Фокусът му върху сигурността, поддръжката на модерни езикови функции и лесните за разработчици инструменти го правят привлекателен избор. Можете да го използвате за създаване на сървърни приложения, инструменти за команден ред и други JavaScript/TypeScript проекти, като прост API.

Инсталиране на Deno

Преди да можете да използвате Deno, трябва да го изтеглите и инсталирате. Инсталацията на Deno варира в зависимост от вашата операционна система.

В macOS и Linux можете да инсталирате Deno, като изпълните тази команда:

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

В Windows можете да инсталирате Deno с Powershell, като използвате тази команда:

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

Можете да потвърдите, че вашата инсталация е била успешна, като изпълните командата по-долу:

deno --version

Горната команда трябва да отпечата версията Deno на конзолата.

Ако използвате VS Code като IDE, можете да изтеглите Разширението на Deno VS Code за да добавите IntelliSense, подобрявайки вашата производителност и опит в разработката, когато работите с проекти на Deno.

След като инсталирате успешно разширението, създайте a .vscode папка в главната директория на вашия проект и създайте a settings.json файл в него.

След това добавете кодовия блок по-долу към settings.json файл за активиране на IntelliSense:

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

Свързване към база данни

За този урок ще използвате MongoDB като база данни, за да съхранявате данни от вашия API.

За да свържете вашето приложение Deno към база данни MongoDB, създайте a db.js файл в основната директория на вашия проект и добавете кодовия блок по-долу към него:

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

За разлика от Node.js, който зависи от мениджъри на пакети подобно на Node Package Manager (npm) или yarn, Deno има вградена система за управление на пакети за импортиране и управление на зависимости директно от URL адреси.

Например кодовият блок по-горе импортира MongoClient от URL адреса https://deno.land/x/[email protected]/mod.ts, което води до пакета.

След това, използвайки импортирания драйвер Deno MongoDB (MongoClient), Deno установява връзка между вашето приложение и локална база данни MongoDB.

В сценарии на живо е по-сигурно да съхранявате идентификационните данни на вашата база данни в .env вместо да ги съхранявате в обикновен текст, както е направено по-горе.

Създаване на модел на база данни

Докато е възможно да се взаимодействат с база данни MongoDB без модел на база данни, това може да доведе до неструктуриран и по-малко поддържаем код.

За да избегнете това, създайте a TodoModel.ts файл в главната директория на вашия проект и структурирайте данните си, като добавите кодовия блок по-долу към файла:

import db from"./db.ts";

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

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

exportdefault Todo;

Кодовият блок по-горе дефинира интерфейс Да направя който представлява структурата на един елемент от задачата. След това, използвайки интерфейса Todo, той създава колекция Todo, като извиква метода за събиране, изложен от вашия предварително създаден екземпляр на MongoDB.

Създаване на сървър с Oak

Oak е междинен софтуер за родния HTTP сървър на Deno. Той е вдъхновен от Koa, който е алтернатива на Express.js.

За да създадете сървър с Oak, създайте a main.ts файл в основната директория на вашия проект и добавете кодовия блок по-долу към вашия файл.

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

Кодовият блок по-горе импортира Приложение от URL адреса на Oak и създава екземпляр на приложение (ап), който слуша за входящ трафик на порт 8000.

The app.use (router.routes()) линия регистрира маршрутите на рутера като междинен софтуер в приложението Oak. Това означава, че приложението ще съпостави регистрираните маршрути с входящите заявки и съответните манипулатори ще се изпълняват, ако съществува съвпадение.

The app.use (router.allowedMethods()) линия обработва HTTP методи, които не са изрично дефинирани в рутера. Например, ако получи заявка с неподдържан метод, например нерегистрирана PUT заявка, разрешени методи () междинният софтуер автоматично ще изпрати подходящ отговор (напр. 405 Методът не е разрешен).

Внедряване на CRUD функционалност

Този урок ще включва прост API за задачи с функционалност CRUD.

Създавам router.ts файл в основната директория на вашия проект и добавете кодовия блок по-долу към вашия файл:

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

Кодовият блок по-горе импортира и създава екземпляр на рутера Oak. Използвайки този екземпляр, можете да създадете манипулатори на маршрути за различни HTTP методи, като извикате имената на съответните методи (получавам, пост, слагам, Изтрий).

Например кодовият блок по-долу е пример за това как можете да създадете манипулатор на GET маршрут, който връща всички документи във вашата Todo колекция.

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

За да изпратите обект на отговор с помощта на Deno, трябва да присвоите отговор.тяло обект на RouterContex към обекта за отговор. Същото важи и за кодовете за състояние.

За да добавите други манипулатори на маршрути, можете да ги свържете към предишния манипулатор на маршрути.

Така:

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

Кодовият блок по-горе дефинира GET манипулатор на маршрут, който връща единичен Todo елемент, който съответства на идентификатора в URL параметрите.

След това дефинирайте CREATE манипулатор на маршрут, който добавя нови документи към вашата колекция:

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

След това добавете PUT манипулатор на маршрут, който актуализира Todo въз основа на документ за самоличност параметър, с данните, изпратени в тялото на заявката.

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

И накрая, създайте манипулатор на маршрут DELETE, който премахва Todo от вашата MongoDB колекция:

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

Можете да стартирате вашето приложение Deno с тази команда:

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

По подразбиране скриптът на Deno не може да има достъп до нищо извън своя обхват, като например мрежата или файловата система. Така че, за да стартирате вашето приложение, трябва да включите различни флагове, за да предоставите на Deno необходимите разрешения.

--allow-net позволява на Deno да прави мрежови заявки. --разрешаване-четене позволява на Deno достъп до файловата система и четене на файлове. --allow-env позволява на Deno достъп до променливи на средата. The --гледам флаг стартира вашето приложение Deno в режим на гледане.

Мигриране от Node.js към Deno

Мигрирането от Node.js към Deno за изграждане на REST API може да донесе значителни ползи за сигурността, продуктивността на разработчиците и управлението на зависимостите. Използвайки защитеното време за изпълнение на Deno, родната поддръжка на TypeScript и опростеното управление на зависимостите, можете лесно да създавате стабилни и ефективни REST API.

Незрялата екосистема на Deno обаче може да ви накара да преразгледате. Ако решите да мигрирате, претеглете внимателно плюсовете и минусите.