Don't Repeat Yourself

Don't Repeat Yourself (DRY) is a principle of software development aimed at reducing repetition of all kinds. -- wikipedia

『RustによるWebアプリケーション開発 設計からリリース・運用まで』という本を共著で書きました

RustのWebアプリケーション開発に関する書籍を共著で執筆しました。1年くらい執筆していましたが、出版時期などが定まってきたので内容の紹介を込めて告知の記事を書きます。9/26刊行予定です。予約よろしくお願いします。

RustによるWebアプリケーション開発

AmazonのURL(アフィリエイトなし) www.amazon.co.jp

数年前に書籍を執筆した際に、「次はWebアプリケーションの実装に関する本を書きたい」と記事に書き残していたのを今見つけたのですが、有言実行できたようです。

どんな本か?

RustでWebアプリケーションの実装や運用を行うには?という疑問に答える一冊です。より応用的なRustの使い方、使えるクレートの紹介など、「現場で実際に使える」トピックを盛り込むことを意識しました。

まず大前提として、Rustの文法や機能の入門書ではありません。Rustの文法や機能に関する基本的な解説は一切含まれていません。なので、取り掛かる前にRustの入門書を一冊以上ないしは公式のチュートリアルをこなすなどして、基本的な使い方はキャッチアップすることをお勧めします。

本書はRustでいわゆるWebアプリケーションの「バックエンド」を開発する書籍です。HTTPをしゃべるサーバーを実装する話がメインです。axumというRustでは最近よく用いられるHTTPサーバーを実装できるライブラリを使って実装します。なお、以下本書で扱う開発の範囲を便宜的に「バックエンド開発」と称します。

バックエンド開発では、たとえば実装スピードを向上させたり保守性を高めたりするためによく利用されるテクニックがいくつかあると思います。しかし、Rustのコミュニティには、そうしたテクニックを使いながらRustでバックエンド開発を行うためにはどうすればよいのか?といった情報や、まずまずな規模のアプリケーションを実装し切るような知見がまだまだ不足しているのではないかという問題意識がありました。このバックエンド開発における「Rust入門以後」を進んでいくにあたり、ガイドとなるような一冊を目指しています。そういうわけで、すでに会社でRustでのバックエンド開発を経験している方には、あまり新しい発見はないかもしれません。

「Webアプリケーション」というとフロントエンドも思い浮かべるかもしれませんが、フロントエンドを扱わなかったのは、単純に著者らの実装や執筆の労力の都合と、おそらく仕事でRustを導入するとなるとバックエンドに導入することのほうがユースケースとしては多いのではないかと考えたためです。たしかにRustを使ってフロントエンドを実装することもできるといえばできるのですが、正直なところどれほど旨味があるでしょうか。また、開発現場の大多数ではReactやVueなどのフレームワークを用いたフロントエンド開発がすでに行われているはずです。こうした事情から、Rustによるフロントエンドの側面は意図的に弾いています。同様に「Webアプリケーション」の文脈で言及されがちなWebAssemblyに関する話もまったくといっていいほど登場させていません。

なので、「Webアプリケーション」と言ってもかなり限定的な範囲を扱った書籍であることに留意いただきたいと思います。あくまで、バックエンド開発にRustを用いるならという話に重点を置いています。

ところで、海外のRustコミュニティには『Zero to Production in Rust』というすばらしい「Rust入門以後」を支える一冊があります。この書籍は非常に詳しく極めて実践的な内容をバランスよく扱っており、私も多くの影響を受けています。ただこの書籍は英語で書かれたものであり、日本語圏のソフトウェアエンジニアには少しハードルが高く感じられるものでもあります[*1]

本書はまさに、『Zero to Production in Rust』にインスパイアされて書かれた一冊でもあります。この書籍を読んでおくと一旦、バックエンド開発の現場にRustを持ち込めるという状態を目指したものです。Rustの普及にはさまざまな障壁がありますし、私個人の意見としても、JavaPHPのような巨大な採用実績を持つことはなかなか難しいだろうなという肌感はあります。それでも、本書の出版によってRustがとりいれられる現場が増えるといいなと思っています。

『Zero to Production in Rust』もそうですが、本書もこれからRustでバックエンド開発を始めていきたい方々向けの内容を中心的に盛り込んでいます。すでに開発されている方はもしかすると新しい発見はそこまで多くないかもしれませんが、上記の中で何か気になるトピックがありましたらぜひお手に取っていただけますと幸いです。

Rustってバックエンド開発に向いてるの?

この問いはよく聞かれますが、裏の意図や意味をよく考えています。「Rustはみんなのバックエンド開発のファーストチョイスになりうるの?」という問いが、実際のところ意味的には近いでしょうか?とすると、答えは今のところはノーになります。一方で、「Rustでバックエンド開発って大変じゃないの?」という問いだとすると、答えは「そうでもないかもしれない」になると思います。色々な方向の問いの可能性がありすぎて、聞かれるたびに都度どういう意味かを聞き返しています😂。

