🦁

Blitz.jsをRuby on Railsエンジニアが触ってみた感想

2021/01/03に公開
1

感想です。

何をしたか

現状でBlitz.jsで本番サービスを運用できるかの調査。
Railsで運用している本番サービスの一部機能を、3日間ほどかけて移行を試してみた。

結論

(Railsの主戦場でもある)新規事業開発の文脈でのクイックな立ち上げを想定するなら、本番運用するにはまだ厳しい。
特に、RailsユーザーとしてはActiveRecordがないのが厳しい。

開発効率そのものはRailsと比べて多少落としても、Railsよりもスケーラブルで型安全に開発したいなら、割と良い選択肢に思う。
もろもろ可能性は感じるので、引き続き応援していきたい。

良かった点(=Blitz.jsに興味を持っている理由)

型安全な開発

サーバーもフロントも全てが型に守られた開発、そしてIDEの恩恵を受けられるのは、いうまでもなく心地がいい。
型は補助輪のようなものなので、ユーザースキルが高ければ必須ではないくらいに思っているが、あるに越したことはないし、複雑なロジックを書くときは型が欲しい。
prismaによりDBのカラムの型が自動でつき、かつその型情報をフロントエンドまで使いまわせる体験はとても良かった。

API開発/繋ぎ込みの必要がなくなる

普段はRailsのAPIモード+SPA(Nuxt.js/Next.js)で開発しており、APIはRESTだったりGraphQLを使っている。
APIの開発とフロントエンド繋ぎ込みの部分は、慣れればやるだけだし工数がそこまでかかっているわけでもないが、ここの手間がない開発体験はやはり良かった。可能な限り素早く開発をするための土台を整えたいと常日頃から考えてるので、こういったところの工数が減らせるにこしたことはない。
型安全な開発がしたいだけなら他にも選択肢があるが、この点まで考慮するとフルスタックtsフレームワークしか選択肢がなく、そして現状だとblitzが一番有望だと思っている。

思想が良い

自分もとても好きなRailsの思想に影響されている。詳しくはぜひこちらで読んで欲しい。
https://blitzjs.com/

Railsの良い点の1つは、Railsというrubyにおける1強のWebフレームワークがフルスタックに全てをカバーし、そして一定の規約を押し付けることで、業界全体が足並みを揃えてRailsの知見を溜めて改善を繰り返していったことのように思う。
この話は、Railsの基本理念にも書かれているのでぜひ読んでみて欲しい。(CoC、メニューは”おまかせ”で、あたり)

Railsの生産性に関する初期のモットーは、”君は美しい唯一無二の雪の結晶というわけではない”でした。これは、無駄な個人プレーをやめれば、平凡な決断で苦労することなく、重要な場面で仕事のスピードが増す、ということを言っています。

Railsの使命の1つは「Web用に情報システムを作成している開発者が直面する”繰り返される決定”という名の木が生い茂る、成長し続けているジャングルで、ナタを振り回す」ようなものです。一度きりで終わる決定もたくさんあります。もしそのような決定をあなたのためにしてくれる人がいれば、なおさらいいです。

2. 共通の基本的なツールボックスを人々が進化させる: フルスタックフレームワークとして、Railsは動的な部分も数多くありますし、それぞれが単独でどのように機能するのかと同じくらいに、それらがどのように組み合わさって機能するのかというのが重要になります。ソフトウェアの不具合はそれぞれのコンポーネントが原因ではなく、それらの相互作用の中で発生します。構成された複数のコンポーネントから、共通の不具合を緩和しようとみんなで取り組み、同じ状態で失敗するならば、不具合の回数を減らすことができるでしょう。

https://postd.cc/rails-doctrine/

これに対して例えば今までのjs界隈は、結果として様々なフレームワークが乱立し消えていっており、業界全体でベストプラクティスを磨きあげるような力が働きづらかったように、側から見ていると感じる。(勿論それらは必要なことだったと思うが、あくまで結果として)

Blitz.jsは上記のような思想を明確に掲げているのが良い。また、フレームワークの隆盛には、OSS開発的な意味でもそれ以外の面でも良質なコミュニティを作り上げることがとても大事だと思っており、ひとりひとりのユーザーを大事にしようとしているところにも好感がもてる。
例えば、Blitz.jsについての話題を呟くと、Brandonがほぼ必ずlikeしてくれたりreplyをくれるし、公式のslackでもサポートが手厚いように見える。

