Guten Tag, Freunde!
Ich präsentiere Ihnen die Übersetzung des Artikels "Das Deno-Handbuch: Ein TypeScript-Laufzeit-Tutorial mit Codebeispielen" von Flavio Copes.
In diesem Artikel lernen wir, wie man mit Deno arbeitet. Wir werden es mit Node.js vergleichen und damit eine einfache REST-API erstellen.
Was ist Deno?
Wenn Sie mit Node.js, dem beliebten serverseitigen JavaScript-Ökosystem, vertraut sind, ist Deno so ziemlich dasselbe. Fast, aber nicht ganz.
Beginnen wir mit einer Liste von Deno-Funktionen, die mir am besten gefallen:
- Es basiert auf modernem JavaScript
- Es verfügt über eine erweiterbare Standardbibliothek
- Es bietet standardmäßige TypeScript-Unterstützung (dies bedeutet, dass Sie TypeScript nicht manuell kompilieren müssen, Deno erledigt dies automatisch).
- Es unterstützt ES-Module
- Es gibt keinen Paketmanager
- Es hat eine globale
await
- Es verfügt über eine eingebaute Testeinrichtung
- Das Ziel ist maximale Browserkompatibilität. Hierzu werden ein Inline-
fetch
und ein globales Objekt bereitgestelltwindow
In diesem Tutorial werden wir all diese Möglichkeiten untersuchen.
Nachdem Sie sich mit Deno und seinen Funktionen vertraut gemacht haben, wird Node.js etwas veraltet erscheinen.
Zumal Node.js auf Rückruffunktionen basiert (es wurde vor Versprechungen und async / await geschrieben). Es ist unwahrscheinlich, dass sie jemals dort erscheinen, da dies bedeutet, dass grundlegende Änderungen erforderlich sind.
Node.js ist großartig und wird der De-facto-Standard in der JavaScript-Welt bleiben. Ich glaube jedoch, dass Deno dank seiner TypeScript-Unterstützung und der modernen Standardbibliothek schnell an Popularität gewinnen wird.
Deno kann sich modernen Code leisten, da er keine Abwärtskompatibilität benötigt. Natürlich gibt es keine Garantie dafür, dass dieser Code im nächsten Jahrzehnt auf dem neuesten Stand bleibt, aber heute ist es so.
Warum Deno? Warum jetzt?
Deno wurde vor fast 2 Jahren von Node.js Schöpfer Ryan Dahl auf der JSConf EU angekündigt. Sehen Sie sich das YouTube-Video an , es ist sehr interessant und ein Muss, wenn Sie mit Node.js und JavaScript arbeiten.
Jeder Projektmanager (Ersteller) ist gezwungen, Entscheidungen zu treffen. Ryan bedauert einige der frühen Entscheidungen in Node. Darüber hinaus schreitet die Technologie voran und JavaScript ist heute eine völlig andere Sprache als 2009, als Node. Denken Sie an ES6 / 2016/2017 und so weiter zurück.
Also beschloss er, ein neues Projekt zu starten, eine Art zweite Welle serverseitiger JavaScript-Anwendungen.
Der Grund, warum ich diesen Artikel jetzt nur schreibe, ist, dass es ziemlich lange dauert, bis die Technologie ausgereift ist. Schließlich haben wir Deno 1.0 (es wurde am 13. Mai 2020 veröffentlicht), die erste stabile Version.
Dies mag wie eine übliche Zahl erscheinen, aber 1.0 bedeutet, dass es bis Deno 2.0 keine drastischen Änderungen geben wird. Wenn Sie neue Technologien erlernen, möchten Sie nicht, dass sie sich zu schnell ändern.
Solltest du Deno lernen?
Gute Frage.
Etwas Neues wie Deno zu lernen erfordert viel Mühe. Mein Rat: Wenn Sie gerade erst mit serverseitigem JS beginnen und Node.js noch nicht kennen und noch nie TypeScript geschrieben haben, beginnen Sie mit Node.
Bisher wurde noch niemand entlassen, weil er sich für Node entschieden hat (um ein berühmtes Zitat zu paraphrasieren).
Aber wenn Sie TypeScript mögen, das nicht von einer
await
Menge npm-Paketen abhängt und es überall verwenden möchte, ist Deno möglicherweise das, wonach Sie suchen.
Wird es Node.js ersetzen?
Nein. Node.js ist ein Riese, eine große Autorität, eine unglaublich gut unterstützte Technologie, die in den nächsten zehn Jahren nirgendwo hingehen wird.
Erstklassige TypeScript-Unterstützung
Deno ist in Rust und TypeScript geschrieben, beides sehr beliebte Sprachen in der heutigen Welt.
Dies bedeutet, dass TypeScript viele Vorteile bietet, selbst wenn wir JavaScript schreiben.
Das Ausführen von TypeScript-Code mit Deno erfordert keine Vorkompilierung - Deno führt dies automatisch durch.
Sie müssen keinen TypeScript-Code schreiben, aber die Tatsache, dass Denos Kern in TypeScript geschrieben ist, macht einen großen Unterschied.
Erstens liebt ein großer Prozentsatz der JavaScript-Entwickler TypeScript.
Zweitens können die von Ihnen verwendeten Tools viele Informationen über TypeScript-Software wie Deno erhalten.
Dies bedeutet, dass wir beispielsweise beim Schreiben von Code in VS-Code (der seit seiner Einführung eng in TypeScript integriert ist) Vorteile wie die Typprüfung beim Schreiben von Code oder erweiterte IntelliSense-Funktionen erhalten. Mit anderen Worten, die Hilfe des Code-Editors wird viel effizienter.
Unterschiede zu Node.js.
Da Deno im Wesentlichen ein Ersatz für Node.js ist, ist es sinnvoll, die beiden zu vergleichen.
Allgemeines:
- Beide basieren auf dem V8-Motor
- Beide eignen sich hervorragend für die serverseitige JavaScript-Entwicklung
Unterschiede:
- Der Knoten ist in C ++ und JavaScript geschrieben. Deno ist in Rust und TypeScript geschrieben.
- Node hat einen offiziellen Paketmanager
npm
. Deno hat keinen solchen Manager, stattdessen können Sie jedes Modul über eine URL importieren. - Der Knoten verwendet die CommonJS-Syntax zum Importieren von Paketen. Deno verwendet den offiziellen Weg - ES-Module.
- Deno ECMAScript , Node.js .
- Deno () . . Node.js , .
- Deno , .. , , Go, . .
Das Fehlen eines Paketmanagers und die Verwendung einer URL zum Abrufen und Importieren von Paketen hat Vor- und Nachteile. Einer der Hauptvorteile ist die große Flexibilität, die mit der Möglichkeit verbunden ist, Pakete zu erstellen, ohne sie in einem Repository wie npm veröffentlichen zu müssen.
Ich denke, dass früher oder später eine Alternative zum Paketmanager in Deno auftauchen wird.
Auf der offiziellen Deno-Website werden Pakete von Drittanbietern gehostet: https://deno.land/x/
Deno installieren
Genug geredet! Lassen Sie uns Deno installieren.
Der einfachste Weg, dies zu tun, ist die Verwendung von Homebrew:
brew install deno
Andere Installationsmethoden sind hier aufgelistet .
Nach der Installation wird der Befehl verfügbar
deno
. Hier ist die Hilfe, die Sie durch Eingabe erhalten können deno --help
:
flavio@mbp~> deno --help
deno 0.42.0
A secure JavaScript and TypeScript runtime
Docs: https://deno.land/std/manual.md
Modules: https://deno.land/std/ https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
To start the REPL, supply no arguments:
deno
To execute a script:
deno run https://deno.land/std/examples/welcome.ts
deno https://deno.land/std/examples/welcome.ts
To evaluate code in the shell:
deno eval "console.log(30933 + 404)"
Run 'deno help run' for 'run'-specific flags.
USAGE:
deno [OPTIONS] [SUBCOMMAND]
OPTIONS:
-h, --help
Prints help information
-L, --log-level <log-level>
Set log level [possible values: debug, info]
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-V, --version
Prints version information
SUBCOMMANDS:
bundle Bundle module and dependencies into single file
cache Cache the dependencies
completions Generate shell completions
doc Show documentation for a module
eval Eval script
fmt Format source files
help Prints this message or the help of the given subcommand(s)
info Show info about cache or info related to source file
install Install script as an executable
repl Read Eval Print Loop
run Run a program given a filename or url to the module
test Run tests
types Print runtime TypeScript declarations
upgrade Upgrade deno executable to newest version
ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory (defaults to $HOME/.deno)
DENO_INSTALL_ROOT Set deno install's output directory
(defaults to $HOME/.deno/bin)
NO_COLOR Set to disable color
HTTP_PROXY Proxy address for HTTP requests
(module downloads, fetch)
HTTPS_PROXY Same but for HTTPS
Deno-Teams
Haben Sie den Abschnitt bemerkt
SUBCOMMANDS
? Dies ist eine Liste aller Befehle, die wir ausführen können. Welche Teams haben wir?
bundle
- sammelt die Modul- und Projektabhängigkeiten in einer Dateicache
- Abhängigkeiten zwischenspeicherncompletions
- erzeugt Shell-Nachfüllungendoc
- zeigt die Dokumentation zum Moduleval
- wird zum Beispiel zum Berechnen eines Codeblocks verwendetdeno eval "console.log(1 + 2)"
fmt
- eingebauter Code-Formatierer (wiegoFmt
in Go)help
- Zeigt eine Liste der Hilfsbefehle aninfo
- Zeigt Informationen zum Cache oder zur Datei aninstall
- Setzt das Skript als ausführbarrepl
- Lese-Rechen-Ausgabe-Zyklus (Standard)run
- führt das Programm mit dem angegebenen Namen oder der angegebenen URL für das Modul austest
- führt Tests durchtypes
- Zeigt eine Liste der TypeScript-Funktionen anupgrade
- aktualisiert Deno auf die neueste Version
Sie können beispielsweise ausführen
deno <subcommand> help
, um Informationen zu einem bestimmten Befehl abzurufen deno run --help
.
Wir können einen Befehl verwenden
deno
, um eine Lese-Auswertungs-Ausgabeschleife zu starten:
Dies ist dasselbe wie das Starten
deno repl
.
Typischerweise
deno
verwendet in einer Typoskript Datei enthielt eine Deno Anwendung zu starten.
Sie können sowohl TypeScript-Dateien (.ts) als auch JavaScript-Dateien (.js) ausführen.
Wenn Sie mit TypeScript nicht vertraut sind, machen Sie sich keine Sorgen: Deno ist in TypeScript geschrieben, aber Sie können Ihre Clientanwendungen in JavaScript schreiben.
Erste App auf Deno
Lassen Sie uns unsere erste Anwendung erstellen.
Dazu müssen wir nicht einmal Code schreiben, sondern führen ihn im Terminal unter Verwendung der URL aus.
Deno lädt das Programm herunter, kompiliert es und führt es aus:
Natürlich würde ich nicht empfehlen, zufälligen Code aus dem Internet auszuführen. In diesem Fall starten wir es von der offiziellen Deno-Website, und Deno verfügt über eine Sandbox, die verhindert, dass Programme das tun, was wir ihnen nicht ausdrücklich erlaubt haben.
Dieses Programm ist sehr einfach und ein Aufruf
console.log()
:
console.log('Welcome to Deno ') // ,
Wenn Sie https://deno.land/std/examples/welcome.ts in einem Browser öffnen , wird Folgendes angezeigt:
Seltsam, nicht wahr? Sie haben wahrscheinlich erwartet, eine TypeScript-Datei zu sehen, haben aber stattdessen eine Webseite erhalten. Der Punkt ist, dass der Deno-Website-Server weiß, dass Sie einen Browser verwenden, und Ihnen eine benutzerfreundlichere Seite bietet.
Laden Sie zum Beispiel dieselbe URL mit
wget
und erhalten Sie text/plain
stattdessen text/html
:
Wenn Sie das Programm neu starten, ist dank Caching kein Neustart erforderlich: Ein erzwungener Neustart kann
mit dem Flag durchgeführt werden
--reload
:
deno run
hat viele verschiedene Funktionen, die von nicht angezeigt werden deno --help
. Um sie zu sehen, sollten Sie Folgendes ausführen deno run --help
:
flavio@mbp~> deno run --help
deno-run
Run a program given a filename or url to the module.
By default all programs are run in sandbox without access to disk, network or
ability to spawn subprocesses.
deno run https://deno.land/std/examples/welcome.ts
Grant all permissions:
deno run -A https://deno.land/std/http/file_server.ts
Grant permission to read from disk and listen to network:
deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts
Grant permission to read whitelisted files from disk:
deno run --allow-read=/etc https://deno.land/std/http/file_server.ts
USAGE:
deno run [OPTIONS] <SCRIPT_ARG>...
OPTIONS:
-A, --allow-all
Allow all permissions
--allow-env
Allow environment access
--allow-hrtime
Allow high resolution time measurement
--allow-net=<allow-net>
Allow network access
--allow-plugin
Allow loading plugins
--allow-read=<allow-read>
Allow file system read access
--allow-run
Allow running subprocesses
--allow-write=<allow-write>
Allow file system write access
--cached-only
Require that remote dependencies are already cached
--cert <FILE>
Load certificate authority from PEM encoded file
-c, --config <FILE>
Load tsconfig.json configuration file
-h, --help
Prints help information
--importmap <FILE>
UNSTABLE:
Load import map file
Docs: https://deno.land/std/manual.md#import-maps
Specification: https://wicg.github.io/import-maps/
Examples: https://github.com/WICG/import-maps#the-import-map
--inspect=<HOST:PORT>
activate inspector on host:port (default: 127.0.0.1:9229)
--inspect-brk=<HOST:PORT>
activate inspector on host:port and break at start of user script
--lock <FILE>
Check the specified lock file
--lock-write
Write lock file. Use with --lock.
-L, --log-level <log-level>
Set log level [possible values: debug, info]
--no-remote
Do not resolve remote modules
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-r, --reload=<CACHE_BLACKLIST>
Reload source code cache (recompile TypeScript)
--reload
Reload everything
--reload=https://deno.land/std
Reload only standard modules
--reload=https://deno.land/std/fs/utils.ts,https://deno.land/std/fmt/colors.ts
Reloads specific modules
--seed <NUMBER>
Seed Math.random()
--unstable
Enable unstable APIs
--v8-flags=<v8-flags>
Set V8 command line options. For help: --v8-flags=--help
ARGS:
<SCRIPT_ARG>...
script args
Codebeispiele
Es gibt andere Beispiele auf der Deno-Website, die hier zu finden sind .
Zum Zeitpunkt dieses Schreibens befand sich im angegebenen Repository Folgendes:
cat.ts
- Zeigt den Inhalt von Dateien an, die als Argumente übergeben wurdencatj.ts
- macht dasselbe, führtcat.ts
aber zuerst einige Manipulationen mit dem Inhalt der Dateien durchchat/
- Chat-Implementierungcolors.ts
- Ein Beispiel für das Stylen von Text mithilfe von Modulencurl.ts
- Eine einfache Implementierungcurl
, die den Inhalt der als Argument übergebenen URL ausgibtecho_server.ts
- TCP-Echoservergist.ts
- Programm zum Platzieren von Dateien in gist.github.comtest.ts
- Testprogrammwelcome.ts
- das Programm, das wir gestartet habenxeval.ts
- Ermöglicht die Ausführung von TypeScript aus einer beliebigen Standarddatenquelle.deno xeval
wurde von der Liste der offiziellen Teams entfernt
Erste echte App auf Deno
Schreiben wir einen Code.
Die erste App, mit der wir gestartet sind,
deno run https://deno.land/std/examples/welcome.ts
wurde bereits geschrieben, sodass Sie nichts Neues über Deno erfahren haben.
Beginnen wir mit einem Standardbeispiel auf der Deno-Website:
import { serve } from 'https://deno.land/std/http/server.ts'
const s = serve({ port: 8000 })
console.log('http://localhost:8000/')
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
Hier importieren wir eine Funktion
serve
aus einem Modul http/server
. Sehen? Wir mussten es nicht installieren und es ist nicht wie Node-Module auf unserem Computer gespeichert. Dies ist einer der Gründe für die schnelle Installation von Deno.
Mit Hilfe
https://deno.land/std/http/server.ts
importieren wir die neueste Version des Moduls. Eine bestimmte Version kann importiert werden mit @VERSION
:
import { serve } from 'https://deno.land/std@v0.42.0/http/server.ts'
Dies ist, was die Funktion ist
serve
:
/**
* Create a HTTP server
*
* import { serve } from "https://deno.land/std/http/server.ts";
* const body = "Hello World\n";
* const s = serve({ port: 8000 });
* for await (const req of s) {
* req.respond({ body });
* }
*/
export function serve(addr: string | HTTPOptions): Server {
if (typeof addr === 'string') {
const [hostname, port] = addr.split(':')
addr = { hostname, port: Number(port) }
}
const listener = listen(addr)
return new Server(listener)
}
Als nächstes rufen wir die Funktion auf
serve()
und übergeben ihr ein Objekt mit einer Eigenschaft port
.
Wir führen dann eine Schleife aus, um auf jede Anfrage vom Server zu antworten:
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
Beachten Sie, dass wir das Schlüsselwort verwenden,
await
ohne den Code in eine async
Funktion einzuschließen.
Lassen Sie uns das Programm lokal ausführen. Ich verwende VS-Code, aber Sie können jeden Editor verwenden.
Ich empfehle die Installation einer Erweiterung von justjavac (es gibt eine andere mit einem ähnlichen Namen, die jedoch veraltet ist und möglicherweise in Zukunft verschwindet): Die
Erweiterung bietet verschiedene Dienstprogramme, mit denen Sie Deno-Anwendungen schreiben können.
Lassen Sie uns eine Datei erstellen
app.ts
und unseren Code einfügen:
Führen Sie ihn aus mit
deno run app.ts
:
Deno lädt alle Abhängigkeiten, die das Programm benötigt, aber zuerst die, die wir in die Datei importieren.
Die Datei https://deno.land/std/http/server.ts weist mehrere eigene Abhängigkeiten auf:
import { encode } from '../encoding/utf8.ts'
import { BufReader, BufWriter } from '../io/bufio.ts'
import { assert } from '../testing/asserts.ts'
import { deferred, Deferred, MuxAsyncIterator } from '../async/mod.ts'
import {
bodyReader,
chunkedBodyReader,
emptyReader,
writeResponse,
readRequest,
} from './_io.ts'
import Listener = Deno.Listener
import Conn = Deno.Conn
import Reader = Deno.Reader
Diese Abhängigkeiten werden automatisch importiert.
Am Ende haben wir ein Problem:
Was ist los? Wir haben eine Erlaubnis verweigert Fehler.
Reden wir über den Sandkasten.
Sandkasten
Wie bereits erwähnt, verfügt Deno über eine Sandbox, die verhindert, dass Programme Dinge tun, für die sie nicht autorisiert wurden.
Was bedeutet das?
Wie Ryan in seinem Vortrag sagt, möchten Sie manchmal ein JavaScript-Programm außerhalb des Browsers ausführen, und Sie möchten nicht, dass das Programm auf alles auf Ihrem System zugreifen kann. Oder wenn es um die Nutzung des Netzwerks nach außen geht.
Nichts hindert die Anwendung Node.js daran, Ihren SSH-Schlüssel oder andere Informationen von Ihrem System abzurufen und an den Server zu senden. Aus diesem Grund installieren wir normalerweise nur Node-Pakete aus vertrauenswürdigen Quellen. Aber woher wissen wir, ob eines der von uns verwendeten Projekte gehackt wurde?
Deno ahmt das vom Browser verwendete Berechtigungssystem nach. JavaScript-Code, der in einem Browser ausgeführt wird, kann nichts mit Ihrem System tun, es sei denn, Sie erlauben dies ausdrücklich.
Zurück zu Deno: Wenn ein Programm Netzwerkzugriff benötigt, müssen wir ihm die Erlaubnis dazu erteilen.
Dies geschieht mit dem Flag
--allow-net
:
deno run --allow-net app.ts
Der Server läuft jetzt auf Port 8000:
Andere Flags:
--allow-env
- Ermöglicht den Zugriff auf Umgebungsvariablen--allow-hrtime
- ermöglicht hochauflösende Messungen--allow-net=<allow-net>
- Ermöglicht den Zugriff auf das Netzwerk--allow-plugin
- Ermöglicht das Laden von Plugins--allow-read=<allow-read>
- Ermöglicht das Lesen von Dateien--allow-run
- Ermöglicht das Starten von Unterprozessen--allow-write=<allow-write>
- Ermöglicht das Schreiben von Dateien--allow-all
- erteilt alle Berechtigungen (ähnlich-A
)
Berechtigungen für
net
, read
und write
können teilweise sein. Beispielsweise können wir schreibgeschützte Dateien zulassen, die sich in einem bestimmten Verzeichnis befinden : --allow-read=/dev
.
Code-Formatierung
Eines der Dinge, die ich an Go liebe, ist der Befehl
gofmt
. Der gesamte Go-Code sieht gleich aus. Jeder benutzt es gofmt
.
JavaScript-Entwickler verwenden normalerweise Prettier und
deno fmt
tatsächlich auch unter dem Schnitt.
Angenommen, Sie haben eine so schlecht formatierte Datei:
Sie starten
deno fmt app.ts
und die automatische Formatierung erfolgt mit fehlenden Semikolons:
Standardbibliothek
Die Standardbibliothek von Deno ist trotz des Alters des Projekts ziemlich umfangreich.
Es enthält Folgendes:
archieve
- Dienstprogramme zur Archivierungasync
- Dienstprogramme für die Arbeit mit asynchronem Codebytes
- Hilfsfunktionen zum Aufteilen von Bytesdatetime
- Analysieren von Daten / Zeitenencoding
- Kodierung / Dekodierung in verschiedenen Formatenflags
- Parsing von Befehlszeilenflagsfmt
- Bildung und Anzeigefs
- Anwendungsschnittstelle für die Arbeit mit dem Dateisystemhash
- Verschlüsselungsbibliothekhttp
- HTTP-Serverio
- Bibliothek von Eingabe- / Ausgabeoperationenlog
- Dienstprogramme für die Protokollierungmime
- Unterstützung gemischter Datennode
- Abwärtskompatibilitätsschicht mit Knotenpath
- mit Pfaden arbeitenws
- Web-Sockets
Noch ein Beispiel
Schauen wir uns ein anderes offizielles Beispiel an
cat.ts
:
const filenames = Deno.args
for (const filename of filenames) {
const file = await Deno.open(filename)
await Deno.copy(file, Deno.stdout)
file.close()
}
Wir weisen einer Variablen
filenames
Inhalt zu. Dies Deno.args
ist eine Variable, die die über die Befehlszeile übergebenen Argumente enthält.
Wir iterieren über sie und verwenden sie jeweils
Deno.open()
zum Öffnen der Datei und zum Deno.copy()
Kopieren des Inhalts Deno.stdout
. Zum Schluss schließen wir die Datei.
Wenn du läufst:
deno run https://deno.land/std/examples/cat.ts
Das Programm wird geladen und kompiliert, aber es passiert nichts, da wir keine Argumente übergeben haben.
Versuchen wir Folgendes:
deno run https://deno.land/std/examples/cat.ts app.ts
Wir
erhalten einen Berechtigungsfehler: Deno hat standardmäßig keinen Zugriff auf das System. Erteilen wir ihm diese Erlaubnis mit
--allow-read
:
deno run --allow-read=./ https://deno.land/std/examples/cat.ts app.ts
Gibt es Express / Hapi / Koa / * für Deno?
Ja natürlich. Schauen Sie sich folgende Projekte an:
Beispiel: Verwenden von Oak zum Erstellen einer REST-API
Ich werde eine REST-API mit Oak erstellen. Oak ist insofern interessant, als es von Koa, einer beliebten Middleware für NOde.js, inspiriert ist und eine ähnliche Syntax aufweist.
Unsere API wird sehr einfach sein.
Unser Server speichert eine Liste der Hunde, deren Namen und Alter.
Wir möchten folgende Funktionalität erhalten:
- füge neue Hunde zur Liste hinzu
- Holen Sie sich eine Liste aller Hunde
- Informationen über einen bestimmten Hund erhalten
- Entfernen Sie einen Hund von der Liste
- Aktualisieren Sie das Alter des Hundes
Wir werden den Code in Typescript schreiben, aber nichts hindert Sie daran, ihn in JavaScript auszuführen - geben Sie nur nicht die Datentypen an.
Wir erstellen eine Datei
app.ts
.
Beginnen wir mit dem Importieren von Objekten nach
Application
und Router
von Oak
:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
Wir erhalten die Umgebungsvariablen PORT und HOST:
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
Standardmäßig wird unsere Anwendung auf localhost ausgeführt: 4000.
Erstellen Sie eine Oak-Anwendung und starten Sie sie:
const router = new Router()
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
Die Anwendung sollte jetzt funktionieren.
Wir überprüfen:
deno run --allow-env --allow-net app.ts
Deno lädt Abhängigkeiten herunter:
und beginnt, Port 4000 abzuhören.
Beim Neustart wird der Installationsschritt dank Caching übersprungen:
Definieren Sie eine Schnittstelle für den Hund und definieren Sie dann ein Array,
dog
das die Objekte enthält Dog
:
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
Beginnen wir mit der Implementierung der API.
Alles ist an Ort und Stelle. Fügen wir dem Router mehrere Funktionen hinzu, die beim Zugriff auf den angegebenen Endpunkt aufgerufen werden:
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
Wir haben Folgendes definiert:
GET /dogs
GET /dogs/:name
POST /dogs
PUT /dogs/:name
DELETE /dogs/:name
Lassen Sie uns diese Routen einzeln implementieren.
Beginnen wir mit
GET /dogs
einer Liste aller Hunde:
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
So erhalten Sie einen bestimmten Hund mit Namen:
export const getDog = ({
params,
response,
}: {
params: {
name: string
},
response: any
}) => {
const dog = dogs.filter(dog => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
So fügen Sie der Liste einen neuen Hund hinzu:
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const dog: Dog = await body.value
dogs.push(dog)
response.body = { msg: 'OK' }
response.status = 200
}
So aktualisieren Sie das Alter Ihres Hundes:
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
},
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = await body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
Und so entfernen Sie einen Hund von der Liste:
export const removeDog = ({
params,
response,
}: {
params: {
name: string
},
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter((dog) => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}
Vollständiger Anwendungscode:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
export const getDog = ({
params,
response,
}: {
params: {
name: string
},
response: any
}) => {
const dog = dogs.filter(dog => dog.name === params.name)
if (dog.length) {
response.status = 200
response.body = dog[0]
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const addDog = async ({
request,
response,
}: {
request: any
response: any
}) => {
const body = await request.body()
const { name, age }: { name: string; age: number } = await body.value
dogs.push({
name: name,
age: age,
})
response.body = { msg: 'OK' }
response.status = 200
}
export const updateDog = async ({
params,
request,
response,
}: {
params: {
name: string
},
request: any
response: any
}) => {
const temp = dogs.filter((existingDog) => existingDog.name === params.name)
const body = await request.body()
const { age }: { age: number } = await body.value
if (temp.length) {
temp[0].age = age
response.status = 200
response.body = { msg: 'OK' }
return
}
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
}
export const removeDog = ({
params,
response,
}: {
params: {
name: string
},
response: any
}) => {
const lengthBefore = dogs.length
dogs = dogs.filter(dog => dog.name !== params.name)
if (dogs.length === lengthBefore) {
response.status = 400
response.body = { msg: `Cannot find dog ${params.name}` }
return
}
response.body = { msg: 'OK' }
response.status = 200
}
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
const app = new Application()
app.use(router.routes())
app.use(router.allowedMethods())
console.log(`Listening on port ${PORT}...`)
await app.listen(`${HOST}:${PORT}`)
Danke für die Aufmerksamkeit.