この業界に本当に3年もいるのかと、自分自身に問いかけたくなる瞬間がある。長い間、私はいつもテクノロジーの周りにいたが、そのほとんどは消費者側から、つまりゲームとしてだった。その裏にあるシステムに触れたことは一度もなかった。
それが、そもそも私がBSBAからBSITに転向した理由の一部でもある。テクノロジーが好きだったし、ビジネス科目の理論的で暗記中心の苦行が嫌いだった。結局のところ、プログラミングもそれほど変わらない。ここにもたくさん暗記すべきことがある。違いは、プログラミングでの暗記は、自分が実際に興味を持っているものに奉仕しているという点だ。
不意を突かれた質問
最近、マルチテナンシーについて聞かれた。私の答えはおおよそこうだった。「複数のテナントがいて、自分は大家という状態です。テナントは大家に報告します」。技術的には間違ってはいないが、痛々しいほど薄っぺらだった。続けて、利点と欠点は?と聞かれたとき、確かなものを何も提示できなかった。
もどかしいのは、マルチテナンシーが私にとって未知の概念ではなかったことだ。以前にも触れたことがあった。ただ、プレッシャーの下で口に出して、半分覚えているのではなく実際に理解しているとわかる形で説明できるほどではなかった。
それから、もっと難しい質問が続いた。ブローカーとは何か?プロバイダーとは何か?「プロバイダー」については、少なくとも大まかには知っていた。依存関係と調達に関するものだと思う、と答えたが、それ以上具体的にはなれなかった。「ブローカー」は完全に真っ白だった。そして次に。APIとREST APIの違いは何か?正直、この2つの概念を座って切り分けて考えたことは一度もなかった。仕事では互換的に使っている。APIとは消費するものだ、というのが私のメンタルモデルの限界だった。RESTが実際に何の略なのか、何を意味するのかを調べたのは、その後だった。
後から振り返って考える
マルチテナンシーは本当のショックだった。なぜなら、以前にその一部を扱ったことがあると分かっていたからだ。ただ、全体像ではなく、パンの塊そのものというより、パン屑のようなものだった。その場では瞬時に思い出せなかった。しかし落ち着いて、じっくり向き合ってみると、思っていたより速く腑に落ちた。
大家のたとえは、実はその場で自分が評価していたよりもよく成り立っていた。1棟のアパートビルと、戸建て住宅の分譲地を比較して考えてみてほしい。マルチテナンシーでは、テナント(アプリを使う異なる顧客や組織)は同じ基盤リソース、つまり「建物」を共有する。1つのコードベース、1つの実行中アプリケーション、そしてしばしば1つのデータベースで、各テナントのデータは(例えばtenant_idカラムや、テナントごとの別スキーマによって)論理的に分離される。大家の利点は、まさに私が感じてはいたが言語化できなかったものだ。分譲地を回って一軒ずつ修理するよりも、1棟の建物を保守・パッチ適用・スケールする方がはるかに簡単だ。トレードオフは、同じコインの裏面だ。テナントはリソースを共有するので、うるさい隣人(データベースを叩きまくるテナントや、テナント間でデータを漏らすバグ)は、完全に分離されたシングルテナント構成に比べて、はるかに大きなリスクになる。
プロバイダーとブローカーは、その場で感じたよりもエキゾチックなものではないと分かった。
プロバイダー(Laravelでは*サービスプロバイダー*)は、私が手探りで向かおうとしていたものに近い。それはブートストラップ層だ。アプリが起動すると、プロバイダーは構成要素、データベース接続、設定、サードパーティ統合を、アプリケーションのコンテナに登録する。そうすることで、あなたのコードが実行される頃には、依存するすべてがすでに配線され、準備が整っている。それは「調達」というより「アプリが開業する前の組み立てライン」に近い。
ブローカーは仲介者であり、私の直感はそこでは間違っていなかった。ただプレッシャーの下でその定義を保持できなかっただけだ。ブローカーは、直接お互いを知る必要のない2つの当事者の間に立つ。送信者から誰かがメッセージを受け取り、受信すべき相手にそれをルーティングするので、送信者は反対側で誰が聞いているのかを知る必要が一切ない。
実際に私に刺さった部分はここだ。私はRedisをよく使ってきた。キュー、キャッシュ、pub/sub、しばらくの間、私のスタックの一部だった。しかし「自分がいつも使っているもの」と「ブローカー」という言葉を結びつけて座って考えたことは一度もなかった。私はそのツールが属するカテゴリに名前をつけることなく、そのツールを使っていたのだ。RabbitMQは名前を聞いたことがあるだけで、触れたことはなかった。Kafkaは3つの中で最も馴染みがなく、それが何をするものかすら説明できなかった。だから、ブローカーについて聞かれたとき、私が経験不足で頭が真っ白になったのではない。すでに持っていた経験にラベルを付けたことが一度もなかったから、頭が真っ白になったのだ。
オブザーバーとディスパッチャーも似たような話だったが、じっくり向き合ってみると、こちらのギャップの方が納得がいった。その場で提示できたのは「ステータスが変化したときに動くワーカーみたいなもの」くらいだった。的外れではないが曖昧だった。というのも、オブザーバーが通常データベースモデルに紐づいているとは、本当に知らなかったからだ。それはモデルが作成・更新・削除されるのを監視し、元のコードがその存在を知る必要なく反応する。ディスパッチャーの方は直感的にもう少し理解できていた。私はそれを「イベントが起きること」と理解していたが、それは的により近い。ディスパッチャーは、ジョブ、イベント、またはメッセージを、それを処理すべき何かへ送り出す。
後から考えてみると、これは知識のギャップというよりは、経験不足のギャップだったのだと思う。オブザーバーとディスパッチャーは、複数のユーザーや複数のサービスが互いにやり取りするとき、実際に反応する価値のある何かがあるときに、その価値を発揮する。私のポートフォリオプロジェクトは、これまでそこまで高度なものではなかった。ほとんどのプロジェクトで自分だけがユーザーなので、他のどこかで反応をトリガーする必要のある2人目のアクターがめったにいない。私がこのパターンに実際に触れた唯一の場所はメールのディスパッチであり、それでさえこれらのパターンの目的のごく一部にすぎない。時々、もっと高度なプロジェクトをポートフォリオに持っていればと思う。本物のマルチユーザーインタラクションがあるプロジェクトなら、誰かに聞かれて初めて名前だけ知るのではなく、自然にこの種のものにぶつかる機会があったはずだ。
そしてAPIとREST APIの質問。振り返るとほとんど恥ずかしいと感じるものだ。APIは広い傘だ。2つのソフトウェアが互いに話すための、何らかの定義された方法すべてを指す。RESTは、APIを構築するための特定のアーキテクチャスタイルの一つで、HTTP上に成り立ち、すべてをURLで識別される「リソース」として扱い、標準的な動詞(GET、POST、PUT、DELETE)を使ってそれに作用する。ステートレスで、一度に1リクエストずつ、それ以前に何があったかの記憶は持たない。つまりREST APIはAPIの特定の一種であり、その同義語ではない。すべてのREST APIはAPIである。すべてのAPIがRESTであるわけではない。
ここから何を得るか
これらの概念のどれも、私にとって本当に未知のものではなかった。それが少し痛いところであり、これを書き留めたいと思わせる理由でもある。私は仕事の中で、これらのアイデアのそれぞれに一度は触れていた。私に欠けていたのは経験ではなく、「これを使ったことがある」を「これを他人にはっきり説明できる」に変える能力だった。実践と説明の間のそのギャップは、3年の経験があっても、あなたを露呈させうる場所らしい。
私はこれを失敗としてではなく、今はチェックリストとして扱っている。マルチテナンシー、プロバイダー、ブローカー、オブザーバー、ディスパッチャー、REST。使ったことはあるが、声に出して弁護しなければならなかったことのない概念たちだ。次に誰かに聞かれる前に直しておく価値がある。