denoでfetchを実装した
denoでfetchを実装した2019/2/3keroxp.icon
https://github.com/keroxp/deno-fetch
fetchはいまブラウザでちゃんと使えるHTTPのモジュール
denoにもfetchは実装されているのだけど、実は結構WIPという感じ
https://github.com/denoland/deno/blob/master/js/fetch.ts
WHATWG ReadableStreamに対応していない、その他fetch標準に準拠できていないところも多々
httpsをfetchするようにするためか、http通信の部分がまるごとRustレイヤに実装されているため、リソースを取得する目的としてしかhttpを開くことができない
denoでWebSocketを実装したときに、クライアントを作ろうとしたけどUpgrade要求するhttpコネクションを開けなくて困ったことがそもそもの動機
というわけで1月後半ころからちょこちょこ実装していた
fetch仕様の日本語訳を横目で見ながら実装した
https://triple-underscore.github.io/Fetch-ja.html
Githubが開発しているブラウザ向けfetch pollyfillも参考にした
https://github.com/github/fetch
…のだが、途中でfetchのresponseはReadableStreamでもある必要があるとわかった
ReadableStreamについてはWeb Streams APIについてで語る予定
ともかく勘所としては、fetchのレスポンスはストリーム形式で読み込める必要もあるというところ
と、それはfetchを策定しているWHATWGが同じく策定しているStreams Standardを使うとのこと
そもそもkeroxp.iconは未だにfetchをブラウザアプリで使ったことがないのでこんなこと知る由もないのであった
fetch使ってる人もjson()しか使ってないのでは
streamsの実装についてはdenoでstreamsを実装したで語る
streamsの仕様が、その役割に対して膨大な上あまり設計センスを感じない複雑な仕様だったせいで実装が大変だった
が、なんとか実装してfetchの実装にはいることができた
が、これもけっこう大変だった
denoでのHTTP通信についてはdenoでHTTPクライアントを実装したことがあるので楽だったが、大変なのは別の箇所だった
何が一番大変だったかというと、Request/Responseボディのストリーム化である
実を言うとまだ終わってない
multipartのformdadtaが怪しい。ていうか読み出せない
fetchゆるふわ勢(俺)はご存じないかもしれないが、fetchのbodyの型は6種類もある
string
Blob
BufferSource = ArrayBufferView | ArrayBuffer
FormData
URLSearchParams
ReadableStream
httpでデータを送信することを考えればせやな…といったラインアップではある
が、どう考えても多すぎである
httpでデータを送信するのはデータをreadしてwriteするだけなのだからこういった抽象型にされるとバラすのが面倒
細かいところは省くけど、上記の6種類のbodyは、requestを送る前、responseをparseする前にすべてReadableStreamにラップされるように仕様で決められている
これが結構面倒というか、ReadableStreamの仕様があまり良くないせいできれいに書けなかった
ともあれそれなりにちゃんと使えるようになったようです
denoのdomTypes.ReadableStreamの型定義が微妙に間違っていて、自家製Steamsとバッティングしたのが悲しい