2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Deno/TypeScript入門〜HTTPレスポンスをCSV出力してみる編〜

Last updated at Posted at 2022-05-08

まえがき

最近私はツールを開発する環境として「Deno」が気に入っています。
シンプルで、軽くて、ランタイムAPIや標準ライブラリが充実していて、開発体験が良いと感じています。
私のところではDenoを本番で採用しようとすると諸々ハードルがありますが、ツールの開発であれば選択肢として大いにアリです。

この記事では、Deno/TypeScriptの概要と、サンプルとして「HTTPレスポンス(JSON)をCSVファイルに出力するツール」の開発手順を解説します。

私自身も初学者なので、間違い等があればコメントでご教示ください。

前提環境

Deno 1.20.5

Denoとは

概要

Wikipediaより引用:

Denoは、V8 JavaScriptエンジン及びRustプログラミング言語に基づいた、JavaScript及びTypeScriptのランタイム環境である。

Node.jsの作者であるライアン・ダールによって作成され、セキュリティと生産性に焦点を当てている。
ライアン・ダールが2018年に行った講演「Node.jsに関する10の反省点」で発表された。

主な特徴

TypeScriptを標準サポート

  • トランスパイラを内蔵しており、Babelなどのトランスパイラ環境がなくても実行できます。

TypeScript Deep Dive 日本語版より引用:

TypeScriptはJavaScriptを拡張して作られたプログラミング言語です。
トレンドが示すとおり、TypeScriptはJavaScriptに代わって第一に選択される言語になりました。
TypeScriptが提供する静的型システムは、コードの保守性と可読性を大幅に向上させます。
またブラウザ等の互換性を心配することなく、モダンで便利なJavaScriptの機能を利用できます。

TypeScriptのダウンロード動向:
Screen Shot 2022-02-04 at 22.03.47.png

パッケージ(モジュール)管理の仕組みがシンプル

  • npm, node_modules, package.json といったツールや設定ファイルがありません。
  • 外部モジュールを使う場合はimportにURLを渡すだけ。さらにrequireも不要です。
import { format, parse } from "https://deno.land/std@0.138.0/datetime/mod.ts";
  • ダウンロードは実行時に行われ、結果はキャッシュされます。
  • すなわち、Denoはランタイム環境であるだけでなくパッケージ管理ツールの役割も持っています。

その他にも、素晴らしい特徴がいろいろあります。さらに詳しく知りたい方は文末のリンク集をご参照ください。

Denoのインストール

公式ドキュメントを参照するのが確実です。

Visual Studio Code (VSCode) の環境構築

テキストエディタでも開発は可能ですが、統合開発環境(IDE)の方が、コード補完や静的チェックが効きますので開発が捗ります。

Denoでは皆さんVSCodeを使っていらっしゃるようです。
以下の記事に素晴らしくまとまっています。

あれこれ調べるのがめんどくさかったら(笑)、
拡張機能「Deno for Visual Studio Code」をインストールして、
作業フォルダ配下に.vscodeフォルダを作成し、
以下のファイルを格納すれば、とりあえず開発を始められると思います。

settings.json
{
    "debug.javascript.unmapMissingSources": true,
    "deno.enable": true,
    "deno.lint": true,
    "deno.unstable": true,
    "deno.suggest.imports.hosts": {
        "https://deno.land": true
    }
}

VSCodeのデバッグ実行を使いたい場合はlaunch.jsonも格納します。

launch.json
launch.json
{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Deno",
        "type": "pwa-node",
        "request": "launch",
        "cwd": "${workspaceFolder}",
        "runtimeExecutable": "deno",
        "runtimeArgs": ["run", "--inspect-brk", "-A", "./app.ts"],
        "attachSimplePort": 9229
      }
    ]
}

※app.tsはアプリケーションのエントリーポイントとなるファイル名ですので、適宜書き変えてください。

「HTTPレスポンス(JSON)をCSVファイルに出力するツール」の開発

APIについて

APIキーもログインも不要で無料で使える天気予報API「Open-Meteo」を使ってみます。
(※商用利用はNGのようです。ライセンス要件をご確認ください。)

