2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
Nuxt × Typescript × Graphql with Appolo で開発するつらみ(全1記事)
リンクをコピー
記事をブックマーク
樋口鉄朗氏:合同会社DMM.comオンラインイベント事業部の樋口鉄朗です。(※取材当時)今回は「Nuxt × TypeScript × GraphQLで開発した際のつらみ」についてのTipsを説明していきたいと思います。よろしくお願いします。
私は公立はこだて未来大学出身で、2019年に新卒でDMM.comに入社しました。趣味は自転車に乗ったり、旅行したり、ドライブに行ったりすることで、多趣味なエンジニアです。
以前は動画配信事業部に所属していて、売上グロース施策の関連開発などを担当していました。また、プラットフォーム事業部では、事業部内のシステムのリプレイスなどのプロジェクトを担当したり、運営事業部チーム向けのアプリケーションやbotを開発したりしていました。
現在所属しているオンラインイベント事業部では、オンラインイベント展示会「DMM showbooth」のCMS機能のフロント部分の開発を担当しています。担当している技術領域はJavaScript、React、Next、Nuxt、Vueなどで、さまざまなフレームワークを触っています。またPHPやGolang、Pythonなども少し触っていて、卒業研究ではSolidityで書いたスマートコントラクトを作っていました。ほかにも、「Mastodon」のサーバー管理をやっています。
それではここから本題に移っていきたいと思います。これはとある案件の話です。プロダクトについての詳細はお話できないのでTipsのみの説明です。ご了承ください。
今回のアジェンダです。Vue2とTypeScriptの組み合わせがつらい話と、GraphQLがつらい話の2点です。
「私、2019年新卒のてっちゃん! 既存システムの改修案件が一段落しそうなところで、突然案件が降ってきた! 『ねぇ。ちょっと楽しいことしない?』。NuxtにTypeScriptにGraphQLを使ったフルSPA(Single Page Application)! あまり触る機会のないモダン環境で開発できるよと誘われ、技術領域のモダンさに目を奪われていたら、背後から迫ってくる納期に気づかなかった!リリースは12月、アサインは6月。フロント開発人数は自分を含めて3人。初めてのVue。これから私、どうなっちゃうの〜??」という案件を担当したときの話です。
ざっくりとしたフロントの仕様は、WebViewがほとんどの、ネイティブアプリケーションライクな何かです。すべてキーボードで操作できる必要があります。動作確認対象のブラウザは1つだけですが、デバイスに入っているプリインブラウザです。アクティブフォーカスが見やすいようにアニメーションが必要です。既存のアプリケーションのデザインは、ほぼ移植するので、リプレイスに近いものになります。
技術仕様や置かれた環境ですが、事業部初GraphQLとTS(TypeScript)を導入しました。また、事業部2例目のNuxtを使ったSPAの開発です。GraphQLは、既存のAPIをリプレイスしていくためのBFF(Backends For Frontends)的な役割として導入することが決定しました。TypeScriptはJS(JavaScript)の“つらみ”を軽減できるのでは? と試験的に導入することになりました。
SPAの開発は以前の経験があったので、そこまでは苦労はしないだろうという環境での開発でした。
では本題に移りましょう。「Vue2×TypeScriptがつらい! 〜Vue3以前の型推論のない世界〜」にご案内します。嫌ですね、そんな世界。この案件を開発したときは、2.6がVueの最新だったので、Vue3のTypeScriptサポートが受けられなかったということを前置きしておきます。
まず、Vueについて解説をします。言わずと知れた、UI構築のためのJS(JavaScript)のフレームワークです。プログレッシブフレームワークという、部分採用可能な仕組みを取り入れているので、HTMLの一部だけをVueに置き換える書き方ができて、弊社のシステムの一部でもこれが動いています。
また、1つのファイルにHTMLのテンプレート構文を記述して、HTMLタグ、styleタグ、scriptタグで、各ロジックを分離して書けるので、1つのファイルで1コンポーネントを実現する単一ファイルコンポーネントと呼ばれる書き方が可能です。
具体的にはこんな感じですね。templateタグ、scriptタグ、styleタグと分けて書くところで、本来だったらファイルが全部別れているものを全部1個にまとめて書けるのがVueの特徴です。
続いて、TypeScriptの話をしておきます。動的型付けのスクリプト言語であるJavaScriptに対して、静的型付けを提供するスーパーセットです。とても良いものなんです。ただ、「VueのTypeScriptのサポートが完璧だったならば」という前置きが入るんですね。
ここがつらいよ、Vue。Vue2.6でTypeScriptのサポートがかなり進んだので、TypeScriptを入れようと気運が全体的に高まっていた時期でした。しかし、Vue2系のTypeScriptサポートは型推論がほぼ使えない状態でした。例えば、computedにhasNext()みたいなメソッドを生やした場合、このhasNext()の返り値は内部の型推論が効かないのでany型になります。
TypeScript tscがstrict modeの場合は、エラーになることがほとんどです。さらに言うと、booleanと型明示を絶対付けないといけないのはもちろん、1ヶ所でもこれが欠けていると、かなりの高確率でVS CodeのVueのlinterであるveturがプロジェクト内すべてを指して、シンタックスエラーですと吐いて、エディタが真っ赤に染まります。
また、「Vue Apollo」を使っていたんですが、ここの書き方が正しくてもVue ApolloのTypeScriptサポートが中途半端だったので、アサーションをしないとまともに型周りのサポートが入らないという残念な仕様でとても苦労しました。
どう書いてもany型になるので、どこかしらでアサーションをかける必要があります。TypeScriptを書いているのにアサーションを使うということに負けを感じて、「なんかなぁ」という感じでした。
また、Vueに「dollar」プラグインみたいなものを入れていると、これも型が付かないんですね。Vueのdeclareで型を明示してもなぜか吐かなくて、この下のほうに書いてあるconst dollarApolloみたいな感じで、「そのthis.$apolloはDollarApolloですよ」という型を入れないと、まともに型が付かないのがVue2.6のTypeScriptサポートのつらい世界でした。
今はVue3が正式に登場していて、Composition APIの登場で、ReactのFunctional Componentみたいなものが作れるようになりました。しかもVue2よりも厳格で、きちんと型推論の効くdefineComponentという型が登場したおかげで、TypeScriptをVueで書くのがかなり楽になりました。
実際にお試しで、運営さん向けツールとして作ったものがあるんですが、きちんと型推論が効いていました。今までだったらany型になっていた、downloadLinkEnable()もきちんとbooleanと型推論が出ているので、「あぁ、すごい!」と、感動を覚えましたね。
みなさんは苦労しなくていいと思います。とりあえずVue3を使いましょう。この問題に直面したときのVue2.6はとてもつらかったです。何も言いません、Vue3を使ってください。
では次の「GraphQLがつらい! 〜レガシーAPIベースで作り上げたクエリに支配された世界〜」の話に移ります。これはまた嫌な世界ですけどね。
API向けのクエリ言語のGraphQLですが、REST(Representational State Transfer)で使われるopenapi.jsonやhoge.json(任意のjson)みたいなファイルに代わってgraphql.schemaというスキーマファイルを定義することでクエリを構築していきます。
REST(Representational State Transfer)のAPIと異なって、1リソースごとではなく、そのリソースの必要な情報のみをクエリ定義できるのが特徴で、必要な情報のみをやることによってリクエストを最小限にしたり、DB負荷を抑えるたりできるのが特徴です。スキーマ設計が正しければ……です。
もともとはREST(Representational State Transfer) APIを使う予定だったんですが、バックエンドの技術力向上と将来性を見込んでGraphQLを使いたいとなりました。「あ、ふーん」と、この時点でちょっと私は暗雲が垂れ込めているなと感じていました。
GraphQLは、レガシーAPIからの置き換えを将来達成するためのBFF(Backends For Frontends)みたいな中継ツールとして使っていました。なので表側のリクエストはGraphQLでできますが、裏は今までどおりレガシーAPIでリレーしていました。このレガシーAPIは、機能ごとの関数がAPIとして生えているSOAP(Simple Object Access Protocol)的なものだったので、結果としてAPIの数だけクエリが生えるという状況が生まれてしまいました。
また、スキーマの命名規則について、フロントエンドとバックエンドのエンジニア間の合意がうまく取れていなかったのに加えて、バックエンドエンジニアとの調整不足により、「hogeItemListItem」「hogeListItem」「HogeItem」みたいな、多様性溢れる命名がたくさん誕生してしまって、フロントエンド側が「なんじゃこりゃー!」という状況になりました。
また、TypeScriptを利用したときに、「GraphQL Code Generator」でスキーマファイルから型定義を自動生成して、レスポンスに対して型を自動で当てていた結果、全部違う命名がそのままフロントエンドに返ってきて「命名違いすぎ! なんでや!」という状態になってしまいました。
QA期間を経て、1ヶ月間でリファクタリングを実施しました。スキーマファイルを一括で直す作業が行われたのですが、ローカルの開発サーバーを立ち上げるときにスキーマファイルを再取得するフロントエンドの処理をpackage.jsonのスクリプトに書いていたので、すべてのフロントエンドのPCで開発環境が壊れるという事態が起きました。「開発環境オワタ」という感じですね。
いろいろな“つらみ”が多いので、GraphQLを利用する場合は、必ずスキーマ駆動開発を使っておきましょうという教訓です。openapi.jsonやgraphql.schemaなどのスキーマ定義を、事前にフロントエンドとバックエンドの間で、要するに開発者と利用者の間で合意を取ってからAPIを作りましょうというのがこのSchema Driven Developmentです。
すでに完成後のインターフェイスがわかっているので、だいたいのライブラリを使えばモックサーバーもすぐに立てられます。フロントエンド側の開発がバックエンドのサーバーのデータの出来上がりを待たなくても、データがすでに完成した状態で開発を進められます。
また、開発における手戻りの発生リスクもとても小さいので、教訓は「スキーマ駆動開発はぜひ使っていきましょう」になります。そもそもGraphQLは本当に必要なのかも検討する必要があるかなと思います。GraphQLは仕組み上、かなりしっかりとした設計がないとあまりメリットがないかなと思っています。
特に今回のように工期やDB、APIの都合上、インターフェイスの自由度はほぼない状態で、機能がリソースに紐づいているのではなくて、リソースが機能に紐づいている、要するにSOAP(Simple Object Access Protocol)的なAPIの張り方をしている場合、GraphQLはBFF(Backends For Frontends)みたいな使い方がぜんぜん適していないんじゃないかと思います。
あとは新しい技術を使ってみたいだけで、GraphQLを使おうとしているのであれば絶対に良くないと思います。きちんと適材適所で使いましょう。
教訓です。モダンな技術もレガシーな技術も適材適所で使っていきましょう。プロダクションに入れるのは熟れてからです。自分用に使うのであればガンガン使っていきましょう。私の発表は終わりです。
関連タグ:
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05