「並行作業とスキーマ駆動開発」社内プロジェクトマネジメント勉強会第3回

リチャード 伊真岡 blog

「並行作業とスキーマ駆動開発」社内プロジェクトマネジメント勉強会第3回

こんにちは、リチャード 伊真岡です。私が勤務しているマーベリック株式会社で行ったプロジェクトマネジメント勉強会第3回の内容についてブログに書き起こします。

今までの回と同様、この勉強会は社内有志メンバーで業務時間外に行い、また業務機密を一切含まない内容なので私の個人ブログに掲載しています。

以下勉強会の発表内容です。

どうも、今日もまた15分間で他ではあまり聞けない切り口でプロジェクト・マネジメントについてお話します。今日のテーマはこちらです。

並行作業とスキーマ駆動開発

時間を戻して30年前、1990年ごろのウェブを振り返るところから始めます。当時多くのウェブサイトでいまより格段にシンプルな構成が採用されていました。HTMLファイル、CSSファイル、場合によってはわずかな量のJavaScriptでウェブページを構成し、サーバーの役割はそれぞれのファイルを配信することのみです。動的なウェブサービスはまだまだ珍しかった時代です。

昔のウェブはHTML, CSS, JavaScriptファイルの配信で実現

最近ではAPIサーバーを置いてウェブサービスを構成することが多く、サーバーはファイルもやり取りするのですが、サーバーとクライアントの間でファイルに限らない「データ」をやり取りする重要性が高まってきました。今日の発表テーマであるスキーマというのは、このデータの構造を決めるものです。

APIサーバーとスキーマ

さて近年のウェブサービス開発の典型的なスタイルを見てみましょう。通常はサーバーサイドの開発とクライアントサイドの開発は担当者が別れていて、サーバーサイド主導でAPIを定義する事が多いと思います。 その場合、開発後期になってようやくAPIが決定するようでは、クライアントサイドの開発時間がたりずプロジェクト炎上の可能性が高くなってしまいます。

APIの決定が遅い場合

APIの決定が遅い場合開発が炎上

理想を言えば、開発初期にAPIをいったん利用可能なレベルで作り込み、あとの時点で微調整を繰り返すのがよいでしょう。しかし、最初に作ったAPIの設計がずさんだと、変更を繰り返すうちにぐちゃぐちゃになって収集がつかなくなります。結局開発のだいぶ後の段階になって、APIの設計の悪さが原因で開発スピードが大きく下がり、これまた炎上してしまいます。

APIの決定が早い場合

APIの微調整で対応できない設計の悪さが露呈し炎上

つまり、APIサーバーを置くことがが当たり前の時代に、スムーズに開発するためには以下の2点が重要になります

  • APIは開発後期に大幅変更すると負担が高いので、開発当初から品質の高いAPIを設計する、
  • そのためエンジニアの技能が必要

現代のソフトウェア開発では、やり直しが重要性になってきているという話を第1回でしましたが、ソフトウェアの品質を上げるために必要不可欠なやり直しと違って、APIの設計が悪くて行うやり直しは本来なら避けられます。なぜ避けられるかというと、API設計にはしっかりとした指針があるからです。

具体的な指針について、2010年代前半まではウェブのAPI設計といえばRESTが一強のような状態でした。REST自体には昔から大きな変更はないので、今の時代でも少し前の書籍の内容が大いに役立ちます。とくにエンジニア達から評価が高く、私が読んだ中でも今でも役に立つ内容が多いと思ったのはこの2冊です

2010年代後半には静的型付API技術とツールセットが出てきます。その筆頭格がGoogleが発表したgRPCとFacebookが発表したGraphQLです(*1)。

(*1 GraphQLはRESTと対比して解説されることが多いのですが、gRPCは必ずしもRESTと対比されるものではありません。実際Google Cloud APIはprotobufでAPIを定義しgRPCで実装しているものの、設計の指針はリソース指向でRESTであると明言しています)

この勉強会はアドテクの会社マーベリックで開催しているので、参加の皆様にはおなじみの世界最強のアドテク会社2社ですね。gRPCやGraphQLが急速に広がったことで、API設計ノウハウは大きく進化しました。RESTは指針として完成されているものの、どうしても細かい部分は個々のエンジニアの判断に委ねられ解釈の幅があるのが特徴ですが、gRPCやGraphQLはツールが伴うこともあってより方法論が具体的です。そして静的型付APIがある程度エラーの混入を防いでくれるおかげで、いまでは「そこそこ優れたAPIを設計する」ためのハードルが下がってきていると言えます。

  • 昔: ごく一部の超優秀なエンジニアのみ優れたAPIを設計できた
  • 今: そこそこ優秀なエンジニアなら、そこそこ優れたAPIを設計できる

開発の初期段階から、そこそこ優れたAPI設計ができるようになると、それがサーバーサイド開発とクライアントサイド開発の並行作業を可能にします。APIはサーバーとクライアントでやり取りするデータの構造つまりスキーマを決めるので、これを指して「スキーマ駆動開発」と呼んでいます。スキーマ駆動開発では優れたAPIを早い段階で設計し、gRPCやGraphQLなどのツールの支援を得て開発をスムーズにできます。

並行作業ができるようになった

並行作業には理論的な裏付けとツールのサポートが不可欠

ソフトウェア開発は放っておくと、どんどん開発スピードが落ちていってしまうことは皆さん経験済みだと思います。反対に開発スピードを上げる方法があるなら、それは非常に大きな価値をもたらしてくれるわけです。

