Denoガむド新しいサヌバヌ偎JavaScriptおよびTypeScriptランタむムの操䜜䟋



良い䞀日、友達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-組み蟌みのコヌドフォヌマッタgoFmtGoなど
  • 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}`)


枅聎ありがずうございたした。