Lær denne sikkerhedsfokuserede JS-runtime at kende med et praktisk eksempelprojekt.

Deno er en JavaScript-runtime bygget på V8, den samme JavaScript-motor, der driver Google Chrome. Den oprindelige skaber af Node.js skabte Deno for at løse nogle af manglerne og sikkerhedsproblemerne ved Node.js.

Selvom det er relativt nyt, har Deno vundet popularitet som en sikker og moderne JavaScript-runtime. Dens fokus på sikkerhed, understøttelse af moderne sprogfunktioner og udviklervenlige værktøjer gør det til et tiltalende valg. Du kan bruge det til at bygge server-side-applikationer, kommandolinjeværktøjer og andre JavaScript/TypeScript-projekter, som en simpel API.

Installerer Deno

Før du kan bruge Deno, skal du downloade og installere den. Denos installation varierer afhængigt af dit operativsystem.

På macOS og Linux kan du installere Deno ved at køre denne kommando:

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

På Windows kan du installere Deno med Powershell ved at bruge denne kommando:

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

Du kan bekræfte, at din installation var vellykket ved at køre kommandoen nedenfor:

deno --version

Kommandoen ovenfor skal udskrive Deno-versionen til konsollen.

Hvis du bruger VS-kode som en IDE, kan du downloade Deno's VS Code-udvidelse at tilføje IntelliSense, hvilket forbedrer din produktivitet og udviklingsoplevelse, når du arbejder med Deno-projekter.

Når du har installeret udvidelsen, skal du oprette en .vscode mappe i dit projekts rodmappe og opret en settings.json fil i den.

Tilføj derefter kodeblokken nedenfor til settings.json fil for at aktivere IntelliSense:

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

Tilslutning til en database

Til denne tutorial skal du bruge MongoDB som en database til at bevare data fra din API.

For at forbinde din Deno-app til en MongoDB-database skal du oprette en db.js fil i dit projekts rodbibliotek og tilføj kodeblokken nedenfor til den:

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

I modsætning til Node.js, som afhænger af pakkeansvarlige ligesom Node Package Manager (npm) eller garn, har Deno et indbygget pakkehåndteringssystem til at importere og administrere afhængigheder direkte fra URL'er.

For eksempel importerer kodeblokken ovenfor MongoClient fra URL'en https://deno.land/x/[email protected]/mod.ts, som fører til pakken.

Brug derefter den importerede Deno MongoDB-driver (MongoClient), Deno etablerer en forbindelse mellem din applikation og en lokal MongoDB-database.

I live-scenarier er det mere sikkert at gemme dine databaselegitimationsoplysninger i en .env fil i stedet for at gemme dem i almindelig tekst, som gjort ovenfor.

Oprettelse af en databasemodel

Mens det er muligt at interagere med en MongoDB-database uden en databasemodel kan det føre til ustruktureret og mindre vedligeholdelsesvenlig kode.

For at undgå dette skal du oprette en TodoModel.ts fil i dit projekts rodmappe og strukturer dine data ved at tilføje kodeblokken nedenfor til filen:

import db from"./db.ts";

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

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

exportdefault Todo;

Kodeblokken ovenfor definerer en grænseflade At gøre der repræsenterer strukturen af ​​et enkelt gøremål. Ved hjælp af Todo-grænsefladen opretter den en Todo-samling ved at kalde indsamlingsmetoden, der er afsløret af din tidligere oprettede MongoDB-instans.

Oprettelse af en server med eg

Oak er en middleware til Denos native HTTP-server. Den var inspireret af Koa, som er en alternativ til Express.js.

For at oprette en server med Oak skal du oprette en main.ts fil i dit projekts rodbibliotek og tilføj kodeblokken nedenfor til din fil.

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

Kodeblokken ovenfor importerer Ansøgning fra Oak URL og opretter en applikationsforekomst (app), der lytter efter indgående trafik på port 8000.

Det app.use (router.routes()) line registrerer routerens ruter som middleware i Oak-applikationen. Det betyder, at applikationen vil matche de registrerede ruter mod indgående anmodninger, og de tilsvarende behandlere vil køre, hvis der findes et match.

Det app.use (router.allowedMethods()) line håndterer HTTP-metoder, der ikke er eksplicit defineret i routeren. For eksempel, hvis den modtager en anmodning med en ikke-understøttet metode, for eksempel en uregistreret PUT-anmodning, tilladte metoder() middleware sender automatisk et passende svar (f.eks. 405 Metode ikke tilladt).

Implementering af CRUD-funktionalitet

Denne tutorial vil indeholde en simpel todo-API med CRUD-funktionalitet.

Lave en router.ts fil i dit projekts rodmappe og tilføj kodeblokken nedenfor til din fil:

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

Kodeblokken ovenfor importerer og opretter en forekomst af Oak-routeren. Ved at bruge denne instans kan du oprette rutebehandlere til forskellige HTTP-metoder ved at kalde de respektive metodenavne (, stolpe, sætte, slette).

For eksempel er kodeblokken nedenfor et eksempel på, hvordan du kan oprette en GET-rutehandler, der returnerer alle dokumenterne i din Todo-samling.

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

For at sende et svarobjekt ved hjælp af Deno, skal du tildele respons.body objekt på RouterContex til svarobjektet. Det samme gælder for statuskoder.

For at tilføje andre rutehandlere kan du kæde dem til den forrige rutehandler.

Ligesom:

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

Kodeblokken ovenfor definerer en GET-rutehandler, der returnerer et enkelt Todo-element, der matcher id'et i URL-parametrene.

Derefter skal du definere en CREATE-rutehandler, der tilføjer nye dokumenter til din samling:

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

Tilføj derefter en PUT-rutehandler, der opdaterer en Todo baseret på id parameter, med de data, der sendes i anmodningsteksten.

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

Til sidst skal du oprette en DELETE-rutehandler, der fjerner en Todo fra din MongoDB-samling:

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

Du kan starte din Deno-app med denne kommando:

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

Som standard kan et Deno-script ikke få adgang til noget uden for dets omfang, såsom netværket eller filsystemet. Så for at starte din ansøgning skal du inkludere forskellige flag for at give Deno de nødvendige tilladelser.

--allow-net giver Deno mulighed for at lave netværksanmodninger. -- tillad-læse giver Deno adgang til filsystemet og læser filer. --allow-env giver Deno adgang til miljøvariabler. Det --holde øje flag starter din Deno-app i urtilstand.

Migrering fra Node.js til Deno

Migrering fra Node.js til Deno for at bygge REST API'er kan give betydelige fordele for sikkerhed, udviklerproduktivitet og afhængighedsstyring. Ved at bruge Denos sikre runtime, native TypeScript-understøttelse og forenklede afhængighedsstyring kan du nemt oprette robuste og effektive REST API'er.

Denos umodne økosystem kan dog få dig til at genoverveje. Hvis du vælger at migrere, skal du afveje fordele og ulemper omhyggeligt.