諸々に感じるイケてる感

認証系がデフォルトで入っていたり、recipeと呼ばれる機能でいろんなライブラリのセットアップがサクッと終わったり、npx prisma introspect で既存DBのschemaを読んでくれて型付きのクライアントができたり、npx prisma studio でデータビューアーが立ち上がったりと、未来感がある。Railsを初めて触った時のドキドキと似たようなものを感じる。

悪かった点

ActiveRecordがない

これに尽きる。RailsユーザーがRails以外を触ると、ActiveRecordがないことに絶望する。
validationとcallbackとscope、そしてモデルに定義していたメソッドなどといったドメインロジックを各自で考えたレイヤで実装しなければならない。(callbackは悪影響が目立つので自分はあまり使わないが、それでもちょっとした用途で欲しくなる。)
またARの諸々の便利なメソッド群がない( ActiveModel::Dirty とか。)。
AR以外のORMはこんなものなのだろうが、ARでの開発に慣れた身としてはまずこの辺で徒労感を覚え、他に大きなメリットがない限りはRailsを使い続けることになる。

prismaはData MapperパターンのORMで、DDDの文脈に沿って設計をするのが良さそうに思うが、それならばそのパターンをフレームワーク側で提供して欲しく、ドメインロジックが各自のオレオレDDDにより実装されていくこと(そしてそれを自分自身が実装すること)は不毛だと思ってしまう。「正しい」DDDなんて存在せずドメインごとの事情に合わせて設計していくしかない、みたいな話はあるのだろうが。

また、それでもオレオレDDDで実装を進めればいいかと言われると、DDDの文脈による設計が有効なのは大規模なときで、小中規模のときはクラスを過剰に分ける設計に必要性を感じず、ActiveRecordパターンだったらもっとシンプルに書けるのにと思わざるを得ない。
大規模になるのを見据えて最初からそういう設計にしておこう、というのは一理あるが、自分が主戦場としている新規事業開発の文脈では、開発は基本的に試行錯誤の連続であり、すなわちサービス内容をどんどん変更したりクローズしたりするのが常なので、そんな状況で不要で過剰な設計をしていくモチベーションはない。そして、一番理想的なのはprogressive framework(Vue.jsの思想でもある)であることで、サービスの拡大とともに設計を変えられるのが良い。その意味で、初手はやはりActiveRecordパターンで、サービスの成長とともにリファクタリングしていくのが良いと考えている。
最初から大規模な開発になることが想定されているサービス、ないし他フレームワークからの移行であれば、もちろんこの限りではない。

TypeORMでも使えばいいのでは言われると、decoratorを使いたくなくてあまり調査してないので、良い感じだったらぜひ教えて欲しい。

REPLの体験が微妙

blitz console でREPLが使えること自体はとても良いのだが、現状だとRailsのようなautoloadがないのでいちいち require を書く必要があるのがダルい。(prismaのクライアント、またqueryとmutationはpreloadされる)

またこれも半分ActiveRecordの話だが、「ある条件のレコードをあるサービスに突っ込んだときに適切な挙動をするか?」みたいなのをサクッと動作確認するときに、Railsなら FooService.new(User.admin.first.comments.first).execute でできるのに、blitzで(prismaで)これをやろうとすると、 const fooService = require("app/services/fooService"); fooService(db.user.findFirst({where: { role: 'admin' }, includes: { comments: true }}).comments[0]) とかになって3倍近くコードを書くことになりダルい。
開発中にREPLはそこそこ使うのと、本番の障害対応時などで使い捨てコードを書いたり rails console -s で調査するときのことも想像すると、この辺はかなり厳しいなと感じた。

配列操作が弱い

blitzではなくjavascriptへの愚痴だが、rubyの豊かなメソッド群になれていると、色々なメソッドが足りなく感じる。
特に配列に対して unique_by やら group_by などの処理をするのは頻出なので、これをいちいち自分で書くのはダルい。ダルすぎるので自分一人のプロジェクトであればprototype定義をしてしまうが、行儀が悪いのは百も承知なので、公式でなんとかなってほしい。

まとめ

blitzがどうというよりは、prismaとtypescriptへの愚痴になってしまった。
年末くらいにもう一度触ってみたいなと思う。

Discussion