SQLite
イベント
該当するコンテンツが見つかりませんでした
マガジン
該当するコンテンツが見つかりませんでした
技術ブログ
本記事は「 Merpay & Mercoin Tech Openness Month 2026 」の17日目の記事です。 この記事は新しいロールであるPdE (Product Engineer)というClient / Backend の境界をまたぐ「越境開発」ロールの取り組みについて、@anzai, @victoria Li, @ninnin, @panoramaの4名でお送りします。記事本文は、そのうちの1人である anzai が、自分の体験を一人称で振り返る形で書いています。 はじめに 「Client エンジニアが Backend を書き、Backend エンジニアが Client を書く」——そんな体制は実際に成立するのか。Q4 に試した小さな実験を紹介します。 ひとことでまとめると、Android エンジニアが Postgres のデータベース(DB)設計とサーバー実装を書き、Backend エンジニアが iOS/Android の画面を作りました。やってみて成立はしたものの、楽な道ではありません。何が効いて、どこで詰まったのか。本記事では「越境開発」というテーマに絞って、その実際を共有します。 越境開発の背景 私は普段メルペイでClient(Android / iOS)のチームを見ている Engineering Manager です。今回はManagerとしてではなく、自分の手でコードを書く一員として KYC(本人確認)領域のAI pod (小規模な開発チーム)に参加しました。 このチームでは、Product Manager(PdM)を置かず、エンジニアが1人で1プロジェクトを仕様策定からデリバリーまで一気通貫に持つ(1 Person 1 Release)、という体制を試しています。 そしてこの体制を回そうとすると、避けて通れない課題が1つ出てきます。それは「1人で End-to-End(E2E)に持つなら、Clientも Backend も自分で書くことになる」ということです。 KYC のプロジェクトは、ほとんどの場合 iOS / Android のClientと、サーバー側の API・DB の両方に手を入れます。従来はここをクライアント担当とサーバー担当で分けていました。1人1プロジェクトにするなら、その境界をまたぐ必要があります。E2Eで開発する中で「Client エンジニアが Backend も、Backend エンジニアが Client も開発できるか」を、実プロジェクトで検証することにしました。 いくつかのプロジェクトで Client-Backend を一気通貫で開発した結果、今期はどちらも成立しました。Client エンジニアがサーバーの DB と API を書いてリリースし、Backend エンジニアがモバイルの画面を出す。これ自体が、まず確かめたかったことです。 以下では、私がどう開発を進めたかを時系列で振り返り、そのあとで、どこで詰まったかを共有します。 AI を活用した越境開発の進め方 私はClientエンジニアです。今回担当したプロジェクトで最終的に必要としていたアウトプットは、具体的には2つでした。1つはお客さまに見せる UI/UX、もう1つは、その後の業務報告に使うレポートです。この2つの具体的なアウトプットから逆算して、「では、その裏側でどんな仕組みを実装しなければならないか」を決めていく必要がありました。そしてその仕組みの大部分が、私にとって初めてのサーバーサイド(Go / Postgres)です。 そこでまず、既存の実装を AI Agent に読み込ませ、「この2つのアウトプットを満たすには、どんな設計・実装が必要か」を AI に検討してもらうところから始めました。要件は手元にあるので、あとはそれを初めての言語と環境にどう落とすか。 この記事のここから先は、その道のりを時系列でたどります。 AI の説明もコードも、最初はわからない 最初にぶつかったのは、コードを書く以前の問題でした。AI Agent が返してくる説明そのものが、何を言っているのかわからないのです。 たとえば「Postgres を起動して、goose で既存の migration を流して、psql で確認して」と AI に言われても、最初は何を指しているのか、まったく理解できませんでした。goose とは何か、psql で何を確かめればいいのか ── そのひとつひとつが、Client 開発しかしてこなかった私には初めての言葉です。AI は正しいことを言っているのかもしれないけれど、こちらにそれを受け取る前提知識がない、という状態からのスタートでした。 ここでやったのは、ひたすら AI に問い返すことです。「それはどういう意味か」「図にして説明してくれ」と、いろいろなパターンで噛み砕いてもらう。そして自分が納得できたら、その理解を「こういうことですよね」と、今度は別のBackendエンジニアに確認しに行く。これを繰り返すことで、環境がどう動いていて、何をすればテストが回るのか、開発の前提条件をまず頭に入れていきました。 前提が見えてきたところで、いよいよ実装です。さきほどの要件をもとに「設計して実装してみて」と AI Agent にお願いし、コードを書いてもらいます。すると今度は、出てきたコードそのものが読めません。 なぜここで defer を呼んでいるのか。なぜ cancel() しなければならないのか。ここで context を受け取っているのは、つまりどういうことなのか。Go のイディオムが、ことごとくわからないのです。 そこで最初は、作ってもらったコードを一行一行、すべて AI に解説してもらいました。 context のキャンセルでリソースを解放しないと goroutine が漏れる、だからこの位置で defer cancel() する。そうした説明を1つずつ受けながら、文法書ではなく目の前の実コードを教材にして読み解いていきます。 なお、DB についてはまったくのゼロからではありませんでした。モバイルでも端末上の SQLite でテーブルを設計し、クエリを書く機会はあります。正規化やインデックスといった基礎概念そのものは持っていたので、サーバーの Postgres は「知っている概念を別のコンテキストに翻訳する」作業に近く、そこは助けになりました。 チャンクごとの並走型にたどり着く ただ、「全部書いてもらってから一行ずつ解説」では、どうしても効率が良くありません。これを変えたのが、チームのふりかえりでした。 私たちは週に1回レトロスペクティブを開き、チームの進め方を少しずつ改善していました。その中で、メンバーの一人が「チャンク(意味のある塊)ごとの並走型」というやり方を持ち込みます。AI に一気に全部を生成させるのではなく、意味のあるコードブロック単位で実装させる。そのブロックが「なぜ必要なのか」を自分が理解できればそのまま進め、理解できなければきちんと問い返す。「ここは A と B のやり方がありそうだけれど、なぜ A を選んだのか」と都度たずねていくことで、コードの一行ずつの意図を理解しながら前に進みます。 このやり方だと、巨大な生成物を上から順に読み下す必要がなくなり、開発の流れを「意味のある順序」で理解できます。機械的な行順ではなく、設計の意図に沿った順序で頭に入っていく感覚です。質問と回答はログとして残し、読み返せば「今日は何を学んだか」の復習にもなりました。 選んだ理由を残し、AI のコードを自分で理解する この進め方には、思わぬ副産物もありました。「いくつかの選択肢のなかで、なぜこの A を選んだのか」を開発の過程ですでに言語化しているので、それをそのまま Pull Request(PR)の説明に書けるのです。結果として、レビューはそれほど詰まることなく得られました。初めての領域でも、選択の根拠を添えられればレビュアーは判断しやすいですし、「ここまで考えた上でのPRなんだな」という信頼も得られます。ビギナーのPRを読むことはコードオーナーにとって大変な負担ですので、このような越境開発において信頼を作るための調査は必要な工程だったと思います。 ここで1つ、立ち止まって考えるべき論点があります。AI が書いたコードを、人間がわざわざ読んで理解する必要はあるのか。生成して、テストが通って、動けばよいのではないか。これはこれから重要になる議論だと思います。 私の現時点の答えは「理解すべき」です。 これからの生産性は、書いたコード量ではなく、意思決定の回数と質でほぼ決まっていくと考えています。そして意思決定の質と回数を上げるには、ドメインの理解が必要です。「このバックエンドの設計は、これで本当に正しいのか」を判断する場面で、いまのところ最終的な判断は人間がしています。その判断を下せるだけの理解を持っていないと、意思決定の回数も質も上がっていきません。だからこそ、AI が書いたコードでも中身を理解しておく価値がある、というのが今の立場です。 またAIの仕組み的に、永遠にそのPRに対して改善ポイントを考え出すことができます。たとえば、あるPRについて1回目のセッションでAIに聞くと A・B・C の3点を直すよう言われ、その修正結果を別のセッションで聞くと、今度は E・F・G の3点を直すよう言われる、ということが起こります。それを全部反映すると、最終的にはオーバーエンジニアリングした膨大なPRになりがちなので、現状は「どこまでが適切か」を人が判断する必要があるでしょう。 もしこの「理解する」のに2〜3年かかる長期投資なら、学ぶ理由はもっと厳しく問われるでしょう。ですが実際はそうではありませんでした。いまの AI Agent によるオンボーディングは本当にしやすく、いわば優秀な指導役が隣について、いつでもペアプロに付き合ってくれるような状況です。この環境であれば、3ヶ月もあれば、いま開発している領域の一通りの知識は得られるという手応えがありました。もちろん、もともとシニアエンジニアとしての経験がある、という条件付きではあります。投資回収が数年ではなく数ヶ月の単位に縮んでいるのなら、理解する側を選ぶのが合理的だと考えています。 設計の最終確認はシニアエンジニアと とはいえ、AI に聞けばそのまま採用、とはしませんでした。象徴的だったのがインデックスの設計です。 「このカラムにインデックスを張るべきか」を、AI の提案を鵜呑みにするのではなく、なぜ必要なのか/不要なのかを自分で根拠を持って調べました。どんなクエリパターンで引かれるのか、カーディナリティはどうか、読み取りが速くなるぶん書き込みコストとのトレードオフはどうなるのか。こうした観点を1つずつ確かめて、「この設計にはこういう理由がある」と説明できる状態にします。 それでも、最後はシニアエンジニアと一緒にレビューしました。正直に言えば、これは自分の自信のなさを埋めるためでもありました。AI が生成したものが本当に正しいのか、その最終的な判断が、私一人ではどうしてもつかなかったからです。 このレビューには、不安を消す以上の価値がありました。シニアエンジニアが、考え得るパターンをいくつも挙げてくれたうえで「では、この方法でいきましょう」と意思決定でき、いくつかの改善点も見つかりました。よりベターな やり方にたどり着くうえで、人と一緒に見てもらう工程はやはり必要だったように思います。こちらは Backend エンジニアが Client 開発をする場合も同様でした。 AI で下書きと理解を加速し、自分で根拠を固め、最終的には人とレビューする。この3段構えが、初めての領域で品質を担保し、かつ自分が安心して前に進むうえで、現実的なやり方でした。AI は出発点と伴走者としては非常に強力でしたが、設計の最終的な妥当性を見極め、選択肢を広げてくれるのは、まだ人間のレビューだった、というのが実感です。 なお、今回書いた DB 設計は2テーブルだけのシンプルな構成で、本格的な分散やシャーディングの考慮までは要りませんでした。テーブルが増え、複雑なインデックス設計が絡む規模で、AI とこの3段構えがどこまで通用するのかは、まだ検証できていません。「シンプルだったから回った」可能性は十分にあります。 最後に補足すると、こうして進められた背景には、組織図上で「越境させた」のではなく、同じチームの中で互いの領域をペアプロで教え合える環境があったことが大きいです。AI に聞いてもわからないこと、そもそも何を聞けばいいかわからないことは、隣にいる詳しいメンバーにその場で聞く。AI と人、両方に頼れる相手がいたことが、越境のコストを最も下げました。 つまずいたポイントと対策 ここまでは「どう乗り越えたか」を中心に書いてきましたが、実際には数多くの詰まりどころがありました。そしてその多くは設計や実装の難しさではなく、環境・ツール・運用、つまりコードを書く以外の全部にありました。Client しか書いてこなかった人間が Backend に入ると、ここでことごとく足を取られます。代表的なものを課題ごとに紹介します。 現状の開発スタイルがわからない 最初の壁は、開発スタイルそのものの違いでした。 Clientエンジニアの感覚として、まずローカルでビルドして動作を確認しようとしました。ところが、このコードをもともとメンテナンスしていたチームは、開発環境(dev)にまずデプロイしてから動かす、というスタイルを取っていました。つまり、ローカルの docker compose は、実のところほとんど使われていなかったのです。 私はそれを知らないまま、ローカルの docker compose を立ち上げようとして、「Postgres のバージョンが合わない」「環境変数が無効だ」と、動かない環境を前に四苦八苦しました。結果ローカルでテストできるようになったので良かったのですが、リポジトリ固有のこうした暗黙知は、AI ではどうにもならない部分です。 enum を一つ増やしたら、芋づる式にバージョンが上がる 次につまずいたのは、依存関係の更新でした。やりたかったのは、protobuf の定義に enum を一つ増やし、新しく追加された定数を参照することだけです。ところが、その定義を取り込もうと go mod tidy を実行したとたん、直接は触っていないはずのライブラリのバージョンが一斉に上がってしまいました。gRPC まわりから、最終的には Go 本体の要求バージョンまで動いてしまう。たった一つの enum のために、なぜここまで広がるのか、最初はまったく見当がつきませんでした。 やっかいだったのは、その「なぜ」に対して、もっともらしい説明がいくつも出てきて、しかもそれが間違っていたことです。AI に理由を聞くと、それらしい仮説、たとえば「余計な更新を巻き込んでいるだけだから、最小限に戻せる」といった答えを返してきます。ですが、その通りに戻そうとしても差分は収まりませんでした。 ひたすらAIと問答し、ようやく分かりました。原因は依存が構造的に噛み合っていたことでした。新しい生成ライブラリが新しい gRPC 系を要求し、それがさらに別の基盤ライブラリを引き、最終的に Go 本体の下限まで押し上げている構造だったのです。本当にそうなのかの依存関係のグラフを図示し、それでも自信が持てなかったのでPR Reviewでシニアエンジニアにレビューいただきました。 ローカルでのテストと Lint DB アクセス層(DAO: Data Access Object)のテストをローカルで回そうとすると、ただ実行するだけでは通りませんでした。テスト用の Postgres を専用ポートで立て、 PGPORT を明示的に指定する、といった、チームでは当たり前すぎて誰もドキュメントに書かない作法を、1つずつ踏みながら知っていきます。 たとえば DAO テストは、 5556 のような専用ポートでテスト用の Postgres を立て、 PGPORT でそこを向けて初めて通ります。これを知らないと、テストはローカルの既定のデータベースに接続しようとして、原因の見えないまま失敗し続けます。どこにも書かれていないこの一手にたどり着くまで、エラーメッセージとにらめっこする時間が続きました。 Lint も同様でした。ローカルで走らせると、設定のバージョン差(v1 系と v2 系の非互換)でうまく通らず、CI(Continuous Integration)に任せるという割り切りに落ち着きました。「ローカルで全部緑にしてから push する」という前提が、まず崩れます。 E2E 開発のマシン要件 1人で Client も Backend も1台で回すと、マシンへの負荷が一気に上がります。実際、Android ビルド+エミュレータ、iOS ビルド+シミュレータ、Docker コンテナ3つを同時に動かして、メモリを90GB使う場面がありました。スワップなしで E2E 開発をするなら、96GB は欲しいところです。 特にBackendのEngineerは元々高いスペックのPCを持っておらず、Client開発でまず最初のローカルビルドを試す段階で躓いてしまいました。ここからローカルビルドに耐えるPCを支給してもらうまでClient開発に着手できないということが起きてしまっていました。 越境して E2E を1人で持つということは、ツールチェーンも全部抱えるということでもあります。ハードウェアは目立ちませんが、無視できない条件でした。チーム内でも「越境する人ほどマシン要件が上がる」という前提を共有し、開発機の選定では多めのメモリを見込んでおく必要がある、という話になりました。 振り返って これらの課題に共通していたのは、詰まったポイントのほとんどが、設計や実装の難しさではなく、環境・ツール・運用の暗黙知だったことです。コードを書く力そのものよりも、その手前のところで足を取られていた、というのが実感でした。 ここで効いてくるのが、もともと人間のオンボーディングでも重要だった条件です。「DX(Developer Experience)が整っている」「オンボーディング資料や開発ドキュメントが整備されている」という、人にとっての整備状況が、そのまま AI にとっての整備状況でもありました。ドキュメントが薄く暗黙知に頼っている領域では、人も AI も同じように迷います。 今のところは、やってみて初めてわかる問題を踏んでは1つずつ潰していく、いわば「悲鳴駆動」で進めるしかなく、チームを立ち上げてから数ヶ月は生産性を上げるのが難しいのが正直なところです。逆に言えば、ここをドキュメントとセットアップスクリプトであらかじめ潰しておけば、越境のコストは大きく下げられる、という改善の的もはっきり見えました。次に越境に挑むなら、最初に着手するのはこの整備だろうと考えています。 まとめ KYC で試した範囲では、Client ⇄ Backend の越境開発は成立しました。Client エンジニアがサーバーを書き、Backend エンジニアが iOS/Android を出せています。 それを支えたのは、いくつかの条件でした。まず、小規模な開発チームとして一体で動き、ペアプロやオンボーディングセッションをしながら互いの領域を学べたこと。次に、AI Agent が初見の言語やコードを一文ずつ理解する伴走者になってくれたこと。ただし、設計の最終的な妥当性を見極め、そして開発者の不安を払拭するのは、いまも人間のシニアレビューでした。環境構築やツールのバージョン、ローカルテストといった暗黙知を埋めるには、オンボーディング環境とドキュメントが要ります。一方で、選択の根拠を開発の過程で言語化し、それを残しておけば、専門外の領域でもレビューは回りました。そして最後に、これらすべてを1台で回すには、メモリ96GB級の開発機が現実的に必要でした。 そして、これらが揃っていても、最初の数ヶ月は生産性が落ちます。越境は成長痛とセットでやってくる、というのが一番の学びでした。逆に言えば、その成長痛をチームとして引き受ける覚悟と、AI を含めたオンボーディングの仕組みがあれば、「クライアントエンジニア」「サーバーエンジニア」という肩書きの境界は、思っていたより動かせます。 次は、もっと複雑な DB 設計を含むプロジェクトで、AI がどこまで越境を支えられるのかを確かめていきます。エンジニア一人ひとりが領域をまたいで動けるようになることは、巡り巡って、より早く・より確かな価値をお客さまに届けることにつながると考えています。これからもこういった挑戦を続けていきたいと思います。 次の記事は yutaroさんです。引き続きお楽しみください。
本記事は 2026 年 4 月 17 日 に AWS Migration & Modernization Blog で公開された「 Modernize VB6 Applications at Scale with AWS Transform Custom 」を翻訳したものです。 想定所要時間 : 90 〜 120 分 レベル : 上級 (400) Microsoft は Visual Basic 6.0 (VB6) の延長サポートを 2008 年に終了 (*) しましたが、金融サービス、保険、ヘルスケア、製造業など、数千ものミッションクリティカルなアプリケーションが依然として VB6 に依存しています。これらのアプリケーションには数十年分のビジネスロジックが含まれていますが、年々メンテナンスが困難になっています。VB6 開発者は労働市場に残る人数が減少しているため採用コストが上昇し、パッチ未適用の脆弱性はコンプライアンス違反のリスクを高め、モノリシックなアーキテクチャは AI、アナリティクス、クラウドサービスとの統合を困難にしています。 * 訳注:厳密には、VB6 の IDE のサポートは終了してますが、VB6 のランタイムはまだサポートはされています。ランタイムは Windows のライフタイムに合わせてサポート継続されていますが、対応は重大なセキュリティ問題等に限定されています。詳細は こちら を参照してください。 これらの課題は、AWS Transform custom でカスタム変換プランを作成することで解決できます。 この記事では、AWS Transform custom のエージェンティック AI 機能を活用して、組織固有のビジネスルールを維持しながら VB6 アプリケーションを大規模にモダナイズする方法を紹介します。 VB6 モダナイゼーションの課題 VB6 アプリケーションのモダナイゼーションには、単純な構文変換を超えた固有の課題があります。 AWS Transform for .NET は .NET Framework アプリケーションの自動ポーティングを提供していますが、VB6 には固有の特性があるため、異なるアプローチが必要です。 VB6 のモダナイゼーションでは、レガシープラットフォームとモダンな .NET の間にある根本的なアーキテクチャの違いに対処する必要があります。言語レベルでは、VB6 の手続き型および COM ベースのパターンをオブジェクト指向の C# 構造にマッピングする必要があります。ユーザーインターフェースも、ActiveX コントロールを使用した VB6 フォームから Blazor や ASP.NET Core MVC などのモダンな Web フレームワークへの変換が必要です。データアクセスパターンはレガシーな ADO や DAO から Entity Framework Core の async/await パターンに移行し、COM 依存関係は .NET ネイティブの代替手段や NuGet パッケージに置き換える必要があり、エラーハンドリングは On Error Resume Next や On Error GoTo パターンから構造化された try-catch 例外処理に移行します。 サンプルアプリケーションの紹介 Salmon King Seafood (SKS) という VB6 Multiple Document Interface (MDI) アプリケーションを使って AWS Transform custom を解説します。これは典型的なエンタープライズモダナイゼーションの課題を表すアプリケーションです。SKS は以下の特徴を持つ水産物受注管理システムです。 15 以上の VB6 フォーム – 受注、顧客管理、商品カタログ、在庫管理、承認ワークフローを含む 3 つの VB6 モジュール (modConnection.bas、modFunctions.bas、modMain.bas) – 共有ビジネスロジックとデータベース接続を含む SQLite データベース (Orders.db) – ADO データコントロールとデータバインディングを通じてアクセス 標準 VB6 コントロール – MSFlexGrid、ListView、Toolbar、ImageList、ComboBox、Control Arrays を含む MDI アーキテクチャ – メインコンテナフォームとメニューからトリガーされる子フォーム このアプリケーションは、エンタープライズアプリケーションでよく見られる VB6 パターンを実装しています。 イベントハンドラを持つフォームベースの UI データバインディングを使用した ADO データアクセス COM ベースのコントロール モジュール内の手続き型ビジネスロジック これらの要素により、SKS はエンタープライズ VB6 モダナイゼーションで遭遇する複雑さを代表するものとなっています。 ソリューション概要 VB6 から C# へのモダナイゼーションには、AWS Transform custom の複雑な変換パターンの学習・適用機能を活用できます。エンドツーエンドのプロセスは以下のステージに従います。 評価 – VB6 アプリケーションポートフォリオのスコープと複雑さを評価する 定義 – VB6 から C# への変換パターン、ビジネスルール、コーディング標準を含むカスタム変換を定義する 実行 – 大規模に変換を実行する レビューと反復 – フィードバックループによる継続的な改善を行いながらレビューと反復を行う このアーキテクチャにより、変換定義を一度作成してテストし、数百のアプリケーションに適用できます。 前提条件 開始する前に、以下を確認してください。 AWS Transform Custom へのアクセス権を持つ AWS アカウント 。現在の料金の詳細については、AWS Transform の料金ページをご覧ください。 ATX CLI (Command Line Interface) がインストールされた MacOS または Linux 環境。詳細なセットアップ手順については、 AWS Transform custom 前提条件ガイド を参照してください。 **Windows 開発者の場合** : WSL2 (Windows Subsystem for Linux) をインストールし、Ubuntu またはその他の Linux ディストリビューションから ATX CLI を実行してください。CLI は `/mnt/c/` パスを通じてローカルコードベースを直接操作します。 変換後のアプリケーションをテストするための .NET 10 SDK 以降 コードレビュー用の Visual Studio 2022 以降または Visual Studio Code VB6 および .NET の開発知識 有効な認証情報が設定されている Git があること 環境の準備 Salmon King Seafood (SKS) サンプルアプリケーションをダウンロードします。これには、典型的なエンタープライズ VB6 ワークロードを代表する VB6 MDI アプリケーションが含まれています。 リポジトリをローカルマシンにクローンします。 git clone https://github.com/GAPVelocityAI/SKSVB6.git cd SKSVB6 Windows で WSL2 を使用している場合は、両方の環境からアクセス可能なパスにクローンします。 git clone https://github.com/GAPVelocityAI/SKSVB6.git /mnt/c/Projects/SKSVB6 cd <path-to-repository> リポジトリの内容を確認します。VB6 プロジェクトファイル (SKS.vbp)、フォームファイル (.frm/.frx)、モジュール (.bas)、SQLite データベース (Orders.db) が表示されます。 ls -la *.vbp *.frm *.bas *.db 変換追跡用にリポジトリを初期化します。 git add . git commit -m "Baseline before VB6 to C# transformation" 次に、リファレンスドキュメントを含むリポジトリをクローンします。このリポジトリには、AWS Transform にコンテキストとして渡すビジネスルールと変換例が含まれており、組織の標準に合ったコードを生成します。 git clone -b dotnet-transform-custom https://github.com/aws-samples/dotnet-genai-samples.git ウォークスルー 以下のセクションでは、AWS Transform CLI を使用して VB6 コードをモダンな C# プロジェクトに変換する手順を説明します。 ステップ 1: VB6 アプリケーションを評価する 変換定義を作成する前に、VB6 ポートフォリオのスコープと複雑さを把握します。SKS リポジトリをクローンした状態で、ATX CLI を起動して評価を開始します。 atx custom def exec -p <path-to-repository> \ -n 'AWS/early-access-comprehensive-codebase-analysis' \ -t パラメータ : -p: ソースプロジェクトのパス (クローンした SKS リポジトリ) -n: 変換定義名 -t: 変換に関わるすべてのツールを信頼し、実行中に AWS Transform が許可を求めて一時停止するのを防ぐ 注意 :2026 年 5 月 1 日時点では、変換定義名は AWS/early-access-comprehensive-codebase-analysis から AWS/comprehensive-codebase-analysis に変更になっています AWS Transform custom は、シェルスクリプトなどの特定のアクションを実行するために許可を必要とします。上記のコマンドの –t 引数により、ツールはユーザーに継続的にプロンプトを表示することなく実行できます。 評価では SKS プロジェクトを分析し、フォーム数 (15 以上)、モジュール数 (3)、COM コンポーネントの依存関係 (MSFlexGrid、ListView)、データベースアクセスパターン (ADO with SQLite)、推定変換複雑度スコアを含む包括的なレポートを生成します。 この評価レポートを使用して、VB6 アプリケーションを変換する際に AWS Transform custom に追加のコンテキストを提供します。 ステップ 2: VB6 から C# へのカスタム変換定義を作成する 次に、VB6 からモダンな C# への変換パターンとルールをキャプチャするカスタム変換定義を作成します。AWS Transform custom は、提供された例、ドキュメント、ビジネスルールから学習し、これらのパターンを一貫して適用します。 対話型 CLI を起動します。 atx -t プロンプトが表示されたら、変換の説明として VB6 to C# ASP.NET Core web application migration と入力します。AWS Transform custom は既存の変換を検索し、この特定のシナリオに該当するものが見つからない場合、カスタム変換を作成するかどうかを尋ねます。「create a new one」と入力して確認します。 図 1 – atx cli の起動 変換コンテキストとビジネスルールの提供 AWS Transform custom は、ドキュメント、移行ガイド、サンプルコードの提供を求めます。ここで組織固有の要件を追加します。SKS アプリケーションについては、そのアーキテクチャに関するコンテキストを提供します。 Salmon King Seafood (SKS) という VB6 MDI アプリケーションがあります。ソースコードは <path-to-repository> にあります。注文受付、顧客管理、製品カタログ、在庫管理、承認ワークフローなど、15 以上のフォームがあります。3 つのモジュール (データベース接続用の modConnection.bas、ユーティリティ関数用の modFunctions.bas、アプリケーションのエントリ ポイント用の modMain.bas) を使用しています。データベースは SQLite で、データ バインディングを使用した ADO データ コントロールを介してアクセスします。コントロールには、MSFlexGrid、ListView、Toolbar、ImageList、およびコントロール アレイが含まれます。これを .NET 10 をターゲットとする ASP.NET Core Blazor Server アプリケーションに変換してください。 組織向けの移行パターンのカスタマイズ 移行の精度を向上させるために、組織固有のマッピングルールを提供します。これらはユーザーが作成したマークダウンファイルで、AWS Transform custom からプロンプトが表示された際に参照します。AWS Transform custom はこれらを変換プランに組み込みます。プロンプトが表示されたら、対話型セッション中に VB6 ソースコードとともにこれらのファイルを参照します。 図 2 – 変換プランへのビジネスルールやその他のコンテキストの追加 変換例の参照 <path-to-repository>/dotnet-genai-samples/src/Amazon.GenAI.TransformCustom/vb6-csharp-references/example-transformations.md ファイルを確認します。ATX エージェントがサンプル変換を求めるプロンプトを表示したら、以下のように参照します。 変換前後の例は、<path-to-repository>/dotnet-genai-samples/src/Amazon.GenAI.TransformCustom/vb6-csharp-references/example-transformations.md にあります。 企業コーディング規約の参照 AWS Transform custom では、組織のコーディング規約を変換に使用することでコード生成を制御できます。これには特定の C# の機能や規約を含めることができます。AWS Transform custom はこれらを使用して、チームのスタイルに合ったコードを生成します。<path-to-repository>/dotnet-genai-samples/src/Amazon.GenAI.TransformCustom/vb6-csharp-references/coding-standards.md ファイルを確認します。組織のプラクティスに合わせて独自の規約を作成できます。 例 : <path-to-repository>/dotnet-genai-samples/src/Amazon.GenAI.TransformCustom/vb6-csharp-references/coding-standards.md で定義されているコーディング規約を適用してください。 ターゲットアーキテクチャ仕様の参照 オプションとして、 <path-to-repository>/dotnet-genai-samples/src/Amazon.GenAI.TransformCustom/vb6-csharp-references/target-architecture.md にあるような、望ましい出力アーキテクチャを記述したドキュメントを使用できます。 AWS Transform custom は参照されたすべてのファイルを読み取り、組織のパターン、規約、アーキテクチャに合った変換プランを生成します。 生成された変換定義 あなたの入力に情報に基づいて、AWS Transform custom はフェーズごとに整理された包括的な変換定義を生成します。 フェーズ 1 – 分析 : VB6 コンポーネントのインベントリ、依存関係の特定、依存関係グラフの作成 フェーズ 2 – プロジェクト構造 : ASP.NET Core Blazor Server プロジェクトの生成、NuGet パッケージの設定、依存性注入のセットアップ フェーズ 3 – データレイヤー : ADO/DAO から Entity Framework Core への変換、DbContext とエンティティモデルの生成 (適切な場合は record 型を使用) フェーズ 4 – ビジネスロジック : モジュールからサービスクラスへの変換 (プライマリ コンストラクターを使用)、関数から async メソッドへの変換 フェーズ 5 – UI レイヤー : VB6 フォームから Blazor コンポーネントへの変換、イベントハンドラの変換 フェーズ 6 – 検証 : ビルド成功の確認、ユニットテストの生成、機能的等価性のテスト 変換定義をすぐに適用するか、レビューして修正するか、レジストリに公開して再利用するか、新しいプランを開始するかを選択できます。次のステップでは、大規模に再利用できるように変換定義を公開します。 AWS Transform custom は変換プランの名前と説明を提案してきます。そのまま受け入れるか、必要に応じて修正できます。これで変換定義がチーム全体で利用可能になります。 カスタム変換定義の表示と管理 公開後、対話型エージェントまたは以下の CLI コマンドを使用して、カスタム変換定義と利用可能なすべての AWS マネージド変換を表示できます。 atx custom def list 図 3 – ユーザーが作成したカスタム変換プランの一覧 このコマンドは、AWS マネージド変換 (AWS/ プレフィックス付き) とカスタム定義の変換の両方を表示します。カスタム定義の下に VB6-to-CSharp-Blazor-Migration 変換プランが表示されます。 ステップ 3: 変換を実行する カスタム変換定義を公開したら、VB6 アプリケーションのモダナイゼーションを実行できます。プロンプトが表示されたら、プロジェクトに対して変換プランを実行します。リポジトリへのパスと、変換後にプロジェクトをビルドするためのビルドコマンドを与える必要があります。 図 4 – 変換を検証するためのビルドコマンドの追加 以下のコマンドを使用して変換プランを直接ターミナルから実行することもできます。 atx custom def exec -p <path-to-repository>\ -n 'VB6-to-CSharp-Blazor-Migration' \ -t AWS Transform custom が認識すべき追加のコンテキストを提供するかどうかを尋ねられます。これは、保存された変換定義には含まれないその場限りのコンテキスト (コード分析で生成されたドキュメントなど) を提供する場合に便利です。 図 5 – 変換プラン生成前の追加コンテキストの追加 プロンプトに回答すると、AWS Transform は実行またはレビュー・修正するための変換プランを生成します。 図 6 – 変換プランのレビューまたは続行 変換プランの内容に問題なければ 続行する 変換エージェントは SKS プロジェクトの構造を分析し、MDI コンテナ (frmMain.frm)、子フォーム、モジュール、データベースパターンを特定してから、変換定義を適用します。エージェントは以下を変換します。 frmMain.frm (MDI コンテナ) → ナビゲーションメニュー付きの Blazor MainLayout.razor frmCustomers.frm、frmProviders.frm など → 個別の Blazor ページコンポーネント modConnection.bas → Entity Framework Core と SQLite プロバイダーを使用した SksDbContext.cs modFunctions.bas → ドメインごとに整理された拡張メソッドクラス MSFlexGrid データグリッド → データバインディング付きの Blazor テーブルコンポーネント ADO データコントロール → async/await を使用した Entity Framework Core クエリ ステップ 4: レビュー、テスト、反復 変換が完了すると、AWS Transform custom は変換されたコードを新しいブランチまたはディレクトリに出力し、変換レポートと手動修正の次のステップを提示します。 変換結果のレビュー 変換レポートには、以下を含む終了基準の検証が含まれます。 dotnet build がエラーゼロで成功 すべての VB6 フォームが Blazor コンポーネントに変換済み (例: frmCustomers.frm → Customers.razor、frmOrderReception.frm → OrderReception.razor) データアクセスレイヤーが Entity Framework Core と SQLite プロバイダーおよび async パターンを使用 (ADO/ADODC データコントロールを置換) COM 依存関係の排除 — MSFlexGrid は Blazor テーブルコンポーネントに、Toolbar/ImageList は Blazor ナビゲーションに置換 エラーハンドリングが On Error 文から構造化された try-catch 例外処理に変換 仕様に従ったモダンな C# 機能の適用 (レコード型、プライマリコンストラクター、パターンマッチング) modConnection.bas が IDbContextFactory<SksDbContext> を使用した登録済み Dependency Injection (DI) サービスに変換 AWS Transform は 1 回の実行で検証基準を満たさない場合があります。変換の実行後、成功した部分と失敗した部分のサマリーを含む部分的な変換結果が得られることがあります。以下に変換結果を示します。 図 7 – 完了した変換結果 フィードバックプロンプトから、未達成の基準に対処するために変換を再実行できます。変換された SKS アプリケーションを検証するには、ターミナルに切り替えて以下を実行します。 cd <path-to-your-project> dotnet build dotnet run ブラウザで https://localhost:<port> にアクセスし、以下に示すように Blazor アプリケーションが受注、顧客管理、商品カタログのページを正しくレンダリングすることを確認します。 図 8 – 請求書作成ページ 図 9 – 注文作成ページ 機能が不足している場合は、CLI にフィードバックを返して変換結果を繰り返し改善します。 Transform コマンドのパフォーマンス Transform custom コマンドは、変換対象のコードベースのサイズに応じて、完了までに最大 60 分かかる場合があります。コードファイルや依存関係が多い大規模なプロジェクトでは、当然ながらより多くの処理時間が必要になります。 変換の制限事項について Transform custom の機能では、VB6 アプリケーションのすべての機能を自動的に変換できるとは限りません。変換完了後、ソースの VB6 アプリケーションと変換先の C# アプリケーション間の機能を比較・検証する必要があります。変換されなかった不足機能については、 Kiro や Amazon Q Developer などの AI 搭載ツールを使用して、ソースから変換先のコードベースへの変換・移植を支援できます。 ユニットテストの重要性 ユニットテストは、変換プロセス全体を通じて機能の正当性を検証します。変換されたコードが元の VB6 アプリケーションと同一の動作をすることを確認し、変換中に導入された不一致やリグレッションを迅速に特定するのに役立ちます。変換前に一連のテストを整備してください。これがリグレッションテストの基準となり、変換後も同等に動作することを検証できます。 まとめ 組織固有のパターン、ビジネスルール、モダンな C# 機能の設定を含むカスタム変換定義を使用することで、組織に蓄積された知見を維持しながら数百の VB6 アプリケーションを体系的にモダナイズできるようになりました。 変換を一度定義すれば、アプリケーションポートフォリオ全体に適用できます。これにより、再利用可能な変換定義に組織に蓄積された知見が保存されます。フィードバックループによる継続的な改善により、各変換はより洗練され、レコード型、プライマリコンストラクター、パターンマッチングなどのモダンな C# 機能がコードベースに自動的に適用されます。モダナイズされたアプリケーションは Linux と AWS Graviton 上で動作し、インフラストラクチャコストを削減できる可能性があります。 AWS Transform custom を使用して VB6 アプリケーションポートフォリオのモダナイゼーションを始めましょう。セットアップ手順については、 AWS Transform custom Getting Started Guide をご覧ください。 追加リソース AWS Transform custom Getting Started Guide AWS Transform custom Product Page AWS Transform custom Documentation AWS Transform custom Command Reference AWS Transform for .NET .NET on AWS Developer Center 翻訳はソリューションアーキテクトの Yoshinori Sawada が担当しました。原文は こちら です。 著者について David Kilzer David Kilzer は、AWS エコシステム内での Microsoft ワークロードの最適化を専門とするソリューションアーキテクトです。C#、SQL Server、そして AWS サービスを用いた最新のソフトウェアソリューション構築に関する専門知識を有しています。 Ashish Bhatia Ashish Bhatia は、AWS のシニアソリューションアーキテクトで、エンタープライズのお客様のクラウドジャーニーのガイドに注力しています。AWS のクラウドネイティブサービスを使用して最新のソフトウェアソリューションを構築するお客様を支援することに情熱を注いでいます。また、彼は Amazon Web Services のスペシャリストソリューションアーキテクトです。最先端の生成 AI ソリューションの作成に取り組み、お客様中心のアプローチを優先しています。 Ty Augustine Ty Augustine は、.NET、SQL Server、コンテナを専門とする Microsoft スペシャリストソリューションアーキテクトです。ニューヨークを拠点に、様々な業界の企業と緊密に連携し、AWS クラウドへの移行とモダナイゼーションを加速させています。AWS に入社する前は、20 年以上にわたり Microsoft スタックのソフトウェアアーキテクトとして活躍していました。
はじめに こんにちは、Checkout Reliabilityチームでバックエンドエンジニアをしているかがの( @ykagano )です! こちらは、「継続的な負荷テスト環境をBASEに構築しました」の第3回の記事です。 先に第1回、第2回を読んでいただくのをおすすめします。 継続的な負荷テスト環境をBASEに構築しました 〜 第1回: 負荷テストの全体像 - BASEプロダクトチームブログ 継続的な負荷テスト環境をBASEに構築しました 〜 第2回: 負荷生成ツールの構築と運用 - BASEプロダクトチームブログ こちらは第1回から紹介しているBASEの負荷テスト環境の構成図です。 負荷テスト環境の構成図 本記事では、モックツールとして採用したWireMockの選定理由から、実際の構築・運用方法までを紹介します。 モックツールの選定 モックツールも要求事項は負荷生成ツールと基本的には同じでした。 以下は第2回の記事からの要求事項の引用です。 OSSである クラウドはコストとセキュリティの両面でハードルが上がるため 分散実行が可能である 継続的負荷テスト環境としてスケーリングは必要 Web UIがある レポート品質が高い 学習コストが低い メンバーの誰もが利用できるようにしたい 実績が豊富である OSSが今後も保守される可能性が高い こちらもOSSの比較表を参考として整理しました。 ツール 分散実行可能 Web UI 学習コスト 実績が豊富 特徴 WireMock △(自前スクリプトが必要) △(標準UIなし) ○(機能が豊富) ◎ 業界標準。機能は強いが、UIと分散は独自実装が必要 MockServer △(状態は共有できない) ○ ○(機能が豊富) ○ UIあり・機能も豊富 Smocker △(分散は想定されていない) ○ ○(YAML/JSON定義が直感的) △ UI特化・軽量。個人/小規模チーム向け モックツールは他にも多数あるのですが、実績や保守性がWireMockとMockServerが突出しているように感じたため、まずこの2つを候補としました。 そして他のツールもWeb UIをそれぞれ実際に触ってみた結果、SmockerのUIが使いやすく思えたため候補に加えた形です。 しかし保守性を考えると実績の豊富なWireMockが良いと思っており、UIの課題と分散実行の部分をクリアできないかと調査を進めました。 継続的な負荷テストを実施するためには、複数のモックサーバーに対して、スタブの設定を容易かつ即時で変更できるUIが必要と考えていたためです。 WireMockのサードパーティのUIも探しましたが、複数のWireMockインスタンスに即時で反映できるようなUIはありませんでした。 そのため、個人的にWireMock HubというOSSを作ることにしました。 ykagano.github.io スタブの編集がUIから行え、複数のWireMockインスタンスに即時で反映できる機能をメインに実装しています。 WireMockと組み合わせることで、使い勝手の良い負荷テスト用のモックツールとなります。 wiremock.org WireMockの構築 ECSに構築しました。 下図では負荷テスト用にWireMockを2台起動しています。 Nginxは外部APIのRate-Limiter(流量制限)を再現するために使用しています。 ECSでのWireMockの構成 またその後ろにWireMock HubのAll-in-One版を起動しています。 1つのコンテナの中にNginx + WireMock Hub + WireMockを内包しています。 負荷テストのために、Web UIを持つWireMock Hubがスタブデータの管理とWireMockへの同期を行います。 負荷テスト用のWireMockは負荷テスト利用時にだけ起動していますが、WireMock Hubだけを日常的に起動しておくこともできます。 こうすることで負荷テスト以外の場面でも、外部APIの異常系のテストなどでWireMock Hubの内包するWireMockをUI付きで日常的に使用することができます。 今回負荷テスト環境を構築しましたが、副産物として、日常的にWireMockを使用できるようになったものとなります。 WireMock Hubの構成 WireMock HubはSQLiteのDBを持っています。 プロジェクトの配下にWireMockのインスタンスとスタブが紐付く構造にしています。 そのため、プロジェクトの持つスタブをインスタンスに対して入れ替えることも可能になっています。 プロジェクト ├─ インスタンス └─ スタブマッピング 実際にWireMock Hubに登録しているプロジェクトです。 WireMock Hubのプロジェクト画面 次はインスタンスです。 WireMock Hubのインスタンス画面 例えば、過去のプロジェクトで使用したスタブをもう一度使いたいという時に、プロジェクトの持つスタブを同期させて入れ替えることも、追記して他のプロジェクトで同期したスタブと同居することもできます。 このように、WireMock HubはWireMockを1台だけ利用したい場合にも便利に使えるようになっています。 WireMock Hubからのスタブ登録 WireMock Hubからのスタブの登録方法は以下の3種類があります。 UIでのスタブ編集(下図 Create Newボタンや編集アイコンボタン) スタブファイルのインポート機能(下図 Importボタン) プロキシ機能を使ったレコーディング機能(下図サイドメニューのRecording) WireMock Hubのスタブマッピング画面 このうち、負荷テスト環境の構築時は、主にレコーディング機能とインポート機能を使っていました。 レコーディング機能 レコーディング機能はWireMockが標準搭載している機能です。 まだ何もスタブに登録していない場合、レコーディング機能はとても役に立ちます。 WireMock Hubのレコーディング画面 レコーディング画面でTarget URLを指定して開始すると、WireMockが対象のURLに対するプロキシ(中継サーバ)になります。 この状態でBASEシステムと外部システムの間にWireMockを挟んで通常のリクエストを通すことができます。 図にするとこのように右上から通常の購入リクエストがBASEシステムに入ってきますが、 BASEシステムが左のWireMockに外部サービスへのリクエストを投げて、結果、外部サービスにリクエストが到達します。 WireMockがプロキシとして外部サービスに通信している図 こうすることで、WireMockに実リクエストが記録されます。 レコーディングを停止するとWireMockには記録された実リクエストがスタブとして登録されます。 WireMockのリクエストログにも記録されているため、リクエストログからWireMock Hubにスタブ登録することも可能です。 その後、汎用的なスタブにするための調整は必要ですが、レコーディング機能を使えば、スタブデータを手で書くことなく登録できます。 インポート機能 インポート機能はWireMock HubからWireMockのJSON形式とOpenAPI形式の両方がインポートできます。 WireMock形式のJSON例 { " mappings ": [ { " request ": { " method ": " GET ", " url ": " /test " } , " response ": { " status ": 200 , " headers ": { " Content-Type ": " application/json " } , " body ": " { \" message \" : \" success \" } ", " fixedDelayMilliseconds ": 2000 } , " priority ": 5 , " persistent ": true , " name ": " テストだよ ", " scenarioName ": " test ", " requiredScenarioState ": " Started ", " newScenarioState ": " Step_2 ", " metadata ": { " hub_isActive ": true } } ] , " meta ": { " total ": 1 } } 例えばレコーディング機能で記録したスタブを、WireMockのJSON形式でエクスポートしておけば、以降はClaude Codeで編集することができます。 例えばモニタリングツールに記録された外部APIの通信時間の平均をスタブの遅延時間(fixedDelayMilliseconds)に一律で設定するといったこともできますし、実際にこうしたスタブの設定調整をClaude Codeを通して行っています。 WireMock HubからWireMockへの自動同期 WireMock HubはWireMockとは疎結合なアプリケーションとして設計しています。 そのため、ECSでWireMockを再デプロイした場合、WireMock Hubに登録していたWireMockインスタンスのIPアドレスが変わってしまうことになります。 毎回、WireMockインスタンスのIPアドレスを調べて再登録せずに済むように、WireMock Hubにはインスタンスの再登録APIを用意しています。 下図が同期処理のシーケンス図となります。 LambdaのAPI経由でインスタンスIPリストを取得し、WireMock HubのAPIに渡すことで、インスタンスIPアドレスを更新し、WireMock Hubのプロジェクトに紐付くスタブをWireMockに自動同期します。 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: true }); sequenceDiagram participant gha as GitHub Actions participant tf as Terraform participant ecs as ECS Fargate<br/>(WireMock Worker) participant sd as Service Discovery<br/>(Cloud Map) participant lambda as Lambda<br/>(wiremock-sync) participant hub as WireMock Hub %% Phase 1: Terraform デプロイ Note over gha, ecs: Phase 1: Terraform デプロイ gha ->> tf : wiremock-hub apply activate tf tf ->> hub : WireMock Hub デプロイ activate hub tf -->> gha : apply 完了 deactivate tf gha ->> tf : wiremock apply activate tf tf ->> ecs : WireMock Worker デプロイ activate ecs ecs ->> sd : タスクIP自動登録(HEALTHY) note right of sd : wiremock-worker.cart-load-test.local<br>→ 172.20.10.x tf -->> gha : apply 完了 deactivate tf %% Phase 2: GitHub Actions による Lambda invoke Note over gha, lambda: Phase 2: Lambda invoke gha ->> lambda : aws lambda invoke activate lambda %% Phase 3: Lambda 処理 Note over lambda, sd: Phase 3: Service Discovery からインスタンス取得 lambda ->> sd : discover_instances(HEALTHY のみ) activate sd sd -->> lambda : インスタンスIPリスト返却 deactivate sd %% Phase 4: Hub API → スタブ配信 Note over lambda, hub: Phase 4: Hub API 呼び出し → スタブ配信 lambda ->> hub : POST /hub/api/projects/{id}/instances/bulk-update note right of hub : {"instances": [...], "syncStubs": true} hub ->> hub : インスタンスIP更新 hub ->> hub : プロジェクトのスタブ定義を取得 hub ->> ecs : POST /__admin/mappings(各 Worker) ecs -->> hub : スタブ登録完了 hub -->> lambda : 同期結果 lambda -->> gha : 完了 deactivate lambda deactivate ecs deactivate hub この仕組みによって、WireMock側の再デプロイをしても、負荷テストに必要なスタブは常に担保されます。 おわりに WireMockはノーコードでスタブが作れますので、開発中APIの代替や異常系の通信テストなどにも便利です。 今回作ったWireMock環境は、カート機能だけでなく、社内で誰でも使えるモックツールとして日常的に使っていければと思います。 全3回の記事を最後までお読みいただきありがとうございました! モックを使ったテストに興味がありましたらぜひ採用情報をご覧ください! binc.jp
動画
該当するコンテンツが見つかりませんでした









