逆を言えば他の、今例に挙げていただいた3つのフレームワーク、
既存のものが小さくなくて、 特に速くもなかったみたいなところなんですかね?
それなりクラウドフェア向けなんで、 すごい小さかったりするんですけども、
今でもそうですけども、ここまでRooterにこだわっていたりとかっていうのは、
あんまりなかったかなと思います。
じゃあ差別化要因のために小さくあって、 しかもRooterにこだわりを入れたみたいな。
そうですね。
Rooterのこだわりみたいなところって、 具体的にどういったところなんですか?
Rooterが現在5個持ってて、
過去、いや6個かな。
過去未来を合わせると8個ぐらいあったという、 なぞにRooterの多いフレームワークになってます。
代表的なものを1個挙げるとしたら、 どれみたいなのあったりします?
代表的なDevXP Rooterというもので、 これも結構早くに実は導入されて、
一番最初のほうは僕が手で作ったTryRooterというのがあって、
それはいわゆるTryキーの構造のRooterになっていて、
それを一番最初に作ったんですけども、
それよりも全然早いDevXP Rooterというのを、
もう一人一緒にやってるUsaonomaさんって人が、
当初、その人が2番目ぐらいに送ってきたプルリクにDevXP Rooterというのが入っていて、
それが2022年の2月とか3月だったと思います。 かなり最初のほうですね。
すごいですね。
2回目のプルリクでRooterの拡張を入れてくるみたいなところをしてきたんですね。
そうです。
結構衝撃的じゃありませんでした?
衝撃的ですね。
しかも1番目のプルリクがTypeScriptで、
パスパラメータ、Rootingに書くパスパラメータって、
スラ、ポストスラ、コロンポストIDみたいな感じで、
コロンポストIDって書くところの方が、
後々ハンドラーの中で聞いてくるみたいなTypeScriptの結構、
意外と簡単に書けるんですけど、黒魔術的なやつを、
Usaonomaさんはプルリクの1番目に出してきたはずです。
すごいですね。
パスパラメータでいうと、そこに変数を埋め込んで、
コントローラーの方で処理できるようにするような仕組みのところですよね。
パラム括弧何とかってやると、
そこにパスパラメータ書いたポストIDが、
サデストレプリって出てくるみたいな機能ですね。
おそらくWebフレームワークを使うというか、
Webフレームワークとして本を使う上では、
かなり必須の機能を1番最初の方からプルリクとして、
外部の方に入れていただいていたみたいなところなんですね。
そうですね。TypeScriptの型を頑張るって意味では、
実はそのUsaonomaさんって人が、
実は1番最初に入れたのが結構特徴的だったっていうのが、
面白い話ですね。
すごいですね。
その時に、もちろんその時から、
Usaonomaさんがずっとコントリビュートしてくれるとは限らないわけじゃないですか。
もちろん1番最初のプルリクエストから。
分からないわけじゃないですか。
その時に結構デカめのプルリクを受け取るっていう形で、
しかも最初の方は小さくしたいし、
あと早くしたいしっていうようなところがあったのかなと思うんですけど、
設計とのぶつかり合いみたいなところは絶対あるんだろうなと思ったんですけど、
そこはなかったんですか。
実はそのまま、
例えば最初に2個目のプルリクを送ったままいなくなってたら、
それはそれで嫌だったんですが、
Usaonomaさん幸運なことにですね、
今もかなりコントリビュートしてくれているので、
本当に逆に最初の頃の設計みたいなのを一緒にかなり頑張って作った。
もう1人いたんですけど、かなり頑張って作ったので、
本当にいてくれてよかったなという、かなり俗人的な話ですけど。
って感じですね。
小さくしつつ、設計として小さくしつつ、早くしつつというのが、
逆にできてきたっていうような背景があったりしたんですかね。
そうですね。設計でいうとそうですね。
あとは僕の思想も多少はやっぱり結構あるのかな。
小さくっていう意味では。
なるべくやることを少なくするということですね。
ただルーターを増やすっていうのは、
単純に外から見るとやることが増えてるような気もするんですけど、
そこら辺についてはバッティングとかなかったんですかね。
それぞれ特化した機能をルーターごとに作るっていう意味では、
逆に特徴をつける。
例えばパターンルーターっていうのだとすごく小さくできるので、
そうするとパンダルサイズが小さいところが有利なランタイム、
例えばクラウド開発では得意みたいなことが特徴付けることができるので、
それはそれで別にいいし、機能としてはルーターの使用さえ満たせれば、
ルーターとして存在し得るので、
あとはそれ固有のルーターのメンテをすればよくて、
なので設計的にはそんなに綺麗に設計できてるので、
あとは追加するだけみたいになってますね。
なるほど。設計的に綺麗にできてる基盤部分が
かなり綺麗に最初からできているので、
その派生部分に関しては多少でかくなったとしても、
収まりいいよねみたいな感じなんですかね。
ですね。なんか割と上手くいってますね。
そこ、なるほど。
上手くいってますね。
なんとなく上手くいっているみたいなのが現状みたいなところなんですかね。
いや、ある程度意図的なんですけども、
設計というか大きな設計が上手くいったのかなと思いますね。
そこの設計の勘どころみたいなところすごい聞きたいなと思うんですけど、
なんか今考えたらこれ一番聞いたなみたいなところあったりしますか。
バージョン2か3かちょっとどこか忘れた。
もしくはマイナーバージョンなんですけども、
レイヤリングというかそのコアの機能と、
あとその他っていうのをちゃんと分けて、
最初からミドルウェアっていうのもあったんですけども、
それ以外にアダプターっていう概念と実装、
あとヘルパーっていう概念と実装、
ルーターはルーターっていう割とそのレイヤーというか機能で分けたんですね。
かつコアは小さくアダプター、
例えばCloudflare向けとかFastly向けとかNode.js向けとかっていうそれぞれの機能、
ランタイム別の機能を追加したければアダプターをくっつける。
あとはミドルウェアもベーシック認証を欲しければくっつける。
あとはヘルパーは普通に関数で呼び出すっていう形で、
本当にコアは小さいんだけど何か必要になったときに足すっていう風な、
しかもカテゴリー分けをするっていうのがうまいこと設計として後々聞いてきたのかなと思いますね。
レイヤー分けして、かつコアの部分は絶対に小さくする。
周辺の部分、何かしら機能を追加したければ周辺のところで頑張って対応していく。
ミドルウェアだったりとかそういったところで追加の部分をやっていくっていうのを徹底していた。
というか最初からやっていたっていうところなんですかね。
そうですね。途中から結構綺麗に設計できたのかな。
でもそれもやってから1,2年で早口だと思うのと。
あと特徴としてJSなんて普通にインポートしなければ、
結果としてバンドルされたところに入らないとかっていう意味では、
JS向きではあったのかもしれないですね。そういう意味では。
なるほど。バンドルしなければいいっていうところですね。
インポートして含めなければいいっていう。
そうそうそう。
ちなみにコアは小さくしてっていうのは今の話があったんですけど、
その周辺のパッケージとか炎のJSXとかいろんなものある、ミドルウェアもあるかなと思うんですけど、
そっちは小さくするみたいな思想はないんですかね。
そんな考えてない。確かに。
コアはとにかくすごいこだわってるけど、あんまり別にミドルウェアどうこうとかJSXどうこうってあんまり考えてないかもしれないですね。
じゃあ周辺のパッケージとかミドルウェアに関してはそこまでっていう思想だけども、
絶対にコアは絶対小さくっていうようなところなんですね。
それも実は割とマーケティングというか、
ベンチマーク的に早く見せた方がいいと思うので、そこは頑張るみたいなのが割とあるかもしれない。
なるほど。特徴づけるためにですね、炎を。
そうですね。
炎を特徴づけるためにコアは小さくして、ベンチマークとしてこのぐらいの速度出るよっていうのを出しやすくする、
中はちょっと言葉悪いかもしれないですけど、出しやすくするためにコアの方は小さくして、
周辺のところでカバーする、機能についてはカバーしていくみたいなことをやられてるというと。
そうですね。ベンチマーク全てじゃないですけど、結構それは測りやすいので、そういう仕様が絶対あったほうがいいと思うんで。
それと同じ系譜で、本来だとNode.jsのアダプターサーバーがあるんですけども、
それは割とベンチマークされやすいので、そっちのパフォーマンスチューニングは結構してますね。
逆に言えばあれですか、ベンチマークしづらいところはあまりカリカリにチューニングしないみたいなところはあったりしますか?
かもしれないです。
なるほど、測りやすいところで数字が出しやすいところを集中的にやっていくっていうところで。
結構あれなんですね、さっきもポロッとありましたけど、マーケティングをかなり意識されてるところはあるんですね。
確かに意識してますね。
割とOSSだったり、エンジニア機質がゴリゴリの人って、そういうところあんまり度外視する嫌いがあるかなと思うんですよね。
なのに、ゆうすけさんはそこを最初から気にするみたいなところがあったりするんですね。
とはいえ一方では、結構ベンチマークってガリガリエンジニアリングなので、
ちょっとあれですね、どっちもあるかなと思いますね。
マーケティングで見栄えももちろん大事だし、でもベンチマークいざやってみるとすごいエンジニアリングの燃えるところではあるので、
結果的にどっちもどっちかな、マーケティング的なところをやりたいなと思ったらベンチマークをやることになって、
ベンチマークをやってみたらすごいエンジニアリング的なことになってみたいな。
結構いい、ベンチマークに関してはそういう面白いところだと思いますね。
あとちょっと聞きたいのが、そこの部分でOSSとして本を開発されたかなと思うんですけど、一番最初から。
最初からマーケティングのことを考えていたのか、
それとももうベンチマークしたらこういう数字になったから、
じゃあ他のツールとの兼ね合いでちょっと差別ができるようになったのか、最初からどっちなんですかね。
本当の最初はもう本当に楽しいからとか、本当になんとなく作ってみて趣味の延長みたいな、
それこそウース・アロンさんのリジェックス・ピールーターのプルウィークが来る前ぐらいは結構楽しみでやってたんですけど、
これ早いなみたいになって、しかもやっぱり冒頭に述べたように差別化みたいな話になると、
やっぱりある程度ベンチマークしてマーケティングってことも必要になるし、
やっぱりもっと使われてほしいから、特にクラウドフェアでよく使われるようになったので、
クラウドフェアのディスコードとかにこういうの作ってるんだよとか言ったりとか、
あとはだんだんこういうのが有名になってくると、
昔元々あったフレームワークの作者からちょっと僕の方が早いよとか言ってきたりとかっていうのも実はあったりとかして、
そうするとやっぱりどんどんどんどんよくしようみたいな感じで頑張った感じですね。
なるほど。じゃあ一番最初のモチベーションとしてはやはり炎を作って、楽しいからもちろん続けていく中で、
すごく早いベンチマークというかすごい早くなってきたなっていうのをプラス、
もっともっと使ってもらいたいから周辺のマーケティング部分のところもやってみようみたいなところがモチベーションとしてあったってところですかね。
そうですね。
でもやっぱり最初は本当に楽しいから、技術的にもできそうだしっていうところがやはり一番最初のモチベーションとしてあった。
そうですね。それこそ当初の目的というかきっかけは、
クラウドヘッドワーカーズ向けのいいフレームワークがないっていうのと、
あとはそれこそトライ機のルーターを自作してみたいみたいなのがあって、
実はそこなんですよ。だから全部ルーターの話かもしれないですけども、実はそうなんです。
それも本当に趣味、勉強。
本当に技術的な好奇心というかチャレンジングみたいなところから始まってってことですね。
ですね。
ここら辺で片井さんあったりします?
そうですね。自分もやっぱりOSS作ってて、みんなにせっかく作ったからみんなに使ってほしいなと思ってブログ書いたりとか、
あとハッカーニュース投稿してみたりとか、そういうので結構みんなに使ってもらう工夫とかはいろいろするんですけど、
やっぱりその中でやっぱ炎って結構気立ちがいに広く使われてるなと思ってるので、
やっぱそこは本当にうまく回ったんじゃないかなと思ってたりします。
うまくいきましたね。
あとはクラウドフェアの話ばっかりしてましたけども、実はバンとかディノとかのランタイムに対応も最初出してからちょっとした後にしたんですね。
そのときに、例えばバンとかって当初エクスプレスが動かなかったし、いいフレームワークもなかったんで、炎があるよって言うとみんな結構それを使ってくれたんですよ。
だからうまく運が良かったとも言える実は。
時代的にバンのリリースとちょっといい感じに相乗効果で乗れたというところが実際ある。
あとやっぱりウェブスタンダード、ブラウザで動くようなAPIがサーバーサイドでも使えますみたいな時代、割と新しい時代。
エクスプレスとかノードJSの次の時代のフレームワークっていうのがあんまりなかったところで、ちょうどよく僕が結局トライルーターを試そうって作ったタイミングと割とちゃんと合ってたっていう。
それこそ運が良かったのかなと思いますね。
炎ってもちろんノードJSに依存しているわけじゃないじゃないですか、ピュアなJSで動いているのかなと思っているんですけど、
それをピュアなJSとして書こうと思ったというか、一番最初大きな多分決定だと思うんですけど、
それってそもそもクラウドフレアワーカーズに対応したいからそうなったってことはどうなんですかね?
そうですね、ていうかむしろノードJSのアプリケーションを実は書いたことがなかった。むしろ本当に。
だからむしろ書き方が分からないぐらいでしたね。
なるほど、書き方が分からないから別にそれをやらなかったっていう話ではないとは思いますけどね、きっと。
選択肢として普通にピュアなJSからやったっていう。
本当に今でも本当にフレームワークを作っているだけで、ノードJSのアプリケーションを作ったこと、運用するアプリケーションを作ったことがないです。
そこでちょっと気になるのが、ノードJS系の、例えばExpressとかいろんなフレームワークあると思うんですけど、そこら辺を参考にしたことってないんですかね?
見た目のAPIはExpressのAppGetなんたらみたいなのを参考にしているのと、あとCoreっていうフレームワークのミドルウェイを束ねるCompose.tsっていうファイルであるんですけども、そこの実装はかなり参考にしましたね。
じゃあそこの部分で実際にExpressのコード読んでみたいな。
Coreは読んでますね。Expressはあんま読んでないかもしれないですね。
あとはExpressのルーターをベンチマークというかに、よりも速くなるよっていう意味では参考にはしましたね。
実装というよりかはベンチマークの対象としてExpressはありましたね。
なるほど。じゃあ実際に動かしてベンチマークして、このぐらいの速度だから本能だったらこのぐらい目指したいよねみたいな。
ですです。
実際ベンチマークでどのぐらい本能の方が速かったりするんですか。
Expressだと普通のHello Worldとかだと3倍ぐらい速いはず。
本能の方が3倍速い。すごい。それはリクエストからレスポンス返ってくるまでの。
普通のHello Worldとですね、ただ他の分で速いところもあるだろうし、同じぐらいのところもあるだろうし、
でも本当に分かりやすいのはやっぱりJSのファイルサイズが違うんで、
1回立ち上がったら別に変わらないよっていう環境だったら、でかくてもいいんですけども。
小さい方が有利な場合とかっていうのは本能の方が全然小さいなと思いますね。
立ち上がりの速度ってところですよね。一番気にしたいのはバンドルサイズを小さくしたいっていうのは、
起動までの速度が非常に重要になるからってところですかね。
そうそう。それもランタイムによりますね。やっぱりいわゆるエッジ環境だと立ち上がりというか、立ち上がりなのかな。
そういう意味でファイルサイズが小さい方が有利っていうのがクラウドフェアではデータとして出てるし、出てますね。
じゃあもう小さければ正義だからっていうところ。
そうですね。あとはメモリ効率の版とかでもいいはずです。
ちなみに版とか他のクラウドフェアワーカーズ以外のエンジンに対応したときの難しさみたいなところってあったりしたんですかね。
Node.js以外はあんまりないですね。
ないんですね。
でもDenoは面倒でしたね。
どういうところが。
インポートの書き方が微妙で結構違って、.tsとかファイル指定をしなくちゃいけなかったりとかするんで、
それの書き換えをするためのスクリプトみたいなのを回して、一時期は2つダブってファイルがあったときもありましたね。
リポジトリの中に.ts、インポート.tsを入れるバージョンと入れないバージョンが共存してたと。
実はありました。
なかなか面倒くさい時期ですね。
なかなか面倒くさいです。他にも多分制約があったのと、
あと.tsの型のチェックがDenoだとすごいやたらと厳しかった気がします。
ストリクトみたいなところが割と厳しめだったんですかね。
警告が出てしまうみたいなところがあった。
それか何か潰したか何かしたような気がします。
握り潰して見なかったことにするみたいなことをしたときもあるという。
ちょっと面倒でしたね。Denoは。
現状は特にファイル分割されていてとかそういうことではないってことなんですか。
そういうことではないですね。
Denoの場合はアップロードする先がNPMでも扱えると思うんですけど、JSRっていうレポジトリに入れてますね。
JSRっていうのは結構Denoのライブラリーが上がるような場所でそこにアップロードしていますね。
だからリリース先が違うってことですか。
です。だからリリース先は今NPMとJSRにどっちもリリースしてますね。
なるほど。NPM一択じゃないんですね。Denoから引けるようにってことで。
そこら辺の2つリリースするの面倒くさかったりするんですかね。そこまででもないですか。
セットアップがだるいかったのと、リリース自体はCIでうまく合わせればいいんですが、今でもあるんですけど、例えばJSRの炎を使っておいてNPMの炎のミドルウェアを使うと型が合わないみたいな問題があって。
組み合わせの問題ですかね、それは。
TSっておそらくこういうことだと思うんですけども、参照するファイルが違うと型が合わないんですよ。
参照するファイルが違うと型が合わない。参照ファイル。
炎のバージョン4と4を使って、4.1を使ってて、本当は4.1、バリデータのミドルウェアが4.2で、上手いこと同じファイルを参照すればいいんですけども、
バージョン違いのファイルを置く、例えばPNPMとかそうかもしれないですけども、そうすると違うファイルを参照するんで、同じ炎でもバージョンが違うだけで型が合わないみたいなのが起こる。
別々の炎のバージョンがローカルというかNPMパッケージとかにインストールされてしまっていて、別々のものを参照し合ってるってことですね。
そうです。
ローカルで。
そうです。なのでJSRの炎とNPMの炎のミドルウェアみたいなのって機能的には、ランタイムというか機能的には一緒にできるんですけども、TypeScriptの型的にはずれちゃうという。
面倒くさいですね。
それが結構一周で上がることは昔ありました。
現実その2つ一緒に使うことあるんですか?
なんかね、あったりとかします。
あるんですね。同じプロジェクトで。
というのは、すげえ微妙な問題ですけど、炎本体はJSRに上げたんだけど、炎周辺のミドルウェアはNPMにしかないみたいなのがあったんですよ。
なるほど。その場合はデノを使ってるんだけど、JSRから基本はコアの部分は引くんだけど、NPMからのパスするというかトラクシーみたいなやつでインポートするから競合が発生すると。
確かにそれはありそうです。
正直、自分じゃやんねえだろうって思っても一周で上がるんで、それはどういうことなんだろうって調べたらそういうことなんですね。
なるほど、そういう環境もあると。
あります。
それ対応どうしたんですか?
ちゃんとJSRとNPMの方で同じものを全部完璧にリリースしないといけないみたいなところが多分キレイなのかなと思うんですけど。
もう無理なのは無理っていうふうに書いておくのと、あとはそのミドルウェア自体もJSRに対応するのを増やしましたね。
リリースを増やしたってことですね。
JSRにリリースするようにしました。
やっぱりそのパワーで解決というか、パッケージを増やしてってことですね、リリース先を。
主要なものに関してはJSRでリリースするよねみたいなルールにしたってことですね。
そうです。めっちゃ大変でしたそれは。
なんか。
手動でフォームでなんかポチポチするのが多かったんで。
ですよね。
なんかすごいね。
一番最初のセットアップがすごく面倒くさそうだなと。
そうです。
まあまあでも一回やってしまえばということですね。
そうですね。
ただあれですね、主要な周辺のパッケージが増えれば増えるほどその作業を2回やることが増えるってことですよね。
今後も。
まあまあまあ。最初だけですけどね。
ちょっと面倒くさいけどもって感じですね。
そうそうそう。
なるほど。ここら辺で片手さんあったりします?
うーん、自分はその辺あんまり経験ないですからね。
リリースに関してみたいなところですかね。
そうですね。自分は普段Goばっかり使ってるんで、その辺で悩んだことはあんまりないですね。
確かにGoは悩まないですね。
確かになんかリリースストアが複数あるってJSぐらいですかね。Rubyとかの場合も別に一つだし、Perlとかも一つだし。
確かに。
うん、確かに。
珍しいな。
パッと思いつかないですね。
そもそもJSなのに上げてるのも少ないと思うんですけども、本来の場合はDのサポートも歌ってるんで上げたほうがいいかなという感じはしますね。
基本はNPMですもんね、JSの場合は。
確かにね、複数ストアという、複数リリースレジストリみたいなのがあんまりないなというのが確かに、
独自の悩みなのかもしれないですけど、炎独自の。
こんだけ有名なOSSの場合は対応が必要になってくるみたいなところかなと思うんですけど。
あと他に炎といえばみたいなところで、ファストパスを用意する。
これはSugar Syntaxみたいなものですかね、ファストパスっていうのがいわゆる。
そうですね。よくぞ、ご存じでって感じですけども。結構その内部の実装では、本当それこそさっき言ったベンチマークみたいなのがやっぱり大きくて、ベンチマークである程度、ファストパスはあったほうがよくて。
例えばテキストのレスポンスを返すときに、JSONだったらJSON組み立てるんだけど、
例えば本当にHello Worldでヘッダーも特に指定しないですよ、ただのテキストですよってときは、すごい早く返すみたいな、いわゆるファストパスみたいなのをある程度いろんな、そんなないですけども、入れたりとかしてるんですけども、
それこそ本当に典型的なパターンに関してはそのファストパスを通るみたいなことをやっていて、
その理由の一つはベンチマークで勝つからみたいなのは多少あったりしますね。
ベンチマークのためにこのケースはファストパスを用意してちょっと早くするみたいなのが一部ではある。
ちなみによくあるケースというか、ファストパスをこれはファストパスにしようみたいなのって、ベンチマーク以外にも実際あるだろうなと思うんですけど、ベンチマーク理由以外に。
そういうのってどうやって決定するんですか。
いくつかパターンはあるんですけども、この本体でいうと面白いのは、オブジェクトの生成、例えばHeaders Objectってあるじゃないですか。
オブジェクトの生成って、レスポンスでもリクエストでもいいんですけども、生成するのすごいコストがかかるんですよ。
時間がかかる。あんまりここまで気にしてる人はあんまりいないと思うんですけども、やっぱり本能だと気にするんで。
例えば、これもランタイムによってどれほど差が出るかっていうのはあるんですが、例えばレスポンスオブジェクトを作ってレスポンスを返すときに、
HeadersってプロパティにHeaders Objectを作ってから入れるのと、HeadersObjectを作らずにレコードを渡して内部的に何か処理してもらうのと、この2つパターンがあって。
以前の版、今はわからないけど、以前の版ではHeaders Objectを作ると遅くて、レコードを渡した方が明らかに早かったんです。
今は正直わからないんですけども、昔は明らかに下がったんです。
そうすると、なるべくHeaders Objectを作らないままコンテキストの中で保持して、レスポンスを返すときに、
必要なかったらHeaders Objectを作らずにレスポンスオブジェクトの中にレコードを入れて返すよみたいなのが、いわゆるファストパスに近い発想でやってましたね。
ちなみにヘッダーオブジェクトを作るオーバーヘッドがかかってしまうってことだと思うんですけど、
それってどのぐらいのオーバーヘッドがかかるんですかね。
基本的には多分無視していい範囲だと思うんですが、普通に使う分には。
炎ではそこがボトルネックになった、ボトルネックではないかもしれないですけど、そこが気になったっていうところなんですけど、どのぐらいなんですかね。
あんま覚えてないですけども、ベンチマークである程度はやっぱりわかるぐらいですね。
差が出るぐらいなんですね。明確に差が出るぐらい差が生じてしまうので、ファストパスを用意するみたいな。
差が出ないかもしれないですね。そんな差が出ないかもしれないですけども、数字を見るとこっちの方が早いよねってのがわかるぐらいですね。
差があったのでそっちを採用した。
これも面白いのは、バンだと明らかな差が出るけど、しかも前のバーのバージョンです。今はちょっとわからないんで、ノードJSだとそんな変わんないとかあります?
そこは使ってるエンジンの内部の設計の違いなんですかね。
だと思います。
ジットコンパイルとかもしてるので、そういうのの差なのかもしれないし、
ただやっぱ重要なのって、他の人もベンチマーク取った時に炎遅いなって思われるかもしれないじゃないですか。
実は炎じゃなくてその書き方の問題で遅いだけなのに、炎が遅いって勘違いされてしまうケースとかもあるので、
早くなる書き方を誘導していくって結構意外と大事なんじゃないかなって、特に炎の場合は大事なんじゃないかなって今聞いてて思いましたね。
見え方っていうのは結構正直ありますね。
実際一周とか、いろんなユーザーとのやり取りの中で、このケースだと遅いんだけどみたいな言うときに、このファストパスあるよみたいなそういう回答したことってあったりするんですか?
それはそんなないかもしれないですね。そんなないかもしれない。だからやっぱり本当にベンチマークだけな感じもしますね。
本当にチューニングするときに?
正直あんまりこれが遅いからだめなんだよみたいな意思はあんまり立たないですね。
なるほど。実際に運用していく上で、ここの部分遅いんだけどどうにかしてくれないみたいなのはあんまない?
ない。あるのはメモリがリークするとかっていうのがちょっとあったんですが、それもこのキーなのかもわからないって感じですね。
基本ランタイムキーですよね。正直メモリリークするような書き方って基本できないと思うんで。
できない。やっぱりやってること少ないんで。
そのメモリリークにもファストパスは寄与するんですかね?
ないと思いますね。ないと思います。なのでパフォーマンスで文句言われることはないっていうのは正直なところです。
基本は今のところはないって。
自分たちがただ求めてるだけという。
ちなみにファストパスはよくありがちな設計というか、やる方法として2パターン用意されるわけじゃないですか。
同じことをやるために2つのパターンが2つの書き方がありますよって形に結局になっちゃうわけじゃないですか。
それで問題になったことってあったりするんですか?なんか不具合があったとか。
これで良かれってやったことが実はダメで戻したみたいのはいくつかある気はしてて。
具体的には。
1個は思いつくのは、JSONのレスポンスを返すときに今、オブジェクトをもらってJSON Stringifyをやって、
これをボディにしてコンテンツタイプをアプリケーションスラッシュJSONにするみたいなやり方をしてるんですが、
場合によってはレスポンスについているスタティックメソッド、Response.JSONをした方が同じなんですけど、そっちの方が早いっていう場合があって。
それをやったんだけど、Response.JSONってランタイムによって実は微妙に違うんで、
やめたみたいなのもありましたね。
パスとパスの例で言うと。
なるほど。ランタイム側の実装の差によって微妙な挙動の違いがあったから、それはリジェクトというかリバートした。
リバートした。良かれと思ってやったんだけどみたいな。
それどうやって気づいたんですか?
試してて気づきましたね。
デバッグというか。
そうそう。DNode版とは違うみたいなのがあったはず。
それも計測してて気づいたっていうところなんですかね。
そうですね。
やはりはちゃんと確認しつつ、やっぱりランタイムキーの微妙な差異があるからできないっていうところは現実あるですね。
ありますね。先ほど言ったHeaders ObjectをResponseに入れるっていうのも、実はNodeだとそんな差がないとかってあるので、
ベンチマーク的に見ても、バンで測ったけどNodeだと違うなみたいなのが本当によくあるんで。
一応僕とか僕らは、バンのベンチマークを一応ベースにしてるというか、
他の結構立派なベンチマーク、立派というか指標となるベンチマークを作ってる人がいて、
いろんなベンチマークがあるんですけども、そこを参考にして、それはバンのベンチマークなので、結構バンで取ったりとかしますね。
バンが一番のベンチマークの指標、メイン指標なんですね。
そこに揃えてるって感じですね。
始まりはクラウドフレアワーカーズじゃないですか。バンじゃないと思うんですけど、エンジンは。
全然違うものかなと思うんですけど、そこには合わせないって感じじゃないですか。
クラウドフレアはベンチとんのは多分すごく難しくて、まずデプロイしたものでベンチするのはちょっとやっぱり難説なのと、
そもそもローカルで動くランタイムが当時なかったのと、今でこそワーカーDとかあるんですけども、それを立ち上げてベンチするのは確かすごい揺れが多かったんで。
最初の頃どうやってベンチ取ってたかっていうと、アプリケーション全体のベンチじゃなくてループターだけベンチ取ってたんですよ。
ワーカーズのベンチは難しい。とあるときにバンが出てきて、バンだとベンチ取りやすい。
HTTPサーバーを立てて、ABじゃなくてオートキャノンでもなくボンバディアっていうのを叩くんですけども、
そうするとバンで早いと呼ばれてるエリシアっていうフレームワークがあって、めっちゃ早いんですけども、その作者がバンのHTTPのベンチマークを作ったんですね。
結構そこを参考にするので、そこに合わせてます。
先行事例があったからバンのものをベンチマークとしているみたいなところが一番でかい。
でかいですね。
あと回しやすいっていうのもでかいですね。
回しやすいですね。それはその人が作ったやつをスクリプトになってて、本当にダウンロードして叩くだけで回してくれるんで便利ですね。
かなり便利ですね。
ここからは最近やられてるみたいなところの話聞けたらなと思うんですけど、最近はAgent DXとかこのCLIとか、
AI系ですかね、基本的には。
AIに対して、AIアジェントに対してどうにかするみたいな、そういうところが主なのかなと思うんですけど、ここら辺何か作る思想みたいなのあったりしますか。
これまであんまり実はAI向けのことってあんまりやってこなかったんですけど、
やっぱりこの時代なんで、AIコーディングエージェントからいかに使いやすいフレームワークにするかみたいな、やっぱりちょっと考えたいと思ってて。
去年に炎CLIっていうのを作ったんですね。これは人間とAIのためのCLIみたいなことを謳っていて、サーバーを立ち上げずに炎のアプリケーションをデバッグできるみたいな機能があるんですよ。
結構好きで、それでAIにとって使いやすいよねみたいな前提でいて、ただ炎CLIってあんまりメンテというか新機能追加してなかったんですけども、
いよいよそういうエージェント向けの機能というか、よくしていこうという時に炎CLI使えるんじゃないかなと思って。
本当に炎CLIが去年なんとなく良いだろうと思ってやってたことって、本当に良いかなっていうのをやっぱり疑わなくちゃいけなくて。
今、Agent DXっていう名前を僕は勝手につけて、そのエージェントにとってのデベロッパーエクスペリエンスみたいなのをちゃんと図ろうっていうのを試みている最中ですね。
なるほど。じゃあ、Agent DXのほうで本腰入れて、エージェントに対するデベロッパーエクスペリエンスを高めていくみたいなところをやってる。
なんかこう思想的な、いろんなことあると思うんですよね。今言ってもらったサーバーを立ち上げなくてもアプリをテストできるみたいなのって、
かなりエージェンティックっていうか、AIにとって使いやすいみたいな考え方なのかなと思うんですけど、
Agent DXだとどういうところがAIさんにDX高いんですかね。
それを本当に測ってる最中でですね。測る手法があって、これはすごい一般的な言葉なんですけど、AIのevalっていう手法があって、
それは実際にモデルを動かして出てきた結果をテストする。その通りなんですけども、今いくつかやってて、
例えばアプリケーションを作ってくださいとか、JSON回数だけのアプリ作ってくださいとか、クラット作ってくださいというふうに雑にAIに渡すと、
どれだけ炎を採択するかとかそういうのを調べたりとか、あとは炎を使ったときにいかに効率的にAIは行動をかけるかとか測ってるんですけども、
最後にやってるのが、CLIなりスキルを入れることで、AIがいかに炎をうまく使えるかみたいなのを測ってるんですよ。それがうまくいけば、このCLIの意味があるじゃないですか。
ただ、実は炎はもともとサーバーを立ち上げなくてもテストできる関数がもともと生えてるので、それを実はAIがかき捨ての行動でそれを使って書くと、結局同じことをしてるので、
それをやられたらあんまり差がないみたいなのが出たりとかしてて、結構面白い結果になってます。
このCLIがやろうとしていたところを、かき捨てのAIがかき捨てで作ってくると、テンポラリーに。
これはもともと、AIが知ってばなんですけどもともと炎が結構テストしやすい関数とか、あとは会社向けのインスペクトするような機能を提供してるので、案外それ使っちゃえばAIがよろしくやってしまうっていう意味では、
逆に言うと炎本体がいいテスト用のツールを提供してたってことなんですけども、結構面白いなと思って。
それが別の角度から分かったってことですね。検証ができたってことですね、Agent DXを作ったことによって。
なるほど、炎の炎コア自体の設計がまずもってAI対応されてたっていうところですね。
割と良かったんじゃないですかね。
ただ、とはいえケースによっては、メソッドを書いてたくさん何回もやっちゃうんじゃなくて、このCLIの機能でバッチみたいな機能をやると一発ですぐみたいな、そういう最適化はできたりはするんですが。
とはいえっていうことですね。
とはいえ、結構もともとよくできてた。
もともとよくできてた部分のところ、ちょっと解像度を高くしたいなと思うんですけど、どういうところが効いてきたみたいなのがあったりします?具体的に。
超具体的に言うと、僕も好きな機能なんですけど、App.Requestっていうメソッドがありまして、これを使うと炎に登録されているハンドラーをサーバーを立ち上げないでも呼び出せる。
で、返ってきたのがPromiseで含まれたResponse Objectである。
めちゃくちゃ使いやすいですね、AIから。
テンポラリーにJS書いてもらって、App.Requestでスラーなんちゃらみたいなことを書いてもらえば、炎のルーターの部分の関数呼び出せるってことですもんね、具体的には。
ノードの開発サーバーとかラングラーとか、下手するとAIめっちゃ立ち上げるじゃないですか。
ああいうのがうまく誘導してあげると、やらなくて済むようになるのではということですね。
普通だったらエンドトゥエンドのテストする場合には、テストの環境を作って、その中でMockサーバーとか作って、それに対してリクエストするみたいなことをしがちですが、それがMockサーバーもいらないしっていうことですもんね、本当の場合は。
その場合ってデータのMockとかってどうするんですかな、App.Requestでリクエストする場合。
かけ捨てのスクリプトとかでもいいと思うんですけど。
基本的には、立ち上がったプロセスの状態が報じされるので、そこでデータベースが参照されればよくて。
例えばクラウドフェアワーカーだと、ちょっと特殊なんですけども、バインディングっていうのでデータベースとかオブジェクトストレージ除くんですけども、うまくやればそこにクラウドフェアの環境を注入することができるので、実はデータを除いたりっていうのもシミュレートすることができます。
なるほど、じゃあローカル環境でクラウドフェアの環境を作っていくコマンドありますよね。
あれでエミュレートして、そちらを参照する、ローカルのDBを参照するみたいなことができるということですね。
できますね、コマンドではないんですけど、できます。そういう方法があります。
注入してってことですね、実行時に。
確かにそれだったらかなり簡単にエンドツーエンドのテスト、API周りのエンドツーエンドテストを書いて検証するみたいなことが高速に行えるってことですかね。
そうですね、ちょっと話ずれますけども、Honoの本体というか、開発用に作っているレポジトリはHonoアップリクエストのテストがめっちゃ書いてあります。
そうですね、実はサーバーを立ち上げてテストするっていうのはHonoコアではやってないです。
もうすべて。
ほぼやってないです。
アップドットリクエスト経由でのテストをしていると。
実際にただとはいえサーバーを立ち上げてテストしないといけないところも若干はあるんじゃないのかなと思うんですけど、その部分ってむしろないってことですかね。
コアの中心機能はないです。
これがすごいところなんですけども、たとえばクラウドフェアとかNodeとかFastlyとかDenoとかBANとかって、実際サーバー立ち上げないと無理なところがあったりするんですが、そのランタイム別のテストは、
ランタイムテストっていうので、またコアのテストとは別のディレクトリランタイムテストっていうのがあるんで、そこで場合によってはサーバーを立ち上げてるところもあります。
そっちは特化してってことですよね。各エンジン特化でテストを書いてるっていうわけかたをして。
コアは本当にサーバー立ち上げないでリクエストレスポンスだけで全部やってます。
すごい雑なイメージだとめちゃくちゃ開発しやすいだろうなと思いますね、コアの開発。
開発しやすい。開発はしやすいしテストも早いです。
ですよね。CIも実行早いですよね、単純に。
すごい理想な環境だなと思うんですよ。でもそれは本当にもうコアが素結合というか、本当にピュアなものとして作られてるからこそできているっていうところがでかいですよね、やっぱり一番。
やっぱりもともとのWebスタンダードっていうのがすごく思想というか、実装思想、あとはブラウザでもともと動いてたものが動くっていう意味ではすごく使いやすいですね。
やっぱりできる限り依存を少なくとか小さく保つ。コアの部分に関してはもうそれ単体で動くようにする。
しかもテストもしやすいというかサーバー立てなくてもいいようにするみたいなのはかなり設計のところが本当に重要になってくるんだろう。
それを維持するための設計っていうのが重要になってくるんだろうなと思うんですけど。
なんかここらへんの設計というか、依存関係少なく頑張るみたいなところがあったりします?
依存関係。そもそもちょっと前の話だと、エーマのAIってやっぱりAIにいかに試行錯誤させるかで、AIに出してくるコードの角度って全然変わってくるので、
やっぱりそのAI側が試行錯誤しやすくなってる設計ってすごいAI向きだなってすごい改めて思いましたね。
やっぱりその辺もそうですね、ちゃんと設計が綺麗だからこそその辺もちゃんと外部通信も発生せずにテストも全部かけるようになってるので、
その辺はすごいなるほどなと今聞いてて思いましたね。
設計がなせる技ですね。
とはいえ自分でその設計とか、例えば関数名とか名付けみたいなのがうまくいってるかっていうと、
いやそうでもないものがなんか世の中に広まってしまったみたいな変な感じもあります。
反省点みたいなところも結構あると。
100%じゃないよなって思いつつも、じゃあ他のあったかなと思うとないんだけど、ないんだけどすごい微妙なものが実は世の中に出回ってる可能性もあるなみたいなちょっと考えてる気がします。
なんか今思うそのモヤモヤポイントっていうか、こここうすればよかったみたいなのあったりします?
そうですね。
SeaRigQueryとかSeaRigParamとかSeaRigQueriesとかなんだった?
パラムをパラムSにした方がよかったのか。
でもこれだったら関数系かみたいな、そういう細かいところの文字の扱い方。
あとSeaRigでリクエストのものを取れますけど、Sea.headerとかSea.textとかでレスポンス系をリクエストっていう文字を挟まないでできるんですけども、
Sea.lessの方がよかったのかなと。
あとSea.reqのリクなのか、それともリクエストにした方がよかったのかとかそういうところを考えてしまう。
なるほど、APIの名前付けというかどうアクセスするかで、どこを短縮するかってところですね。
そういうところは今から直そうとすると結構めんどくさいところですね。
一方では結構説明的というか長く作った変数名関数名が結構あったりするので、その辺がぐちゃぐちゃしてるなとは自分で思うんですけど。
心の中でここちょっとぐちゃってんだよなみたいな心残りがある。
実は結構ある。
若干一貫性がある。
そういう意味って作者だからあるというか、多分使ってる側はあんまり気にしてないと思うんですよね。
やっぱり自分もそういうのあるんで、やっぱり作者だとこうしとけばもっと良くなったのになとか思うことあるんですけど。
でもユーザー側は正直そんなに気にしてないと思いますね。
じゃあ良いですね。
そうですね。確かに書いてる本人は気にしがちだけども、使う方はあんまり気にしないというのはありがちだと思うので。
さらに言うとAI越しに使うと全く気にしないみたいなところがより今後あるかもしれないのでね。
確かに。本当思うんですよ。これ最後の方なんであるかもしれないですけども。
それこそAIがいわゆる技術選定みたいなのを知らすと、パッケージ.jsonに何がDependencyで入ってるかなんて人間気にしなくなると、炎が入ってるかどうか気にしなくなるじゃないですか。
でもそれは実際あるとは思います。
本当に。
できたもので判断するので依存関係を見ないみたいなのは、エンジニアじゃないとより顕著ですよね。より顕著というかエンジニアじゃない場合は多分見ないってことだと思うんですけど。
そうすると炎の作者ですって言ってちょっと引っ張るというか受けを取れたのが誰も知らなくなってしまう。
実はみんな炎使ってるのに炎使ってるって知らないからみたいな感じですよね。
まじであり得る世界観。
その場合はあなたのパッケージ.json見せてくださいみたいな感じです。
ほらここに炎ってあるでしょみたいな感じですね。その時代になってしまったら。
ソフトウェア開発とかOSSってめっちゃ、逆に片杉さんどう思いますかというのは変わりますよねってすごい雑な話ですけども、変わりますよね。
そうですね。さすがに自分は何の依存が増えたのかとか絶対見てますけど、その辺の温度感も人によるだろうし、なかなかその辺どうなるんですかねというのは難しいですよね。
実際何か本当にあんまり知識がないやつを作らせたりすると自分が見たことないライブラリー使っていることとかもあるんですよね。
そうなると他のライブラリーあんのかなとかいちいちちゃんと調べないと出てこないし、それをじゃあ全部一個一個全部に対してやるかって言ったら正直やらない人がほとんどだと思うんですよ。
そうなると最初の実装で炎使われてたからそのまま炎のままでってなる人が圧倒的に多そうだし、
炎じゃないやつで作ってきてても特に困ってないんだったらそのままいっちゃうんじゃないかなっていう気はしますよね。
そうですね。
そうですね。
ちょっとエンジニアとしてはそこにこだわり持ってほしいなと思いますけどね。
一個人の希望的観測からすると。
自分もどういうの使ってるかとか見てますけども、そのうちノーロックになる可能性はあるなとは思いつつライブラリを作ってますね。
でもその中でも自動的に選ばれていくっていうのは現時点でもかなり選ばれているとは思うのに関しては。
それこそエージェントDXみたいなのでちょっと測ったりとかしてて、まあまあ使われておりますね、エージェントから。
なのでその時点でもすごいっていうような形だと思いますけどね、本当に。
逆に言うとあれですよね、例えば炎の微妙だって思ってるところを直した、新しい炎作りましたってなっても、
多分ずっと炎が使われて新しい炎は使われないんじゃないかとか、
今から新しいライブラリ作った時にそれ使ってもらえるのかって問題はあるなってちょっと思ってたりしますね。
ありますね、ありますし、結構古いのを使うんですよね、エージェントさんは。
そうですね。
結構古いの、だからそれこそスキルみたいので起動修正してあげないと古いの使い続けちゃうんですよね。
ちなみに今から炎みたいな、頑張ってOSS使われるようにしようみたいなの作るとしたらどうやります?どうマーケティングしていくみたいなのあったりします?
超むずい質問ですね。エージェント向きなのはそうだと思うんですけど、超むずいですね。
例えばあれですよね、今からOSSを作るとしたらどんな作るかとかそういう話ですよね。
何作るかな?
作るもそうだし、何を作るかもそうだし、どう進めていくかみたいなところも結構重要かなと思ってて。
そうですね。むずいですね。めっちゃむずいですね。その一つの答えが、エージェントTXとかHonnoCLの最適化みたいなことではあるんですが、むずいですね。そもそも何作るかっていうのはむずいですね、やっぱり。
そもそも自分の課題があった上での炎ですもんね、始まりは。あとは技術的な挑戦。
ですね。ただ今だと本当にチャットで何でも作っちゃう世界なので、じゃあ何作ろうっていうのは難しい感じもしますね。
なるほど。何かあったとしてもパッと作ってで駆け捨てでそれでいいじゃんみたいな。
なりますね。
ただインフラとか、インフラは大事な気はしますけどね。アプリケーションをデプロイしたり、それこそ炎も結構ベースのレイヤーなので、今から炎を作るのは難しいとはいえ炎はやっぱり大事で、
というのは炎はパフォーマンスもしっかりしてるし、まあまあセキュリティ的なところもしっかりしてるし、ちっちゃいしっていう意味では炎を使ったほうがいいじゃないですか、結局言い合いも。
っていう意味ではまあまあ太って変わられないっていう意味ではいいんですが炎以外作るって言ったら難しいですね。
そうですね。ただ今の話の中だったらOSSとしてやっていくというか、作るんだったら基盤部分できる限りテイレイヤーの部分のほうが基盤としていいんじゃないかみたいなところは1個あるって感じですか。
案外そうなんじゃないですかね。太って変わられない部分っていうのはまあまああるのかなと思いますけどね。
まあなんか1個のライブラリーとかではなくてってことですかね。
もうありますね。難しいですねこの時代で。
今過渡期なんでわからないとしか。
案内ちゃいますね。
小さいユーティル系とかだとAIに作らせればいいから使わないし、ルーターみたいなのって大体めんどくさいし、とにかく早ければ早くて書きやすかったら大体の人は満足するので、やっぱり炎みたいなやつ使いたいって多分大体の人はなるんですよね。
そこの境目を見つける必要がある気がしていて、結構難しいですよね以前より。
僕はちょっと前にAXっていうアックスって呼んでもいいんですけども、カールとかカールプラスパイソンの書き捨てスクリプトでJSONをパースするみたいなのじゃなくて、JSONあとはHTMLをパースするっていうのを組み合わせでやるんじゃなくて、
コマンド自体に入っているJSONをパースすることも組み合わせたカールみたいなコマンドを作って、まあまあ便利なんですけども、例えばそういうAIがやっているちょっと面倒なことをサポートするためのユーティリティとかもまあまああるかもしれないとは思いますね。
AIが作ってくるシェルスクリプトみたいなのの省略版みたいなことですね。
そうですね。トークンを減らすっていうアプローチもまあまあありなのかもしれないですね。ただそれも使われないという意味ないですけどね。
そうですね。AIに選ばれないといけないというところが一番難しいのかもしれないですね。
スキル読ますのだって一応コストっちゃコストですからね。
なるほど。結論は多分難しいんだと思いますね。
なかなか答えが出ていない話ですね。
はい。答えわかる人いないと思うので、すごい難しい質問かなと思うんですけど。ありがとうございます。