あまり深く考えずに字面通り答えるなら、本書を書いた以上は「向いている」と言いたいところですが、私個人としては「Rustでも実装できるし運用できる」くらいの感覚を持っています。上述した通り、現代におけるJavaPHPRuby on Railsなどの立ち位置になるのはちょっと難しいのではないか?と思っています。そもそもシステムプログラミング言語ですしね。

詳しい議論はぜひ書籍を読んでいただきたいと思っていますが、書籍内では下記の観点から議論をしています。

  • Rustを入れるメリット
    • Rustの高いパフォーマンスの恩恵を受けることができる。
    • 非常に優れた開発者体験の恩恵を受けることができる。
  • Rustを入れる際の課題点
    • 知見の流通が少なく、知見を持つ人がいないと導入に苦労をしやすい。
    • 一通り開発し運用するのに十分なものは揃っているが、エコシステムそれ自体は細かい点においてはまだまだ発展途上である。
    • 「Rustのような低レイヤー向け言語の導入はオーバーキルなのでは?」という疑義にストレートに答えにくい。

どのプログラミング言語でもそうだとは思いますが、正直なところ慣れてしまえば書くこと自体に抵抗はなくなりますし、すらすら書けるようになってきます。時折コンパイラに怒られてライフタイムの調整に走ることはままありますが、その対処が実装時のかなりの時間を占めているかというとそうでもありません。

開発中は普通に他のプログラミング言語を書いているのと変わりないと感じています。むしろRustのShared XOR Mutability[*2]の原則などにより変数のスコープの整理が言語側の仕組みによって強制されるようになるので、結果的に見通しのいいコードになりやすいとすら感じます。

加えてrust-analyzerやclippyをはじめとするエディタやツールの支援も多いです。rust-analyzerは個人的には他のLanguage Serverと比較しても非常に完成度が高いと感じており[*3]IDEとまではいきませんがそれに近い開発体験を得られるはずです。clippyを使うとRustのidiomaticな記法を教えてもらうことができます。よく言われる話ですがコンパイルエラーも非常に読みやすいです。そういうわけで開発者体験は他のプログラミング言語と比べると群を抜いてるかなという印象です。

上記から、私個人はバックエンド開発ではRustはファーストチョイスになりえます。しかし、もうかれこれ7年近くRustを使っているため完全にバイアスがかかっています。この辺りをどう感じられたかは、ぜひ本書で実際にいろいろ手を動かしてみて、感想を寄せていただけると嬉しいかなと思っています。そうした感想の集まりが、結局のところ今後のRustの立ち位置を決めていくのだと思っています。

著者について

期間の長短はあれ、共著者の3名はRustを使ったバックエンド開発の経験を持っています。私自身は現在は実務ではRustから離れてしまっていますが、Rustで開発していた頃に本書の大多数は執筆されています。実務からは離れているものの、最近もOSSのコードをメンテナンスしているなど完全にRustから離れているわけではありませんが。その他の著者は今でも実務でRustを使用して開発を行っています。

共著者3名は『実践Rustプログラミング入門』という書籍を4年ほど前に執筆した関係性にあたります。出版後しばらくしたのちに吉川さんのWEB+DB PRESSのRust回でレビュワーとして少しお手伝いをしました。今回は講談社さん側からの私への声掛けで、当初は単著で取り組もうか悩んだのですが、単著ではなかなかモチベーションの維持が難しいだろうと思い共著で執筆しようと声をかけたのがきっかけです。

また、吉川さんの伝手でrust-jpや『実践Rust入門』の共著者でお馴染みの河野達也さんにレビューをお願いしています。河野さんには数多くの貴重なレビューやフィードバックをいただきました。中には考慮しないと致命的なものであったり、ときには実際にベンチマークをとっていただいたりなど大変ありがたいものも含まれています。

目次とトピックの簡単な紹介

目次は下記の通りです。

  • はじめに
  • 第1章 本書で開発するアプリケーション
  • 第2章 開発環境の構築
  • 第3章 最小構成アプリケーションの実装
  • 第4章 蔵書管理サーバーアプリケーションの設計
  • 第5章 蔵書管理サーバーの実装
  • 第6章 システムの結合とテスト
  • 第7章 アプリケーションの運用
  • 第8章 エコシステムの紹介

ちなみにですが、5章が一番長いです。

以下で各章の概略を説明します。

はじめに

Rustでバックエンド開発をするにあたり、どのようなメリットやデメリットが考えられるのかなどを簡単に記載しています。いわゆる導入の章にあたります。

第1章 本書で開発するアプリケーション

今回開発予定の蔵書管理アプリケーションの要件を整理する章です。

第2章 開発環境の構築

Rustの開発環境を準備するための章です。Visual Studio CodeないしはRust Roverを使った開発が期待されますが、どのエディタを用いたとしても基本的に問題はありません。なお私はNeovimですべて開発しました。

