Upgrade to Pro — share decks privately, control downloads, hide ads and more …

レガシーシステム刷新における TypeSpec スキーマ駆動開発のすゝめ

レガシーシステム刷新における TypeSpec スキーマ駆動開発のすゝめ

TSKaigi Hokuriku 2025
https://hokuriku.tskaigi.org/talks/24
で発表した資料になります。

#目次
- レガシーシステム刷新について
- レガシーシステムとは
- レガシーシステムを取り巻く現状と課題
- TypeSpecによるスキーマ開発について
- レガシーシステム刷新におけるスキーマ駆動開発について
- レガシーシステム刷新における大きな課題
- レガシーシステム刷新への適用性
- レガシーシステム刷新で具体的にどうやって活用するか
- おわりに

サンプルリポジトリURL: https://github.com/tsukuha/tskaigi-hokuriku2025-typespec-poc

Avatar for karacoro / からころ

karacoro / からころ

November 23, 2025
Tweet

More Decks by karacoro / からころ

Other Decks in Technology

Transcript

  1. Copyright © LIXIL Corporation. All rights reserved. 株式会社LIXIL SoE DevOps.

    Digital アプリケーションエキスパート karacoro / からころ(Tsukuha Kawakami) レガシーシステム刷新における TypeSpecスキーマ駆動開発のすゝめ
  2. 3 本日のアジェンダ • レガシーシステム刷新について ◦ レガシーシステムとは ◦ レガシーシステムを取り巻く現状と課題 • TypeSpecによるスキーマ開発について

    • レガシーシステム刷新におけるスキーマ駆動開発について ◦ レガシーシステム刷新における大きな課題 ◦ レガシーシステム刷新への適用性 • レガシーシステム刷新で具体的にどうやって活用するか • おわりに
  3. 7 レガシーシステムの定義 • 技術的な観点 [1] [1] 2025年5月28日 DXの現在地とレガシーシステム脱却に向けて p.7 https://www.ipa.go.jp/disc/committee/begoj90000002xuk-att/legacy-system-modernization-committee-20250528-report.pdf

    ② システムの肥大化複雑化 ① 技術の老朽化 古い要素技術やパッケージでシステムが構成されており、それらに対応できる技術者が 高齢化・離脱し要員の確保が難しい・ハードウェア等が故障すると代替が利かない システムが巨大・複雑で機能の追加・変更が困難・現行業務の遂行や改善に支障が発生。 システムの補完機能やカスタマイズ箇所が増え、 人手で運用をカバーしなければならない ③ システムのブラックボックス化 仕様や設計のドキュメントが整備されておらず、 新システムへの移行や再構築時に支障 が発生・システム障害発生時に原因がすぐに特定できない
  4. 8 DXとレガシーシステムを取り巻く現状と課題 • 2025年の壁(2018年に発表) [1] ◦ 既存システムの問題が足枷となり日本企業がDXを推進できずに 経営改革が遅れるとデジタル競争の敗者となり経済損失が発生 [1] 2018年9月7日

    D X レポート ~ITシステム「2025年の崖」の克服とDXの本格的な展開~ https://www.meti.go.jp/policy/it_policy/dx/DX_report_summary.pdf [2] 2025年5月28日 DXの現在地とレガシーシステム脱却に向けて p.5 https://www.ipa.go.jp/disc/committee/begoj90000002xuk-att/legacy-system-modernization-committee-20250528-report.pdf • 中長期的な影響 [2] ◦ 企業が先送りにしている既存のレガシーシステムの保守切れ対応や システム移行のタイミングで各所で問題が続発 ◦ IT需要が益々増える一方で、人口減少と熟練者の離脱によりITの担い手は減り続 け、IT人材需給の差が一層拡大 ◦ 進化するデジタル技術の導入・連携ができず、諸外国との隔たりは一層拡大し、日 本の産業競争力は低下の一途を辿る
  5. 10 レガシーシステム刷新時の大きな課題 ② マイグレーション後の動作担保 ① デグレーション 刷新前と後で登録されるデータが違う・表示される項目が違うなど、刷新前後で システムの挙動に差異が出てしまうこと システムを刷新した前後で動作保証を行うことが課題になることがある 単体・結合・システムテストやE2E,

    VRT など総合的に動作を保証することが多い ③ 技術のモダナイゼーション すでにメンテが終了していたり、脆弱性が残されたフレームワークやツールの刷新など も並行して行うことも多く、人材戦略の面からも技術のモダナイズが必要になることも
  6. 11 レガシーシステム刷新時の大きな課題 ② マイグレーション後の動作担保 ① デグレーション 刷新前と後で登録されるデータが違う・表示される項目が違うなど、刷新前後で システムの挙動に差異が出てしまうこと システムを刷新した前後で動作保証を行うことが課題になることがある 単体・結合・システムテストやE2E,

    VRT など総合的に動作を保証することが多い ③ 技術のモダナイゼーション すでにメンテが終了していたり、脆弱性が残されたフレームワークやツールの刷新など も並行して行うことも多く、人材戦略の面からも技術のモダナイズが必要になることも システムをまるっと置き換えるのは 到底、現実的ではない
  7. 12 • BEとFEは分離しやすくシステム刷新時には、 段階的に別々のフェーズとして刷新することが多い • BEのデータ構造の変更は難しいことも多いためFEが先行しがち • 上記 + API仕様書が(詳細に)定義されていない場合に適用しやすい

    ◦ API仕様書自体がない ◦ API仕様書にリクエストボディやレスポンスが詳細に定義されていない ◦ API仕様書がメンテされていない など レガシーシステム刷新にスキーマ駆動開発を適用する?
  8. 13 • API仕様を事前に定め、それを基に BE/FE の開発を進める手法 • スキーマ駆動開発には、OpenAPI や GraphQL, gRPC

    などが よく利用される スキーマ駆動開発(SDD)とは ① スキーマ定義(API仕様定義) Contract(契約) ② バックエンド開発 Producer(提供者) ② フロントエンド開発 Consumer(消費者)
  9. 14 • OpenAPI とは ◦ HTTP API のプログラミング言語に依存しないインタフェース を構築するためのフォーマット ◦

    OpenAPI に基づくツール群を Swagger と呼ぶ OpenAPI と TypeSpec について • TypeSpec とは ◦ OpenAPI のフォーマットにコンバートでき TypeScriptライクに 記述できる ◦ TypeSpecから出力された OpenAPI(.yml) から各種ツールを 利用し、型定義 や HTMLとしてAPI仕様 を出力することができる
  10. 15 • TypeSpec から 型定義とAPI仕様 の生成フロー OpenAPI と TypeSpec について

    TypeSpec 定義 (.tsp) OpenAPI(.yaml) TypeScript 型定義 API仕様書(HTML) compile
  11. 16 TypeSpecでのAPI仕様の記述例 import "@typespec/http"; using Http; @service(#{ title: "認証" })

    @tag("認証") namespace SampleAPI.Common { @route("/common/auth") interface GetAuthInfo { @summary("認証情報取得 API") @post auth(Auth.AuthRequest): Auth.AuthResponse; } } features/common/main.tsp
  12. 17 TypeSpecでのAPI仕様の記述例 import "@typespec/http"; using Http; @service(#{ title: "認証" })

    @tag("認証") namespace SampleAPI.Common { @route("/common/auth") interface GetAuthInfo { @summary("認証情報取得 API") @post auth(Auth.AuthRequest): Auth.AuthResponse; } } features/common/main.tsp
  13. 18 TypeSpecでのAPI仕様の記述例 import "@typespec/http"; import "../../models/common/error.tsp"; using Http; using SampleAPI.Common.Error;

    namespace SampleAPI.Common.Auth { model AuthRequest { @bodyRoot body: { @summary("ID") id: string; @summary("password") password: string; } } ... /models/common/authInfo.tsp
  14. 19 TypeSpecでのAPI仕様の記述例 ... model _AuthResponse { @statusCode statusCode: 200; @bodyRoot

    body: { @doc("ID") @example("1") id: string; @doc("名称") @example("サンプル名称 ") name: string; } } alias AuthResponse = _AuthResponse | UnauthorizedError; } /models/common/authInfo.tsp
  15. 20 TypeSpecでのAPI仕様の記述例 ... model _AuthResponse { @statusCode statusCode: 200; @bodyRoot

    body: { @doc("ID") @example("1") id: string; @doc("名称") @example("サンプル名称 ") name: string; } } alias AuthResponse = _AuthResponse | UnauthorizedError; } /models/common/authInfo.tsp
  16. 21 スキーマ駆動開発に TypeSpec を利用する • メリット ◦ 構造化データとして OpenAPI の仕様を扱うことができる

    ◦ OpenAPI 同様に BE や FE のソースコードに依存することがない ◦ データ構造を合わせることにより、FEの API のリクエスト/レスポンスの 型の自動生成と相性がよくなる • 懸念点 ◦ 多少の学習コストがかかる ◦ BE側が Node.js(TypeScript)でない場合には、 型の自動生成をするメリットが薄い(OpenAPI でも同様)
  17. 33 踏みがちな課題を設計によって吸収する • /typespec から /frontend への型定義出力について ◦ TypeSpec を編集した際に

    CI などにより型定義の変更が走ることにより、 FE への影響を可視化できる ◦ FE への影響を可視化できることにより運用に組み込んでも、 スキーマ定義変更によるデグレーションなどの心配が少なくなる • FEにAPI定義層を設ける ◦ インタフェースとしての役割が明確になり、APIリクエストによる インプット/アウトプットの型定義をエンドポイント単位で集約でき、 スキーマ定義の変更や、fetchクライアント の変更などにも柔軟に 対応できる
  18. 34 踏みがちな課題を設計によって吸収する • /typespec のディレクトリ構造を刷新後と刷新前で分離しておく ◦ TypeSpec の機能としてバージョンでの管理もできるが、 刷新前と刷新後で APIエンドポイント

    のベースパスの変更や、 新旧API の並行維持期間も存在する可能性があるため、 ディレクトリを分割して管理しておくのがおすすめ ◦ HTMLに出力される仕様書も新旧でそれぞれ出力しやすくなるため、 対応関係が明確になりやすい ◦ BE 移行途中に刷新前のAPI仕様に変更がかかっても柔軟に対応できるなど
  19. 35 設計余談 Q&A • 型の整合性をとるためにZodなどは導入する? ◦ 手動での Zod の実装コストは高くため、限られたリソース下では コスト低減策を検討したい

    ◦ TypeSpec から Zodクライアント を自動生成するためには、 OpenAPI に変換した後、Zod の定義を自動生成をする必要があり、 「Orval」などのツールを使うと可能になる • モノレポ形式ならパッケージとして型定義を提供できない? ◦ パッケージで提供することも可能だがその場合に直接FEを触らない開発者 がAPI仕様を触る場合FEの影響に気づきづらい問題があるため推奨されない
  20. 36 設計余談 Q&A • BE には結局どういうメリットがあるの? ◦ BE は ORM

    などのツールによる実装ベースの型定義出力と比べると、 スキーマ駆動開発ベースの型定義の自動生成による恩恵を受けづらい 事実が存在する ◦ ただ、スキーマ定義はAPI仕様であり BE と FE の間の共通言語というだけ。 宣言的に機能していればプロジェクトにとっての目的を果たしている といえるのでは(FEエンジニアとデザイナー間の Figma の立ち位置だと考える) • TypeSpec の学習コストはどうなの? ◦ OpenAPI を直接 yml で書くより、TypeSpec で構造化データとして 記述するほうが学習コストを加味しても最終的には生産性が高いと考える
  21. 37 おわりに • 今後の展望 ◦ あまり日本では取り上げられていないが、BEエンジニアとの ギャップを埋めるための方法として、スキーマ駆動で API の挙動を Consumer側から契約(Contract)が守られているかを

    テストする「Contract Testing」というテスト手法があるみたい なので調べてみてもいいかも ◦ TypeSpec => OpenAPI => Zod(ランタイムバリデーション) の変換周りはまだまだ発展途上みたいなので色々試してみたい