2023の12日目の記事です。はじめにUbieでソフトウェアエンジニアをやっているisseiです。2021年の3月に入社してから2年程症状検索エンジン「ユビー」の開発をしていましたが、ここ1年くらい新規のプロダクトの検証とそのスケールのための開発をしています。2023年の前半は、新規のプロダクトの検証を出来るだけ素早く行うため、実装範囲を小さくし、バックエンドの実装も最小限にとどめて、ほとんどの機能をフロントのコードで完結させていたのですが、後半は、前半に検証が終えられたプロダクトのスケールに向けた設計変更と実装の置き換えを行っています。良かったので、採用に至った経緯と、実装の概要、実際に採用してみて感じたメリット/デメリットについて紹介します。UI(SDUI)とはAirbnbが開発した、サーバーからデータと一緒にUIのロジックをレスポンスとして返却し、クライアント側ではそのレスポンスをUIに変換して表示する設計です。https://medium.com/airbnb-engineering/a-deep-dive-into-airbnbs-server-driven-ui-system-842244c5f5SDUIを採用する利点は、複雑な画面の出し分けなどもバックエンドで制御しやすいということ、ネイティブアプリやwebフロントエンドのリリースをしなくても、バックエンド側のレスポンスを変更するだけでUIの変更が出来ること、などが挙げられます。Ubieのプロダクトでは、ペイシェントジャーニー上で意思決定を支援するために適切なタイミングで適切なコンテンツを出し分ける事が重要であり、検証を回すスピートも速いことから、これらのメリットはプロダクトと非常に相性が良いです。今回SDUIを採用した開発中のプロダクトは、疾患を治療中の方を対象にしていて、ユーザーは治療中の疾患に関する質問に答えていくと、最後に表示される結果画面で自分の回答に応じた治療に有益なコンテンツが見られる、というものです。Boot(Node.jsへの移行中)APIのクエリ言語としてGraphQLを採用しています。今回の設計変更のポイントは2つあります。結果画面のUIをサーバーサイドから変更するためのGraphQLスキーマの設計ユーザーの属性や回答に応じて動的にコンテンツをフィルタリングするための条件の設計どちらもボリュームの大きいテーマなので、今回の記事では前者の結果画面のUIをサーバーサイドから変更するためのGraphQLスキーマの設計に絞って話します。今回は結果的にSDUIを採用しましたが、最初からSDUIを採用することが決まっていたわけではありません。当初はSDUIのことは知らずに普通にTypeScriptとGraphQLでやりたいことを実現するための設計を考え始めました。やりたいことを考えるのですが、スケールを見据えた設計ということで、将来的な要件が曖昧なため、自分なりに様々なユースケースを想定してビジネス側からの要求に柔軟に対応できる仕様を考え、次のような満たしたい条件を抽出しました。サーバーのレスポンス変更だけでコンテンツの追加や見た目、順番を変更できる返却するコンテンツの追加、変更のコストを出来るだけ小さくしたい(理想的には管理画面からエンジニア以外のメンバーでも簡単に変更ができるようにしたい)日時をトリガーとしたコンテンツの切り替えを自動でできるようにしたいその後、これらの条件を満たすようなGraphQLスキーマの実装を始めたのですが、自分のGraphQL力では実現したいことをうまく表現できず、同僚のゆーくに相談した所、そこで初めて自分が作ろうとしていたものがいわゆるSDUIと呼ばれるものだと知り、SDUIを採用することになりました。SDUIがプロダクトにフィットするか検討して採用を決めたわけではなく、プロダクトに必要なものを作っていたら自然とSDUIに行き着いていたということです。実装方法SDUIの実装のポイントは大きく分けて次の2つです。バックエンドから返すレスポンスのGraphQLスキーマ設計フロントエンドでの受け取ったレスポンスのコンポーネントへの変換それぞれ簡単に説明していきます。GraphQLのスキーマ設計GraphQLのスキーマを以下に記載します。(読みやすいように簡略化しています。String!}ポイントは全てのコンテンツをResultContentのunionで返していることです。ResultQuestionnaireLinkこうすることでコンテンツごとにorderのようなプロパティを持たずにコンテンツの順番を表現できます。今後コンテンツの種類が増えたとしてもResultContentBaseを継承したtypeを末尾に追加して行くだけで済みます。レスポンスをコンポーネントに変換するフロント側では次のようなコンポーネントを実装することでResultContentFragmentを各コンポーネントに変換しています。補完が効くようになります。使用箇所のコードはこんな感じになります。ResultPage;フロントのコードはレスポンスのコンポーネントへの変換と各コンポーネントのスタイリングが主な責務になりました。出し分けのロジックがないのでとてもシンプルですね。向上した最初の設計には頭を使いましたが、フロントのコードの責務がシンプルになったことで、フロント、バックエンドどちらのコードも実装時に考える事が少なくなり、レビューもしてもらいやすくなったと感じています。これらは開発期間に対して複利で効いてくるので非常に大きいメリットだと思います。思考コストを先に支払うことでコミュニケーションがスムーズになったSDUIの場合、先に許容するUI、しないUIをデザイナーと一緒にすり合わせる必要があるのですが、最初にUIのルールを決めることで、実装時に設計に戻って考えたりすることが減ったように感じます。チームのメンバーやチーム外から仕様に関する会話をスムーズになりました。ビジネスロジックに集中できる管理画面でコンテンツの入稿をすることを目指す場合、それぞれのコンテンツに対して管理画面上で出し分けの条件を設定したくなると思います。SDUIの場合はコンテンツの出し分けをバックエンドのみで行うため設計がしやすく、ビジネスロジックを考えることに集中出来ています。出し分けの部分の設計については、また機会があれば書きます。おわりにSDUIは、プロダクトに複雑な画面の出し分けがあったり、少ないコストで表示しているコンテンツを切り替えたい場合には非常に強力な武器です。設計に多少難しさはありますが、Ubieでは限られた人的リソースでプロダクトをデリバリーするための高速道路になってくれると感じています。フロントエンドとバックエンドを一気通貫で設計できる場合には一度検討してみてはいかがでしょうか。Ubieでは絶賛採用中ですので、このようなシステムの設計から関わりたいという方やUbieに興味があって話を聞いてみたい方がいましたら、自分のXにDMを送ってもらうか、採用サイトからご連絡ください。テックブログPublicationUbie株式会社のテックブログです。Proよくある質問LinksX(Twitter)GitHubメディアキットLegal利用規約プライバシーポリシ。