ここで少し話が飛んで、コンピューターの作業であっても、人の作業であっても知的作業を「大幅に」速くするには主に2つの方法があります。

  • 無駄な作業をやめる (こっちの話は今回の対象外)
  • 並行・並列作業 (こっちが今日のテーマ)

つまり、一つ一つの作業自体を高速化するのは多くの場合早い段階で限界が訪れて、それよりは上記2つの視点で高速化を狙うほうが効果が大きいのです。

まずはコンピューターが行う並行・並列作業といえばGPUによる計算の高速化が有名です。超並列と言ったらいいでしょうか、並列作業しやすい計算アルゴリズムであるならば、場合によってはCPUと比べ100倍を超える速度が出たという例もあるようです。

しかし、並列・並行作業というのは何でも同時に走らせればよいのではありません。コンピュータの仕事でも人が行う仕事でも、考え抜かれた仕組みがなければあっという間に崩壊します。コンピュータの並列・並行作業の場合はデータ不整合や破壊を生み出し、それを後知恵で防ごうとしてかえって全体が遅くなるか、もっと悪ければソフトウェアが全く意味をなさない結果を返します。人の場合は並行・並列作業に失敗すると手戻りの嵐で何が最新で正しい状況下わからなくなって現場が崩壊します。

データ不整合

たとえばFork-Joinというコンピュータが並行作業をするためのアルゴリズムがあるのですが、これはJavaの標準ライブラリを始めとした様々なプログラミング言語や技術スタックに取り入れられています。このアルゴリズムには背景理論を説明した学術論文があり、アカデミックな世界でしっかりと理論を検証した上で、実務の世界で一般のプログラマが利用しているのです。並行・並列作業系のアルゴリズムはこのようにしっかりした学術的な裏付けがあるものが多く、そうでないオレオレ並行・並列アルゴリズムはどこかの時点で思いも寄らぬ落とし穴にはまってしまい、爆発してしまいます。それくらい正しい並行・並列作業の仕組みを考えるのは難しいのです。

fork-join

今紹介したのはコンピューターの並行・並列作業でしたが、人の並行作業も似たような話で、しっかりした理論の枠組みとツールの支援が必要です。いい加減にAPIを設計すると、だいぶあとになってからやり直さざるを得なくなる例は紹介しましたね。gRPCやGraphQLは静的型付けというコンピュータサイエンスの世界で研究者たちが何十年も積み重ねたエラー混入を防ぐ仕組みを採用していますし、それぞれ世界でもっともソフトウェアを作る能力に優れた2社が長年運用したbattle-testedな開発ツールチェインを持っています。

では、gRPCやGraphQLを使えば、クライアント側開発とサーバー側開発の同時進行のような並行、並列作業に耐えうる優れた設計ができるのか?というと、そんなことはありません。

設計が重要

あくまでそれらは優れた設計の土台でしかなく、API設計を正しく行うには設計指針の理解が必要です。優れた設計には勉強が必要なわけですね。

勉強が重要

そして優れたAPI設計をおこなうには、勉強のさらに前にもう1つ重要な段階があって、それが今からお話することです。

RDRAでAPI設計エンジニアが、業務を理解し要件を定義する

前回に引き続きRDRAに関することを交えてお話します。RDRAは株式会社バリューソースの神崎善司 (@zenzengood) さんが提唱している要件定義の手法で、一部設計に関わる工程も含みます。

RDRA4つの領域

RDRAでは要件定義のスピードを保つために、最初から縦方向に深くほるのは避け、横方向に4つのフェーズ間で移動しながら要件の詳細を詰めることを前回の勉強会でお話しました

rdra-concurrent-1

rdra-concurrent-2

RDRAは要件定義の手法論なので、設計の話は一部範囲外です。API設計を考えるとしたらRDRAの4つの領域の外、一番右側のフェーズになるでしょう。

rdra-concurrent-3

rdra-concurrent-4

クライアント・サーバー間の並行作業の話をしたように、要件定義とAPI設計もある程度並行作業をすることがソフトウェア開発プロジェクトのスピードを保つのに有効です。

rdra-concurrent-5

rdra-concurrent-6

そして様々な作業を並行して行い、当然多少の手戻りは発生してしまうので、致命的な手戻りを防ぐために「優れた仕組み」が必要になります。これがgRPCやGraphQLなどのスキーマ駆動時代のAPI設計ツールであり、要件定義に関してはRDRAが致命的な手戻りを生みづらい仕組みだと考えています。

rdra-concurrent-7

まとめ

要件定義ではRDRA、設計ではAPI設計の分野でgRPCやGraphQLが出てくるなど、ソフトウェア開発の「早い段階での工程」に関するツールや手法論が近年進化し、ソフトウェア開発の様々な工程を同時並行で行う土台が整ってきました。同時並行で行えるということは、それだけ開発スピードを上げられる、ソフトウェア開発をビジネスの成功に結びつけやすくなるということです。

しかし、土台が整っただけであって、API設計ツールを使いこなす、リソース指向API設計を理解する、オブジェクト指向設計を理解するといった勉強は必要です。ここは「そこそこ優れたエンジニアができる」レベルになってきているので、歯を食いしばって頑張りましょう。

API設計に関するツールが増え、知見が溜まってきたということは、それだけ学ぶ事が増えたという意味で、それはそれで大変な時代です。しかし、ちゃんと学べば並行作業によってソフトウェア開発スピードを向上させるのが現実的な世の中になってきました。API設計者が綱渡り的職人芸を発揮しないとプロジェクト全体が手戻りの嵐になっていた時代よりはだいぶ良くなりました。