Open-Meteoはパラメータによって様々なデータを取得できますが、今回は「東京の1週間分の気温」をGETします。
URLは以下で、ブラウザでも試すことが出来ます。
https://api.open-meteo.com/v1/forecast?latitude=35.6785&longitude=139.6823&hourly=temperature_2m&timezone=Asia%2FTokyo

レスポンスJSONのサンプル
{
  utc_offset_seconds: 0,
  hourly: {
    temperature_2m: [
      20.5,   21, 21.3, 21.3, 21.6, 21.4, 19.8, 18.3, 17.6,   17,
      16.7, 16.7, 16.5, 16.3, 16.1, 16.1, 16.1,   16, 15.9, 15.9,
      15.5, 14.5,   14, 14.4, 15.3, 15.7, 15.3,   15, 15.1, 14.8,
      14.2, 13.8, 13.4,   13, 12.7, 12.6, 12.5, 12.5, 12.4, 12.4,
      12.4, 12.4, 12.3, 12.2, 12.1, 12.6, 14.1, 15.8, 17.6, 18.7,
      20.6,   22,   22, 21.4, 20.9,   20, 19.1, 18.1, 17.3, 16.9,
      16.5, 16.2,   16,   16,   16, 15.9, 15.9, 15.9, 15.9, 15.9,
        16, 16.3, 16.3, 16.8, 17.4, 18.1, 18.3, 18.4, 18.3, 18.2,
        18, 17.8, 17.7, 17.6, 17.5, 17.4, 17.3, 17.1,   17, 16.9,
      16.8, 16.7, 16.7, 16.8, 17.3, 17.9, 18.8, 19.6, 20.5, 21.5,
      ... 68 more items
    ],
    time: [
      "2022-05-08T00:00", "2022-05-08T01:00", "2022-05-08T02:00",
      "2022-05-08T03:00", "2022-05-08T04:00", "2022-05-08T05:00",
      "2022-05-08T06:00", "2022-05-08T07:00", "2022-05-08T08:00",
      "2022-05-08T09:00", "2022-05-08T10:00", "2022-05-08T11:00",
      "2022-05-08T12:00", "2022-05-08T13:00", "2022-05-08T14:00",
      "2022-05-08T15:00", "2022-05-08T16:00", "2022-05-08T17:00",
      "2022-05-08T18:00", "2022-05-08T19:00", "2022-05-08T20:00",
      "2022-05-08T21:00", "2022-05-08T22:00", "2022-05-08T23:00",
      "2022-05-09T00:00", "2022-05-09T01:00", "2022-05-09T02:00",
      "2022-05-09T03:00", "2022-05-09T04:00", "2022-05-09T05:00",
      "2022-05-09T06:00", "2022-05-09T07:00", "2022-05-09T08:00",
      "2022-05-09T09:00", "2022-05-09T10:00", "2022-05-09T11:00",
      "2022-05-09T12:00", "2022-05-09T13:00", "2022-05-09T14:00",
      "2022-05-09T15:00", "2022-05-09T16:00", "2022-05-09T17:00",
      "2022-05-09T18:00", "2022-05-09T19:00", "2022-05-09T20:00",
      "2022-05-09T21:00", "2022-05-09T22:00", "2022-05-09T23:00",
      "2022-05-10T00:00", "2022-05-10T01:00", "2022-05-10T02:00",
      "2022-05-10T03:00", "2022-05-10T04:00", "2022-05-10T05:00",
      "2022-05-10T06:00", "2022-05-10T07:00", "2022-05-10T08:00",
      "2022-05-10T09:00", "2022-05-10T10:00", "2022-05-10T11:00",
      "2022-05-10T12:00", "2022-05-10T13:00", "2022-05-10T14:00",
      "2022-05-10T15:00", "2022-05-10T16:00", "2022-05-10T17:00",
      "2022-05-10T18:00", "2022-05-10T19:00", "2022-05-10T20:00",
      "2022-05-10T21:00", "2022-05-10T22:00", "2022-05-10T23:00",
      "2022-05-11T00:00", "2022-05-11T01:00", "2022-05-11T02:00",
      "2022-05-11T03:00", "2022-05-11T04:00", "2022-05-11T05:00",
      "2022-05-11T06:00", "2022-05-11T07:00", "2022-05-11T08:00",
      "2022-05-11T09:00", "2022-05-11T10:00", "2022-05-11T11:00",
      "2022-05-11T12:00", "2022-05-11T13:00", "2022-05-11T14:00",
      "2022-05-11T15:00", "2022-05-11T16:00", "2022-05-11T17:00",
      "2022-05-11T18:00", "2022-05-11T19:00", "2022-05-11T20:00",
      "2022-05-11T21:00", "2022-05-11T22:00", "2022-05-11T23:00",
      "2022-05-12T00:00", "2022-05-12T01:00", "2022-05-12T02:00",
      "2022-05-12T03:00",
      ... 68 more items
    ]
  },
  hourly_units: { temperature_2m: "°C", time: "iso8601" },
  longitude: 139.625,
  generationtime_ms: 2.048015594482422,
  elevation: 20.84375,
  latitude: 35.625
}