第3章 最小構成アプリケーションの実装

本書ではaxumというHTTPサーバーを実装するためのライブラリを用いて開発を進めます。まずはaxumで簡単なHTTPサーバーを立ててみる章になります。基本的に後続の章はこの章で実装した内容をベースに進行します。

また、HTTPサーバーを実装した後はsqlxを用いて簡単なデータベース接続をチェックできる機能を実装します。

アプリケーション本体の実装だけでなく、ユニットテストやCIの準備までを含みます。アプリケーション構築の最初の方からCIパイプラインを構築しておくと、ビルドやテストの成功/失敗のフィードバックサイクルを素早く回せるだろうという狙いから、この辺りから導入しています。

第4章 蔵書管理サーバーアプリケーションの設計

「設計」とタイトルに出てしまっていますが、ここで3章の実装内容をいわゆるレイヤードアーキテクチャを用いた実装に切り替えていきます。本書にレイヤードアーキテクチャを入れた意図としては、多くの開発現場でこうしたアーキテクチャが採用されているだろうという予測と、いわゆる「real world」な、現実のアプリケーションの設計に即した実装を用意しておきたかったからです。ここにはDIを含む現場で用いられるような設計手法がいくつかとりいれられています。

第5章 蔵書管理サーバーの実装

この章で蔵書管理アプリケーションを一気に実装しきります。実はコード量がかなり多くなってしまい、相当な機能数があるといえばあります。単純に蔵書を管理するだけでなく、蔵書管理アプリケーションに登録されているユーザー管理などもさせています。

第6章 システムの結合とテスト

テストに関する細かい話や結合テストに関する話題が書かれています。モックやデータベース周りのテストに関して、5章では一旦飛ばした内容が再度解説されます。

第7章 アプリケーションの運用

いわゆる「オブザーバビリティ」、「CI」、そして最後に残ったOpenAPIに関する話題を扱います。アプリケーションの運用効率を高めるためによく利用される技術が、Rustの開発においてはどう実現されるかという話を中心にまとめています。CIについては、とくに高速化の際使えそうなtipsを雑多にとりあげています。

第8章 エコシステムの紹介

この章は参照用の章です。本書で紹介したクレート以外に使えるクレートを紹介しています。

書籍を書いた感想など

今回は完全に日本のRustによるバックエンド開発シーンが盛り上がるとよいなという気持ちで書いています。現時点では本書に類似するような書籍はないと思っており、この書籍が市場に放たれることで、Rustによる本格的なバックエンド開発の知見が巷に流通するとよいなと思っています。

一方で実装がかなり大変だったかなと思っています。仕様を盛り込んでしまった関係で思ったより実装を完了させるのが大変でした。それに伴って書籍のある章のページ数が大きくなり過ぎており、この辺りを読者のみなさんが果たしてやり切れるのかどうか…は、著者としてはよくわからないなと思っています。

また、書籍の帯では「ベストプラクティス」などと銘打たれていますが、私個人の意見としては、本書の内容はあくまで「実装の一手段」として捉えて欲しいです。そもそもベストプラクティスという言葉はそんなに好きではないです。というのも、どの手段を採用するかは前提によるのが実務だろうと思っているからです。そこに存在するのは、トレードオフの検討を通じた「ベターな選択」の積み重ねであり、「ワースト」を選ばないことが大事なのです。何かが他の選択肢を否応なく排斥しうる「ベスト」になることはまずないからです。

そういうわけで、本書を読んで「こういう手があるんだな」と思っていただき、さらに自身で改良した手法を編み出して行ってもらえることを願っています。そして可能なら改良した手法をぜひインターネット上の記事に知見として放流してください!「This Week in Rust」にてお待ちしております。[*4]

ところで、Rustを入れる検討をしている会社さんがありましたらぜひお声掛けください。何か導入の支援などできますと嬉しいと思っています。

*1:もちろん原著の英語は非常に平易かつ明確で、そこまで読みこなしが難しいものでもないとは思いますが。

*2:ある参照の共有はできる。ある参照の変更もできる。ただしそれらを共存させられないというRustの仕組みです。

*3:これは私がkotlin-analyzerというKotlin向けのLanguage Serverを最近作ったり、作るための調査をしていたりした際に感じたことです。rust-analyzerのレベルの速度や安定性を持ったサーバーがなかなかないなと思っています。それもそのはず、相当な工夫が裏側には隠されています。このブログに結構おもしろいエピソードがたくさんあります。

*4:This Week in Rustは、GitHub上のリポジトリに記事のURLを追加するPull Requestを投げると記事を掲載することができます。普段はRedditやHacker Newsなどの有名どころから、編集者がキュレーションするなどして収集されていますが、読者からの応募も受け付けしています。英語の記事が多いですが、一応日本語の記事も投稿可能です。実は私は日本語記事のレビュワーを務めています。ほとんど日本語記事が来ることはありませんが…