¡Buen dia amigos!
Les presento la traducción del artículo "The Deno Handbook: A TypeScript Runtime Tutorial with Code Examples" de Flavio Copes.
En este artículo, aprenderemos cómo trabajar con Deno. Lo compararemos con Node.js y crearemos una API REST simple con él.
¿Qué es Deno?
Si está familiarizado con Node.js, el popular ecosistema de JavaScript del lado del servidor, Deno es prácticamente lo mismo. Casi, pero no del todo.
Comencemos con una lista de las características de Deno que más me gustan:
- Está basado en JavaScript moderno.
- Tiene una biblioteca estándar extensible
- Tiene soporte estándar para TypeScript (esto significa que no tiene que compilar TypeScript manualmente, Deno lo hace automáticamente)
- Soporta módulos ES
- No tiene administrador de paquetes
- Tiene un global
await
- Tiene una instalación de prueba incorporada
- Su objetivo es la máxima compatibilidad con los navegadores. Para ello, proporciona un objeto en línea
fetch
y globalwindow
En este tutorial, exploraremos todas estas posibilidades.
Después de familiarizarse con Deno y sus capacidades, Node.js parecerá un poco anticuado.
Especialmente porque Node.js se basa en funciones de devolución de llamada (se escribió antes de promesas y async / await). Es poco probable que aparezcan allí alguna vez, ya que esto significa que se necesitan cambios fundamentales.
Node.js es excelente y seguirá siendo el estándar de facto en el mundo de JavaScript. Sin embargo, creo que Deno crecerá en popularidad rápidamente gracias a su compatibilidad con TypeScript y su biblioteca estándar moderna.
Deno puede permitirse un código moderno ya que no necesita compatibilidad con versiones anteriores. Por supuesto, no hay garantía de que este código se mantenga actualizado en la próxima década, pero hoy lo está.
¿Por qué Deno? ¿Porqué ahora?
Deno fue anunciado hace casi 2 años por el creador de Node.js, Ryan Dahl, en JSConf EU. Mire el video de YouTube , es muy interesante y debe verlo si está trabajando con Node.js y JavaScript.
Cada director de proyecto (creador) se ve obligado a tomar decisiones. Ryan lamenta algunas de las primeras decisiones en Node. Además, la tecnología está avanzando y JavaScript es un lenguaje completamente diferente hoy en día de lo que era en 2009 cuando Node. Piense en ES6 / 2016/2017 y así sucesivamente.
Así que decidió comenzar un nuevo proyecto, una especie de segunda ola de aplicaciones JavaScript del lado del servidor.
La razón por la que solo estoy escribiendo este artículo ahora es porque la tecnología tarda bastante en madurar. Finalmente, obtuvimos Deno 1.0 (se lanzó el 13 de mayo de 2020), la primera versión estable.
Este puede parecer un número común, pero 1.0 significa que no habrá cambios drásticos hasta Deno 2.0. A medida que aprenda nuevas tecnologías, no querrá que cambie demasiado rápido.
¿Deberías aprender Deno?
Buena pregunta.
Aprender algo nuevo como Deno requiere mucho esfuerzo. Mi consejo: si recién está comenzando con JS del lado del servidor y aún no conoce Node.js, y nunca antes ha escrito TypeScript, comience con Node.
Nadie ha sido despedido por elegir Node (parafraseando una cita famosa).
Pero si te gusta TypeScript, que no depende de una tonelada de paquetes npm, y quieres usarlo en todas partes
await
, Deno podría ser lo que estás buscando.
¿Reemplazará a Node.js?
No. Node.js es un gigante, una gran autoridad, una tecnología increíblemente bien respaldada que no irá a ninguna parte en la próxima década.
Compatibilidad con TypeScript de primera clase
Deno está escrito en Rust y TypeScript, ambos lenguajes muy populares en el mundo actual.
Esto significa que obtenemos muchos beneficios de TypeScript, incluso si estamos escribiendo JavaScript.
Ejecutar código TypeScript con Deno no requiere compilación previa; Deno lo hace automáticamente.
No tiene que escribir código TypeScript, pero el hecho de que el núcleo de Deno esté escrito en TypeScript marca una gran diferencia.
Primero, un gran porcentaje de desarrolladores de JavaScript aman TypeScript.
En segundo lugar, las herramientas que utiliza pueden obtener mucha información sobre software escrito en TypeScript como Deno.
Esto significa que cuando escribimos código en VS Code, por ejemplo (que tiene una estrecha integración con TypeScript desde su inicio), obtenemos beneficios como la verificación de tipos al escribir código o capacidades avanzadas de IntelliSense. En otras palabras, la ayuda del editor de código se vuelve mucho más eficiente.
Diferencias con Node.js
Dado que Deno es esencialmente un reemplazo de Node.js, tiene sentido comparar los dos.
General:
- Ambos se basan en el motor V8
- Ambos son excelentes para el desarrollo de JavaScript del lado del servidor
Diferencias:
- El nodo está escrito en C ++ y JavaScript. Deno está escrito en Rust y TypeScript.
- Node tiene un administrador de paquetes oficial
npm
. Deno no tiene tal administrador, en cambio le permite importar cualquier módulo usando una URL. - Node usa la sintaxis CommonJS para importar paquetes. Deno utiliza la forma oficial: módulos ES.
- Deno ECMAScript , Node.js .
- Deno () . . Node.js , .
- Deno , .. , , Go, . .
No tener un administrador de paquetes y usar una URL para obtener e importar paquetes tiene sus ventajas y desventajas. Una de las principales ventajas es la gran flexibilidad en la capacidad de crear paquetes sin tener que publicarlos en un repositorio como npm.
Creo que tarde o temprano aparecerá alguna alternativa al administrador de paquetes en Deno.
El sitio web oficial de Deno aloja paquetes de terceros: https://deno.land/x/
Instalación de Deno
¡Basta de hablar! Instalemos Deno.
La forma más sencilla de hacer esto es usando Homebrew:
brew install deno
Aquí se enumeran otros métodos de instalación .
Después de la instalación, el comando está disponible
deno
. Aquí está la ayuda que puede obtener escribiendo 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
Equipos Deno
¿Notaste la sección
SUBCOMMANDS
? Esta es una lista de todos los comandos que podemos ejecutar. ¿Qué equipos tenemos?
bundle
- recopila las dependencias del módulo y del proyecto en un archivocache
- caché de dependenciascompletions
- genera recargas de cáscaradoc
- muestra la documentación del móduloeval
- utilizado para calcular un bloque de código, por ejemplodeno eval "console.log(1 + 2)"
fmt
- formateador de código incorporado (comogoFmt
en Go)help
- muestra una lista de comandos auxiliaresinfo
- muestra información sobre la caché o el archivoinstall
- establece el script como ejecutablerepl
- ciclo de lectura-cálculo-salida (predeterminado)run
- ejecuta el programa con el nombre dado o la URL del módulotest
- ejecuta pruebastypes
- muestra una lista de características de TypeScriptupgrade
- actualiza Deno a la última versión
Puede ejecutar
deno <subcommand> help
para obtener información sobre un comando específico, por ejemplo deno run --help
.
Podemos usar un comando
deno
para iniciar un ciclo de lectura-evaluación-salida:
esto es lo mismo que comenzar
deno repl
.
Normalmente se
deno
utiliza para iniciar una aplicación Deno contenida en un archivo TypeScript.
Puede ejecutar archivos TypeScript (.ts) y archivos JavaScript (.js).
Si es nuevo en TypeScript, no se preocupe: Deno está escrito en TypeScript, pero puede escribir sus aplicaciones cliente en JavaScript.
Primera aplicación en Deno
Creemos nuestra primera aplicación.
Para ello, ni siquiera tenemos que escribir código, lo ejecutaremos en el terminal usando la URL.
Deno descarga el programa, lo compila y lo ejecuta:
Por supuesto, no recomendaría ejecutar código aleatorio de Internet. En este caso, lo estamos lanzando desde el sitio oficial de Deno, además, Deno tiene una caja de arena que evita que los programas hagan lo que no les permitimos explícitamente hacer.
Este programa es muy simple y es una llamada
console.log()
:
console.log('Welcome to Deno ') // ,
Si abre https://deno.land/std/examples/welcome.ts en un navegador, verá lo siguiente:
Extraño, ¿no? Probablemente esperaba ver un archivo TypeScript, pero en su lugar obtuvo una página web. El punto es que el servidor del sitio web de Deno sabe que está utilizando un navegador y le proporciona una página más fácil de usar.
Cargue la misma URL usando
wget
, por ejemplo, y obtenga en su text/plain
lugar text/html
:
Cuando reinicia el programa, gracias al almacenamiento en caché, no es necesario reiniciar:
Usando una bandera,
--reload
puede realizar un reinicio forzado:
deno run
tiene muchas funciones diferentes que no se muestran deno --help
. Para verlos, debe ejecutar 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
Ejemplos de código
Hay otros ejemplos en el sitio web de Deno que se pueden encontrar aquí .
En el momento de escribir este artículo, se puede encontrar lo siguiente en el repositorio especificado:
cat.ts
- muestra el contenido de los archivos pasados como argumentoscatj.ts
- hace lo mismo,cat.ts
pero primero realiza algunas manipulaciones con el contenido de los archivoschat/
- implementación de chatcolors.ts
- un ejemplo de estilo de texto usando móduloscurl.ts
- una implementación simplecurl
que genera el contenido de la URL pasada como argumentoecho_server.ts
- servidor de eco TCPgist.ts
- programa para colocar archivos en gist.github.comtest.ts
- programa de pruebawelcome.ts
- el programa que lanzamosxeval.ts
- le permite ejecutar TypeScript obtenido de cualquier fuente de datos estándar.deno xeval
ha sido eliminado de la lista de equipos oficiales
Primera aplicación real en Deno
Escribamos un código.
La primera aplicación con la que lanzamos
deno run https://deno.land/std/examples/welcome.ts
ya estaba escrita, por lo que no ha aprendido nada nuevo sobre Deno.
Comencemos con un ejemplo estándar publicado en el sitio web de Deno:
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' })
}
Aquí estamos importando una función
serve
de un módulo http/server
. ¿Ver? No tuvimos que instalarlo y no está almacenado en nuestra computadora como los módulos de nodo. Esta es una de las razones de la rápida instalación de Deno.
Con la ayuda
https://deno.land/std/http/server.ts
importamos la última versión del módulo. Se puede importar una versión específica usando @VERSION
:
import { serve } from 'https://deno.land/std@v0.42.0/http/server.ts'
Esta es la función
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)
}
A continuación, llamamos a la función
serve()
y le pasamos un objeto con una propiedad port
.
Luego ejecutamos un ciclo para responder a cada solicitud del servidor:
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
Tenga en cuenta que estamos usando la palabra clave
await
sin envolver el código en una async
función.
Ejecutemos el programa localmente. Estoy usando VS Code, pero puedes usar cualquier editor.
Recomiendo instalar una extensión de justjavac (hay otra con un nombre similar, pero está obsoleta y puede desaparecer en el futuro): la
extensión proporciona varias utilidades para ayudarlo a escribir aplicaciones Deno.
Creemos un archivo
app.ts
y peguemos nuestro código en él:
Ejecutarlo con
deno run app.ts
:
Deno cargará todas las dependencias que necesita el programa, pero primero la que importamos en el archivo.
El archivo https://deno.land/std/http/server.ts tiene varias dependencias propias:
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
Estas dependencias se importan automáticamente.
Al final, tenemos un problema:
¿Qué está pasando? Tenemos un error de permiso denegado.
Hablemos de la caja de arena.
Salvadera
Como mencioné anteriormente, Deno tiene una caja de arena que evita que los programas hagan cosas para las que no han sido autorizados.
¿Qué significa esto?
Como dice Ryan en su charla, a veces desea ejecutar un programa JavaScript fuera del navegador y no desea que el programa tenga acceso a todo en su sistema. O cuando se trata del mundo exterior usando la red.
Nada impide que la aplicación Node.js obtenga su clave SSH u otra información de su sistema y la envíe al servidor. Es por eso que generalmente solo instalamos paquetes de Node de fuentes confiables. Pero, ¿cómo sabemos si uno de los proyectos que estamos usando ha sido pirateado?
Deno imita el sistema de permisos utilizado por el navegador. El código JavaScript que se ejecuta en un navegador no puede hacer nada con su sistema a menos que usted lo permita explícitamente.
Volviendo a Deno, si un programa necesita acceso a la red, tenemos que darle permiso para hacerlo.
Esto se hace usando la bandera
--allow-net
:
deno run --allow-net app.ts
El servidor ahora se está ejecutando en el puerto 8000:
Otros indicadores:
--allow-env
- permite el acceso a variables de entorno--allow-hrtime
- permite la medición de alta resolución--allow-net=<allow-net>
- permite el acceso a la red--allow-plugin
- permite cargar complementos--allow-read=<allow-read>
- permite leer archivos--allow-run
- permite iniciar subprocesos--allow-write=<allow-write>
- permite escribir archivos--allow-all
- otorga todos los permisos (similar-A
)
Permisos para
net
, read
y write
pueden ser parcial. Por ejemplo, podemos permitir que los archivos de sólo lectura que se encuentran en un determinado directorio: --allow-read=/dev
.
Formato de código
Una de las cosas que me encanta de Go es el comando
gofmt
. Todo el código de Go tiene el mismo aspecto. Todo el mundo lo está usando gofmt
.
Los desarrolladores de JavaScript suelen usar Prettier y,
deno fmt
de hecho, también lo usan debajo del corte.
Digamos que tiene un archivo tan mal formateado:
comienza
deno fmt app.ts
y el formateo automático se lleva a cabo sin punto y coma:
Biblioteca estándar
La biblioteca estándar de Deno es bastante extensa a pesar de la antigüedad del proyecto.
Incluye lo siguiente:
archieve
- utilidades para archivarasync
- utilidades para trabajar con código asincrónicobytes
- funciones auxiliares para dividir bytesdatetime
- análisis de fechas / horasencoding
- codificación / decodificación en diferentes formatosflags
- análisis de indicadores de línea de comandofmt
- formación y exhibiciónfs
- interfaz de aplicación para trabajar con el sistema de archivoshash
- biblioteca de cifradohttp
- servidor HTTPio
- biblioteca de operaciones de entrada / salidalog
- utilidades para la talamime
- soporte de datos mixtosnode
- capa de compatibilidad con versiones anteriores de Nodepath
- trabajar con caminosws
- enchufes web
Un ejemplo mas
Echemos un vistazo a otro ejemplo oficial
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()
}
Asignamos
filenames
contenido a una variable Deno.args
, que es una variable que contiene los argumentos pasados usando la línea de comando.
Los iteramos y para cada uno, primero los usamos
Deno.open()
para abrir el archivo y luego Deno.copy()
copiamos el contenido en Deno.stdout
. Finalmente, cerramos el archivo.
Si tu corres:
deno run https://deno.land/std/examples/cat.ts
El programa se cargará y compilará, pero no pasa nada porque no pasamos ningún argumento.
Ahora intentemos esto:
deno run https://deno.land/std/examples/cat.ts app.ts
Obtenemos error de permiso:
Deno no tiene acceso al sistema por defecto. Démosle este permiso con
--allow-read
:
deno run --allow-read=./ https://deno.land/std/examples/cat.ts app.ts
¿Existe Express / Hapi / Koa / * para Deno?
Oh, por supuesto. Eche un vistazo a los siguientes proyectos:
Ejemplo: usar Oak para crear una API REST
Voy a crear una API REST usando Oak. Oak es interesante porque está inspirado en Koa, un middleware popular para NOde.js, y tiene una sintaxis similar.
Nuestra API será muy sencilla.
Nuestro servidor almacenará en memoria una lista de perros, sus nombres y edades.
Queremos obtener la siguiente funcionalidad:
- agregar nuevos perros a la lista
- obtener una lista de todos los perros
- obtener información sobre un perro específico
- eliminar un perro de la lista
- actualizar la edad del perro
Escribiremos el código en Typecript, pero nada le impide hacerlo en JavaScript, simplemente no especifique los tipos de datos.
Creamos un archivo
app.ts
.
Comencemos por importar objetos desde
Application
y Router
hacia Oak
:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
Obtenemos las variables de entorno PORT y HOST:
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
De forma predeterminada, nuestra aplicación se ejecutará en localhost: 4000.
Cree una aplicación Oak y ejecútela:
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}`)
La aplicación debería funcionar ahora.
Verificamos:
deno run --allow-env --allow-net app.ts
Deno descarga las dependencias:
Y comienza a escuchar en el puerto 4000.
Al reiniciar, el paso de instalación se omitirá gracias al almacenamiento en caché:
Defina una interfaz para el perro, luego defina una matriz que
dog
contenga los objetos Dog
:
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
Comencemos a implementar la API.
Todo está en su lugar. Agreguemos algunas funciones al enrutador que se llamará al acceder al punto final especificado:
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
Hemos definido lo siguiente:
GET /dogs
GET /dogs/:name
POST /dogs
PUT /dogs/:name
DELETE /dogs/:name
Implementemos estas rutas una por una.
Comencemos con
GET /dogs
, que devuelve una lista de todos los perros:
export const getDogs = ({ response }: { response: any }) => {
response.body = dogs
}
A continuación, le indicamos cómo obtener un perro específico por nombre:
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}` }
}
A continuación, se explica cómo agregar un perro nuevo a la lista:
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
}
A continuación, le indicamos cómo actualizar la edad de su perro:
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}` }
}
Y aquí se explica cómo eliminar un perro de la lista:
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
}
Código de aplicación completo:
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}`)
Gracias por su atención.