CSV出力結果のサンプル

temperature.csv
2022/05/08 00:00,16.8
2022/05/08 01:00,16.4
2022/05/08 02:00,16.2
2022/05/08 03:00,16.5
2022/05/08 04:00,16.4
(以下略)

コード

app.ts
import { format, parse } from "https://deno.land/std@0.138.0/datetime/mod.ts";

let output = "";
let temperatureList: number[] = [];
let dateTimeList: string[] = []; // e.g."2022-05-08T21:00"

// GETとparse
try {
  // 東京の1週間分の気温をGET
  const response = await fetch(
    "https://api.open-meteo.com/v1/forecast?latitude=35.6785&longitude=139.6823&hourly=temperature_2m&timezone=Asia%2FTokyo",
  );
  const responseJson = await response.json();
  console.log(responseJson);
  temperatureList = responseJson["hourly"]["temperature_2m"] as number[];
  dateTimeList = responseJson["hourly"]["time"] as string[];
} catch (e) {
  console.log(`API error: ${e.message}`);
  Deno.exit();
}

// CSV出力用文字列に整形
temperatureList.forEach((temperature, i) => {
  // 2件め以降の場合は改行を挿入
  if (i > 0) {
    output += "\n";
  }
  // 日時フォーマット
  const outputDateTime = format(
    parse(dateTimeList[i], "yyyy-MM-dd'T'HH:mm"),
    "yyyy/MM/dd HH:mm",
  );
  // CSV出力用文字列に追加
  output += `${outputDateTime},${temperature}`;
});

// CSV書き出し
try {
  Deno.writeTextFileSync("./temperature.csv", output);
  console.log(`Written to ./temperature.csv`);
} catch (e) {
  console.log(`Output error: ${e.message}`);
  Deno.exit();
}

実行

Denoのセキュリティ機構として、ネットワークを許可するための--allow-netと、ファイル書き込みを許可するための--allow-writeオプションを付けて実行します。

$ deno run --allow-net --allow-write app.ts

コードのちょっとした解説

Denoの標準APIについて

DenoはブラウザのようにfetchなどのWeb標準APIを実装しています。
fetch_data

また、DenoのランタイムAPIは、テキストファイルの読み書きのために Deno.readTextFileDeno.writeTextFile 非同期関数を提供します。
同等の同期関数 Deno.readTextFileSyncDeno.writeTextFileSync もあります。
read_write_files

Denoの標準ライブラリについて

今回使用したdatetimeのような、Deno本体との連携が保証された標準ライブラリが提供されています。
標準ライブラリは、サードパーティ・ライブラリと同じくimportして使用します。
また、importする際には上のコードの/std@0.138.0のようにバージョン番号をpathで指定します。

型について

なんと言っても、型を定義できることがTypeScriptの強みです。
型の間違いは、VSCodeでリアルタイムにチェックが働きます。
スクリーンショット 2022-05-08 10.13.46.png
TypeScript Deep Dive 日本語版 > TypeScriptの型システム

さらに詳細な情報を得られるお勧めリンク集

Deno

TypeScript

あとがき

後続の「スタブ・サーバーを作ってみる編」もぜひ。。。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?