- JavaScriptランタイムはこれからもたくさん出てくる
- Node.js, Deno, cloudflare workers, Google Apps Script, ...
- それぞれ別々のAPIを設計していたらキリがない
- 独自のAPIを設計してテストして仕様を維持していくのは大変
- Web標準APIを使えば解決
JavaScriptランタイムとWeb標準API
前提として、JavaScriptにはどのランタイムでも使える関数(標準ビルトインオブジェクト)と特定のランタイムでしか使えない関数(ランタイムAPI)がある。
前者は例えばeval
やArray
などで、後者はconsole
やsetTimeout
などだ。
標準ビルトインオブジェクト | ランタイムAPI | |
---|---|---|
特徴 | すべてのランタイムで使える | ランタイムごとに違う |
例 |
Array , eval など |
console , setTimeout
|
実装者 | JSエンジン(V8など) | JSランタイム(Node.jsなど) |
仕様策定場所 | TC39 | WICGやW3CやWHATWGなど |
ブラウザで使えるDOM API
などもランタイムAPIの一種である。
ブラウザの場合は「このランタイムAPIをこの仕様で実装しましょうね」という取り決めがあり、複数のブラウザで共通のランタイムAPIが使えることが保証されている。
一方サーバー側ランタイムでは、このような共通APIの取り決めはない。
そのため、HTTPリクエストの方法一つとってもランタイムごとに分かれてしまっている。
- 標準モジュールのHTTPモジュール(Node.js)
- fetch(Deno, cloudflare workers)
- UrlFetchApp.fetch(Google Apps Script)
ランタイムごとに仕様を作成するデメリット
独自のランタイムAPIを作成すると以下のようなデメリットがある。
- 仕様の作成が大変
- JSの特性として、基本的に後方互換性を維持する必要がある
- 一度入れたAPIは消せない
- 堅牢なAPIを作るには大量の議論が必要
- 仕様の維持が大変
- たとえばQuickJSにはBigFloatというAPIがある
- このAPIの使い方は?
- APIのテストも1から書かなきゃいけない
- ドキュメントも維持しなきゃならない
ランタイムが独自のAPIを考え出して設計し、テストしなければならない。
ユーザーからすると、書かれたテストが正しいかも(中身を見ないと)わからない。実装とテストを書いた人間が正気かどうか、誰が保証するのだろうか?
これをやれるのはNode.jsのような巨大プロジェクトか、Googleのような大企業の潤沢な資金によって維持されているプロジェクトだけだろう。新しいランタイムを作成しなければならないときに1から使用を設計し維持するのは開発者にとってもユーザーにとっても辛い。
そこで、Web標準APIを流用してしまうという手がある。
Web標準APIをサーバー側で使うメリット
Web標準を使うと以下のような嬉しい点がある。
- 仕様は既に議論されていて(基本的に)堅牢である
- wptという、Web APIのためのテストがある
特にwptがあるのが嬉しいポイントで、「wptのテストのうち何割通ったか」というのが実装の信頼性の使用になる。https://wpt.fyi/ を見れば他のランタイムとの比較もできる。実装を書いた人間の正気はwptによって保障される。
ドキュメントはMDNにあるし、ユーザーは新しいAPIを学ぶ必要もない。他のランタイムにコードを持っていくときにバベる必要もない。
fetch仕様の中に部分的に要らない機能があるからといって、オレオレfetchやfecth2.0を実装する必要は全くない。Web APIは部分的に実装してもOKである。
本当に必要な時以外は、独自のランタイムAPIを生み出す必要はないと思う。
Winter CG
実はサーバー側ランタイムで歩調を合わせてWeb標準APIを使えるようにしようという取り組みは既に始まっている。Winter CGである。
これまでのようにブラウザ側によって定義されたAPIをサーバー側に流用するだけでなく、サーバー側ランタイムから仕様の策定にかかわっていこうという団体である。Denoやcloudflareなどが参加している。
現在はwebcrypto-streamsとcommon-minimum-apiの仕様策定が進められている。
まとめ
- 独自APIを入れるくらいなら、Web標準APIを(たとえ部分的にでも)入れてもらったほうが開発者とユーザーにとってメリットがある。
- Web APIは一部の機能だけ実装してもよい。星取表のように埋める必要はないし、不要な機能は実装する必要はない。
- 「サーバー側ランタイムに同じAPIが実装されているのが本当にいいことなのか」という問いは「ChromeとSafariに同じAPIが実装されているのが本当にいいことなのか」みたいなレベルの話で、そこはランタイムごとの特色を出すよりも大事なことがあると思う。