良い一日、友達!Flavio Copesによる
記事「TheDenoHandbook:A TypeScript Runtime Tutorial withCodeExamples」の翻訳を紹介します。
この記事では、Denoの操作方法を学習します。これをNode.jsと比較し、それを使用して単純なRESTAPIを構築します。
デノとは?
人気のあるサーバー側のJavaScriptエコシステムであるNode.jsに精通している場合、Denoはほとんど同じです。ほとんどですが、完全ではありません。
私が最も好きなDeno機能のリストから始めましょう:
- 最新のJavaScriptに基づいています
- 拡張可能な標準ライブラリがあります
- 標準のTypeScriptサポートがあります(つまり、TypeScriptを手動でコンパイルする必要はなく、Denoが自動的にコンパイルします)
- ESモジュールをサポートします
- パッケージマネージャーはありません
- それはグローバルです
await
- テスト機能が組み込まれています
- その目標は、最大のブラウザー互換性です。このために、インライン
fetch
オブジェクトとグローバルオブジェクトを提供しますwindow
このチュートリアルでは、これらすべての可能性を探ります。
Denoとその機能に慣れると、Node.jsは少し時代遅れになります。
特にNode.jsはコールバック関数に基づいているため(promiseおよびasync / awaitの前に記述されています)。根本的な変更が必要であることを意味するため、それらがそこに表示される可能性はほとんどありません。
Node.jsは素晴らしく、JavaScriptの世界では事実上の標準であり続けるでしょう。ただし、TypeScriptのサポートと最新の標準ライブラリのおかげで、Denoの人気は急速に高まると思います。
Denoは、下位互換性を必要としないため、最新のコードを購入できます。もちろん、このコードが今後10年間最新であるという保証はありませんが、今日ではそうです。
なぜデノ?なぜ今なのか?
Denoは、ほぼ2年前にJSConfEUでNode.jsの作成者であるRyanDahlによって発表されました。見るYouTubeの動画を、それは非常に興味深く、必見のNode.jsとJavaScriptであなたがしている作業している場合です。
各プロジェクトマネージャー(作成者)は、決定を下すことを余儀なくされています。ライアンは、ノードでの初期の決定のいくつかを後悔しています。さらに、テクノロジーが進歩し、JavaScriptは、ノードが2009年にあったときとはまったく異なる言語になりました。 ES6 / 2016/2017などを思い出してください。
そこで彼は、サーバー側のJavaScriptアプリケーションの一種である新しいプロジェクトを開始することにしました。
私が今この記事を書いているのは、テクノロジーが成熟するまでにかなり長い時間がかかるからです。最後に、最初の安定したリリースであるDeno 1.0(2020年5月13日にリリースされました)を入手しました。
これは一般的な数字のように思えるかもしれませんが、1.0は、Deno2.0まで大幅な変更がないことを意味します。新しいテクノロジーを学ぶとき、それがあまりにも速く変化することを望まないでしょう。
あなたはデノを学ぶべきですか?
良い質問。
デノのような新しいことを学ぶには多くの努力が必要です。私のアドバイス:サーバー側のJSを使い始めたばかりで、Node.jsをまだ知らず、TypeScriptを作成したことがない場合は、Nodeから始めてください。
ノードを選択したことで解雇されたことはありません(有名な引用を言い換えます)。
しかし、大量のnpmパッケージに依存しないTypeScriptが好きで、どこでも使用したい
await
場合は、Denoが探しているかもしれません。
Node.jsに取って代わりますか?
番号。Node.jsは巨大で大きな権威であり、信じられないほど十分にサポートされているテクノロジーであり、今後10年間はどこにも行きません。
ファーストクラスのTypeScriptサポート
DenoはRustとTypeScriptで書かれており、どちらも今日の世界で非常に人気のある言語です。
これは、JavaScriptを作成している場合でも、TypeScriptから多くのメリットが得られることを意味します。
DenoでTypeScriptコードを実行する場合、事前コンパイルは必要ありません-Denoはこれを自動的に実行します。
TypeScriptコードを作成する必要はありませんが、DenoのコアがTypeScriptで作成されているという事実は大きな違いを生みます。
まず、JavaScript開発者の大部分がTypeScriptを愛しています。
次に、使用するツールは、DenoのようなTypeScriptで記述されたソフトウェアに関する多くの情報を取得できます。
つまり、たとえばVS Code(最初からTypeScriptと緊密に統合されている)でコードを作成すると、コード作成時の型チェックや高度なIntelliSense機能などのメリットが得られます。言い換えれば、コードエディタの助けがはるかに効率的になります。
Node.jsとの違い
Denoは本質的にNode.jsの代替であるため、2つを比較することは理にかなっています。
一般:
- どちらもV8エンジンに基づいています
- どちらもサーバー側のJavaScript開発に最適です
違い:
- ノードはC ++とJavaScriptで書かれています。DenoはRustとTypeScriptで書かれています。
- ノードには公式のパッケージマネージャーがあり
npm
ます。Denoにはそのようなマネージャーはありませんが、代わりにURLを使用して任意のモジュールをインポートできます。 - NodeはCommonJS構文を使用してパッケージをインポートします。Denoは公式の方法であるESモジュールを使用します。
- Deno ECMAScript , Node.js .
- Deno () . . Node.js , .
- Deno , .. , , Go, . .
パッケージマネージャーがなく、URLを使用してパッケージを取得およびインポートすることには、長所と短所があります。主な利点の1つは、npmなどのリポジトリにパッケージを公開しなくてもパッケージを作成できる柔軟性が高いことです。
遅かれ早かれ、デノのパッケージマネージャーに代わるものが登場すると思います。
Denoの公式ウェブサイトはサードパーティのパッケージをホストしています:https://deno.land/x/
Denoのインストール
十分に話します!Denoをインストールしましょう。
これを行う最も簡単な方法は、Homebrewを使用することです。
brew install deno
その他のインストール方法はここにリストされています。
インストール後、コマンドが使用可能になります
deno
。次のように入力すると、ヘルプが表示されます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
デノチーム
セクションに気づきました
SUBCOMMANDS
か?これは、実行できるすべてのコマンドのリストです。どのチームがありますか?
bundle
-モジュールとプロジェクトの依存関係を1つのファイルに収集しますcache
-依存関係をキャッシュしますcompletions
-シェルリフィルを生成しますdoc
-モジュールのドキュメントを表示しますeval
-たとえば、コードのブロックを計算するために使用されますdeno eval "console.log(1 + 2)"
fmt
-組み込みのコードフォーマッタ(goFmt
Goなど)help
-補助コマンドのリストを表示しますinfo
-キャッシュまたはファイルに関する情報を表示しますinstall
-スクリプトを実行可能として設定しますrepl
-読み取り-計算-出力サイクル(デフォルト)run
-モジュールの指定された名前またはURLでプログラムを実行しますtest
-テストを実行しますtypes
-TypeScript機能のリストを表示しますupgrade
-Denoを最新バージョンに更新します
deno <subcommand> help
たとえば、を
実行して特定のコマンドに関する情報を取得できますdeno run --help
。
コマンド
deno
を使用して、読み取り-評価-出力ループを開始できます。
これは、開始と同じ
deno repl
です。
通常
deno
、TypeScriptファイルに含まれるDenoアプリケーションを実行するために使用されます。
TypeScriptファイル(.ts)とJavaScriptファイル(.js)の両方を実行できます。
TypeScriptを初めて使用する場合でも、心配する必要はありません。DenoはTypeScriptで記述されていますが、クライアントアプリケーションはJavaScriptで記述できます。
Denoの最初のアプリ
最初のアプリケーションを作成しましょう。
これを行うには、コードを記述する必要はありません。URLを使用してターミナルで実行します。
Denoはプログラムをダウンロードし、コンパイルして実行します。
もちろん、インターネットからランダムなコードを実行することはお勧めしません。この場合、Denoの公式Webサイトから起動します。さらに、Denoには、プログラムが明示的に許可していないことを実行できないようにするサンドボックスがあります。
このプログラムは非常にシンプルで、呼び出し
console.log()
です:
console.log('Welcome to Deno ') // ,
https://deno.land/std/examples/welcome.tsをブラウザで 開くと、次のように表示されます。
奇妙ですね。TypeScriptファイルが表示されることを期待していましたが、代わりにWebページを取得しました。重要なのは、Deno Webサイトサーバーは、ユーザーがブラウザーを使用していることを認識し、よりユーザーフレンドリーなページを提供するということです。たとえば、
を使用して同じURLをロードし、代わりに
wget
取得しtext/plain
ますtext/html
。
キャッシュのおかげでプログラムを再起動すると、再起動は必要ありません。
フラグを使用して
--reload
強制再起動を実行できます:で
deno run
表示されないさまざまな機能がありますdeno --help
。それらを表示するには、次を実行する必要があります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
コード例
ここ で見つけることができるDenoのウェブサイトに他の例があります。
この記事の執筆時点では、指定されたリポジトリに次のものがあります。
cat.ts
-引数として渡されたファイルの内容を表示しますcatj.ts
-同じことをしますcat.ts
が、最初にファイルの内容でいくつかの操作を実行しますchat/
-チャットの実装colors.ts
-モジュールを使用したテキストのスタイル設定の例curl.ts
-curl
引数として渡されたURLのコンテンツを出力する単純な実装echo_server.ts
-TCPエコーサーバーgist.ts
-gist.github.comにファイルを配置するためのプログラムtest.ts
-テストプログラムwelcome.ts
-私たちが立ち上げたプログラムxeval.ts
-任意の標準データソースから取得したTypeScriptを実行できます。deno xeval
公式チームのリストから削除されました
Denoの最初の本物のアプリ
コードを書いてみましょう。
私たちが最初に立ち上げたアプリ
deno run https://deno.land/std/examples/welcome.ts
はすでに作成されているため、Denoについて新しいことは何も学びません。
DenoのWebサイトに投稿されている標準的な例から始めましょう。
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' })
}
ここでは
serve
、モジュールから関数をインポートしていますhttp/server
。見る?インストールする必要はなく、ノードモジュールのようにコンピューターに保存されません。これが、Denoをすばやくインストールする理由の1つです。
助け
https://deno.land/std/http/server.ts
を借りて、モジュールの最新バージョンをインポートします。特定のバージョンは、以下を使用してインポートできます@VERSION
。
import { serve } from 'https://deno.land/std@v0.42.0/http/server.ts'
これは関数が何であるかです
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)
}
次に、関数を呼び出し
serve()
て、プロパティを持つオブジェクトを渡しますport
。
次に、ループを実行して、サーバーからの各要求に応答します。
for await (const req of s) {
req.respond({ body: 'Hello World\n' })
}
関数で
await
コードをラップせず
にキーワードを使用していることに注意してくださいasync
。
プログラムをローカルで実行してみましょう。私はVSコードを使用していますが、どのエディターでも使用できます。
justjavacから拡張機能をインストールすることをお勧めします(同様の名前の
拡張機能がありますが、非推奨であり、将来的になくなる可能性があります):拡張機能は、Denoアプリケーションの作成に役立ついくつかのユーティリティを提供します。
ファイル
app.ts
を作成して、コードをそのファイルに貼り付けましょう。
実行
deno run app.ts
:
Denoは、プログラムに必要なすべての依存関係をロードしますが、最初にファイルにインポートする依存関係をロードします。https://deno.land/std/http/server.ts
ファイルには、独自のいくつかの依存関係があります。
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
これらの依存関係は自動的にインポートされます。
最後に、問題があります。
何が起こっているのでしょうか。許可拒否エラーが発生しました。
サンドボックスについて話しましょう。
サンドボックス
先に述べたように、Denoには、プログラムが許可を得ていないことを実行できないようにするサンドボックスがあります。
これは何を意味するのでしょうか?
Ryanが講演で述べているように、JavaScriptプログラムをブラウザーの外部で実行したいが、プログラムがシステム上のすべてにアクセスできるようにしたくない場合があります。または、ネットワークを使用して外の世界になると。
Node.jsアプリケーションがシステムからSSHキーまたはその他の情報を取得し、それをサーバーに送信することを妨げるものは何もありません。これが、通常、信頼できるソースからのノードパッケージのみをインストールする理由です。しかし、使用しているプロジェクトの1つがハッキングされているかどうかをどうやって知ることができますか?
Denoは、ブラウザで使用される許可システムを模倣しています。ブラウザで実行されているJavaScriptコードは、明示的に許可しない限り、システムで何も実行できません。
Denoに戻ると、プログラムにネットワークアクセスが必要な場合は、その許可を与える必要があります。
これはフラグを使用して行われ
--allow-net
ます:
deno run --allow-net app.ts
サーバーは現在、ポート8000で実行されています。
その他のフラグ:
--allow-env
-環境変数へのアクセスを許可します--allow-hrtime
-高解像度の測定が可能--allow-net=<allow-net>
-ネットワークへのアクセスを許可します--allow-plugin
-プラグインのロードを許可します--allow-read=<allow-read>
-ファイルの読み取りを許可します--allow-run
-サブプロセスを開始できます--allow-write=<allow-write>
-ファイルの書き込みを許可します--allow-all
-すべての権限を付与します(同様-A
)
の権限
net
、read
およびwrite
部分的な場合があります。たとえば、特定のディレクトリにある読み取り専用ファイルを許可できます--allow-read=/dev
。
コードのフォーマット
Goについて私が気に入っていることの1つは、コマンド
gofmt
です。すべてのGoコードは同じように見えます。誰もがそれを使用していgofmt
ます。
JavaScript開発者は通常、Prettierを使用しますが
deno fmt
、実際には、カットの下でも使用します。
このような不適切なフォーマットのファイルがあるとします。
開始する
deno fmt app.ts
と、セミコロンが欠落した状態で自動フォーマットが実行されます。
標準ライブラリ
プロジェクトの時代にもかかわらず、デノの標準ライブラリは非常に広範です。
これには次のものが含まれます。
archieve
-アーカイブ用のユーティリティasync
-非同期コードを操作するためのユーティリティbytes
-バイトを分割するためのヘルパー関数datetime
-日付/時刻の解析encoding
-さまざまな形式でのエンコード/デコードflags
-コマンドラインフラグの解析fmt
-形成と表示fs
-ファイルシステムを操作するためのアプリケーションインターフェイスhash
-暗号化ライブラリhttp
-HTTPサーバーio
-入力/出力操作のライブラリlog
-ロギング用のユーティリティmime
-混合データのサポートnode
-ノードとの下位互換性レイヤーpath
-パスを操作するws
-Webソケット
もう1つの例
別の公式の例を見てみましょう-
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()
}
コマンドラインを使用して渡された引数を含む 変数である変数に
filenames
コンテンツを割り当てますDeno.args
。
それらを繰り返し処理し、それぞれについて、最初にそれら
Deno.open()
を使用してファイルを開き、次にDeno.copy()
コンテンツをにコピーしますDeno.stdout
。最後に、ファイルを閉じます。
実行する場合:
deno run https://deno.land/std/examples/cat.ts
プログラムはロードされてコンパイルされますが、引数を渡さなかったため、何も起こりません。
それでは、これを試してみましょう。
deno run https://deno.land/std/examples/cat.ts app.ts
パーミッションエラーが発生します:
Denoはデフォルトでシステムにアクセスできません。彼にそのような許可を与えましょう
--allow-read
:
deno run --allow-read=./ https://deno.land/std/examples/cat.ts app.ts
Express / Hapi / Koa / * Denoには存在しますか?
はい。次のプロジェクトを見てください。
例:Oakを使用してRESTAPIを作成する
Oakを使用してRESTAPIを作成します。Oakは、NOde.jsで人気のあるミドルウェアであるKoaに触発されており、同様の構文を持っているという点で興味深いものです。
APIは非常にシンプルになります。
私たちのサーバーは、犬のリスト、名前、年齢をメモリに保存します。
次の機能を取得したいと考えています。
- リストに新しい犬を追加する
- すべての犬のリストを取得します
- 特定の犬に関する情報を取得する
- リストから犬を削除します
- 犬の年齢を更新する
Typescriptでコードを記述しますが、JavaScriptでコードを記述できます。データタイプを指定しないでください。
ファイルを作成します
app.ts
。
さんがにオブジェクトをインポートすることから始めましょう
Application
とRouter
からOak
:
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
環境変数PORTとHOSTを取得します。
const env = Deno.env.toObject()
const PORT = env.PORT || 4000
const HOST = env.HOST || '127.0.0.1'
デフォルトでは、アプリケーションはlocalhost:4000で実行されます。
Oakアプリケーションを作成し、起動します。
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}`)
これで、アプリケーションが機能するはずです。
チェックします:
deno run --allow-env --allow-net app.ts
Denoは依存関係をダウンロードします:
そしてポート4000でリッスンを開始します。
再起動時に、キャッシュのおかげでインストール手順がスキップされ
ます:犬のインターフェースを定義し
dog
、オブジェクトを含む配列を定義しますDog
:
interface Dog {
name: string
age: number
}
let dogs: Array<Dog> = [
{
name: 'Roger',
age: 8,
},
{
name: 'Syd',
age: 7,
},
]
APIの実装を始めましょう。
すべてが整っています。指定されたエンドポイントにアクセスするときに呼び出されるいくつかの関数をルーターに追加しましょう。
const router = new Router()
router
.get('/dogs', getDogs)
.get('/dogs/:name', getDog)
.post('/dogs', addDog)
.put('/dogs/:name', updateDog)
.delete('/dogs/:name', removeDog)
以下を定義しました。
GET /dogs
GET /dogs/:name
POST /dogs
PUT /dogs/:name
DELETE /dogs/:name
これらのルートを1つずつ実装してみましょう。すべての犬のリストを返す、
から始めましょう
GET /dogs
:
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 dog: Dog = await body.value
dogs.push(dog)
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
}
完全なアプリケーションコード:
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}`)
清聴ありがとうございました。