Microsoft developer platformのAspire 13.3で注目すべき変更は、multi-language AppHosts向けの環境変数設定APIが、値の種類ごとに分かれていた withEnvironment* から、単一の withEnvironment(name, value) に整理されたことです。特にTypeScript AppHostや、C#のAspire Hosting integrationをTypeScript、Python、JavaなどのAppHostから使えるようにしている開発者は、旧メソッドの利用箇所、生成SDK、IExpressionValue を扱うカスタム型を確認する必要があります。
今回のドキュメント更新PRは、2026年5月5日に microsoft/aspire#15649 の変更を文書化するために作成され、release/13.3 ブランチを対象としていました。PR自体は2026年5月6日にマージされています。内容は、Aspire 13.3の「unified withEnvironment API」と、C#側の IExpressionValue をmulti-language AppHosts向けに説明するものです。(GitHub)
Aspire 13.3のwithEnvironment統一APIで何が変わったのか
これまでpolyglot AppHostでは、環境変数に渡す値の種類によって、次のような専用メソッドを使い分ける必要がありました。
| 従来の考え方 | Aspire 13.3での考え方 |
|---|---|
エンドポイントなら withEnvironmentEndpoint | withEnvironment(name, value) に統一 |
パラメーターなら withEnvironmentParameter | withEnvironment(name, value) に統一 |
接続文字列リソースなら withEnvironmentConnectionString | withEnvironment(name, value) に統一 |
式なら withEnvironmentExpression | withEnvironment(name, value) に統一 |
| Bicep出力やKey Vault Secretなども専用メソッドで扱う | 統一APIへの移行対象として整理 |
Aspire 13.3のドキュメントでは、polyglot AppHosts、つまりTypeScript、Java、Python、Go、RustなどのAppHostで、単一の withEnvironment(name, value) が複数の値の種類を扱うAPIとして説明されています。受け付ける値には、通常の string、ReferenceExpression、EndpointReference、パラメータービルダー、接続文字列リソースビルダー、IExpressionValue が含まれます。(GitHub)
実務的には、「環境変数を入れるときに、値の種類ごとにメソッド名を覚える」運用から、「環境変数名と値を渡すだけ」の運用へ寄せる変更です。
変更前後のコードイメージ
TypeScript AppHostでは、従来は次のように値の種類ごとにメソッドを選ぶ必要がありました。
await api
.withEnvironmentEndpoint('SERVICE_URL', cache.primaryEndpoint)
.withEnvironmentParameter('API_KEY', apiKeyParam)
.withEnvironmentConnectionString('DB', database)
.withEnvironmentExpression('REDIS_URL', redisExpression);
Aspire 13.3以降は、次のように統一できます。
await api
.withEnvironment('SERVICE_URL', cache.primaryEndpoint)
.withEnvironment('API_KEY', apiKeyParam)
.withEnvironment('DB', database)
.withEnvironment('REDIS_URL', redisExpression);
この変更により、AppHostの記述は短くなります。さらに、環境変数の値がエンドポイントなのか、パラメーターなのか、接続文字列なのかをメソッド名で分岐させる必要が減るため、レビュー時にも「どの環境変数に何を渡しているか」を追いやすくなります。
IExpressionValue は何のために追加されたのか
IExpressionValue は、C#側で「実行時の値」と「publish時に使うmanifest expression」の両方を提供できる値を表すための抽象化です。ソース上では、IValueProvider と IManifestExpressionProvider を継承するpublic interfaceとして定義されています。(GitHub)
Aspireでは、ローカル実行時に解決される値と、publish時にmanifestへ表現として出力される値を分けて考える場面があります。たとえば、Azureリソースの出力、Key Vault Secret、接続文字列、エンドポイント参照のように、単なる文字列ではなく、実行環境やデプロイ先によって解決される値です。
IExpressionValue があることで、こうした値を withEnvironment(name, value) の統一APIに乗せやすくなります。PR #15649では、C#側にpublicな IExpressionValue 抽象化と WithEnvironment(..., IExpressionValue) サポートを追加し、既存のコンストラクターやオーバーロードを壊さない形で環境値の共通基盤を用意したと説明されています。(GitHub)
誰が対応すべきか
今回のMicrosoft developer platform documentation updateは、すべてのAspire利用者に即時修正を求めるものではありません。影響が大きいのは、multi-language AppHostsを使っているチームと、Aspire Hosting integrationを作っているチームです。
| 対象者 | 対応優先度 | 確認すべきこと |
|---|---|---|
| TypeScript AppHostを使っている開発者 | 高 | withEnvironmentEndpoint など旧ヘルパーを使っていないか |
| Python、Java、Go、Rustなどpolyglot AppHostを検証しているチーム | 高 | 生成SDKに統一APIが反映されているか |
| Aspire Hosting integrationを公開している開発者 | 高 | ATS exportで IExpressionValue やunion型を正しく扱えるか |
| C# AppHostのみを使っている一般利用者 | 中 | 既存コードが動くか、将来の移行予定を把握する |
| CI/CDでAppHost生成SDKをキャッシュしているチーム | 中 | 古い .modules/ や生成SDKを使い回していないか |
C# AppHostだけを使っていて、TypeScript AppHostやpolyglot SDKを使っていない場合、今回の変更による作業は限定的です。ただし、将来的にTypeScript AppHostへ移行する予定がある場合や、社内共通のAspire integrationを作っている場合は、早めに旧API依存を減らしておく価値があります。
旧 withEnvironment* からの移行表
Aspire 13.3のドキュメントでは、TypeScript AppHost向けに旧 withEnvironment* ヘルパーは非推奨となり、統一 withEnvironment(name, value) へ置き換える移行表が示されています。(GitHub)
| 旧メソッド | 移行後 |
|---|---|
withEnvironmentExpression(name, expr) | withEnvironment(name, expr) |
withEnvironmentEndpoint(name, endpoint) | withEnvironment(name, endpoint) |
withEnvironmentParameter(name, param) | withEnvironment(name, param) |
withEnvironmentConnectionString(name, resource) | withEnvironment(name, resource) |
withEnvironmentFromOutput(name, output) | withEnvironment(name, output) |
withEnvironmentFromKeyVaultSecret(name, secret) | withEnvironment(name, secret) |
移行時のポイントは、単にメソッド名を置換するだけで終わらせないことです。値の型が意図どおり解決されるか、ローカル実行とpublish時の両方で確認してください。特に、Key Vault SecretやBicep outputのような値は、文字列として即時評価されるものではなく、実行時やmanifest生成時の解決に依存します。
まず確認すべき変更点
旧APIの利用箇所を検索する
TypeScript AppHostを使っている場合は、まず旧メソッドの利用箇所を検索します。
grep -R "withEnvironmentExpression\|withEnvironmentEndpoint\|withEnvironmentParameter\|withEnvironmentConnectionString\|withEnvironmentFromOutput\|withEnvironmentFromKeyVaultSecret" .
PowerShellなら、次のように確認できます。
Select-String -Path .\**\*.ts -Pattern "withEnvironment(Expression|Endpoint|Parameter|ConnectionString|FromOutput|FromKeyVaultSecret)"
見つかった箇所は、原則として withEnvironment(name, value) に置き換えます。ただし、値を .toString() などで文字列化している箇所があれば注意が必要です。エンドポイントや接続文字列リソースは、Aspireに参照として渡すことで依存関係やmanifest表現を保てる場合があります。安易に文字列化すると、publish時の解決やリソース参照が失われる可能性があります。
生成SDKを再生成する
Aspireのmulti-language AppHostでは、CLIがC# integration assemblyを読み取り、ATS属性をスキャンし、TypeScriptなどのSDKを生成します。ドキュメントでは、TypeScript AppHostにintegrationを追加すると、Aspire CLIがassemblyをロードし、[AspireExport] などをスキャンして、型付きTypeScript SDKを生成すると説明されています。(Aspire)
そのため、パッケージやCLIを更新しただけで安心せず、生成済みSDKも更新してください。
aspire update --self
aspire update
aspire run
Aspire 13.3のmigration手順でも、CLI更新には aspire update --self、プロジェクト更新にはリポジトリルートで aspire update を実行する流れが示されています。(GitHub)
.modules/ の型定義を確認する
aspire run 後、TypeScript AppHostなら .modules/ 配下の生成SDKを確認します。見るべきポイントは次の3つです。
| 確認項目 | 期待する状態 |
|---|---|
withEnvironment の引数 | 複数の値型を受け取れるunion型になっている |
旧 withEnvironment* | 残っていても非推奨扱い、または利用不可なら置換済み |
| カスタムintegrationの型 | EndpointReference、ParameterResource、IExpressionValue などが期待どおり表現される |
PR #15649では、TypeScript、Java、Python、Go、Rustの生成ATS artifactsやスナップショットが更新対象に含まれていました。つまり、影響はTypeScriptだけに限定されません。(GitHub)
カスタムintegration開発者が見るべきポイント
Aspire Hosting integrationを作っている場合は、アプリ利用者よりも確認範囲が広くなります。特に、環境変数を設定する拡張メソッドや、callback context、ATS union型を公開している場合は注意してください。
[AspireUnion] に IExpressionValue を含めるべきか確認する
ドキュメントのmulti-language integration guideでは、withEnvironment のunion型例に、string、ReferenceExpression、EndpointReference、IResourceBuilder<ParameterResource>、IResourceBuilder<IResourceWithConnectionString>、IExpressionValue が含まれています。(GitHub)
カスタムintegrationで環境変数エディターや独自の withEnvironment 相当APIを公開している場合は、次の観点で確認します。
| 確認観点 | 判断基準 |
|---|---|
| 単なる文字列だけで十分か | 固定値だけなら string で足りる |
| エンドポイントやパラメーターを受け取るか | EndpointReference や ParameterResource 系をunionに含める |
| 接続文字列リソースを受け取るか | IResourceWithConnectionString 系のbuilderを扱えるようにする |
| runtime valueとmanifest expressionの両方が必要か | IExpressionValue の対象になる |
| TypeScriptなどの生成SDKに出したいか | ATS-compatibleな型だけを使う |
たとえば、独自のデータベースintegrationで「接続URI」「JDBC文字列」「Secret参照」を環境変数に渡したい場合、単なる string では不十分です。manifest生成時に正しく表現できる値として扱えるよう、ReferenceExpression や IExpressionValue の利用を検討する必要があります。
capability IDの重複もあわせて確認する
今回のドキュメント更新対象ファイルでは、multi-language integration authoringの説明も更新され、Aspire 13.3では同一assembly内のduplicate capability IDを検出する ASPIREEXPORT013 にも触れています。(GitHub)
これは withEnvironment そのものとは別の話に見えますが、実務では関連します。旧APIを整理するタイミングで、同じexport IDを複数の拡張メソッドに付けていると、生成SDK側で衝突する可能性があります。
避けるべき例は、異なるC#型向けのメソッドに同じ [AspireExport("configure")] を付けるようなケースです。C#ではオーバーロードやreceiver typeで区別できても、polyglot SDKではcapability IDが衝突することがあります。
移行時に失敗しやすいポイント
値を文字列化してしまう
もっともありがちな失敗は、エラーを避けるために値を String(...) や .toString() で文字列化してしまうことです。
// 避けたい例
await api.withEnvironment('CACHE_URL', String(cache.primaryEndpoint));
このように書くと、一見コンパイルは通っても、Aspireが本来保持できるリソース参照やmanifest expressionの情報を失う可能性があります。エンドポイント、パラメーター、接続文字列リソース、Key Vault Secretなどは、できるだけ値オブジェクトのまま withEnvironment に渡すのが安全です。
ローカル実行だけで確認してしまう
aspire run で動いても、aspire publish やデプロイ時に同じように解決されるとは限りません。IExpressionValue はruntime valueとmanifest expressionの両方に関わるため、次の2つを分けて確認してください。
| 確認シーン | 見るべきポイント |
|---|---|
| ローカル実行 | 環境変数が期待どおりアプリに注入されるか |
| publishまたはmanifest確認 | 参照や式が文字列に潰れず、デプロイ先で解決可能な形になっているか |
特にAzure系リソース、Bicep output、Key Vault Secretを扱うAppHostでは、ローカルだけで判断しないほうが安全です。
非推奨APIが残っているからといって放置する
PR #15649では、既存のpolyglot appを壊さないため、旧 withEnvironment* aliasをobsoleteな互換shimとして残す方針が説明されています。(GitHub)
一方で、13.3の変更履歴には、後続の変更としてobsolete shim methodsの削除も記載されています。利用しているCLIや生成SDKの時点によって旧メソッドが残っているかは変わり得るため、「まだ動くから使い続ける」ではなく、早めに統一APIへ移行するのが現実的です。(GitHub)
実務での移行チェックリスト
移行作業は、次の順番で進めると手戻りを減らせます。
| 手順 | 作業 | 完了条件 |
| -: | ———————————- | ——————————————– |
| 1 | Aspire CLIとプロジェクトを13.3系へ更新 | aspire update --self と aspire update が完了 |
| 2 | 旧 withEnvironment* を検索 | 旧ヘルパーの利用箇所を一覧化 |
| 3 | withEnvironment(name, value) へ置換 | 値を文字列化せず、参照オブジェクトのまま渡す |
| 4 | aspire run でSDKを再生成 | .modules/ に新しい型定義が反映される |
| 5 | アプリ起動時の環境変数を確認 | 期待する環境変数名と値が注入される |
| 6 | publishまたはmanifest確認 | 接続文字列、Secret、出力値が適切な表現で残る |
| 7 | CI/CDのキャッシュを見直す | 古い生成SDKやAppHost成果物を使い回していない |
AppHostの環境変数は、アプリの起動可否だけでなく、接続先、Secret、エンドポイント、デプロイ時のmanifestに直結します。置換作業は小さく見えますが、レビューでは「値の型を保って渡しているか」を必ず確認してください。
どう判断すればよいか
今回のMicrosoft developer platform documentation updateは、API名の整理だけではなく、Aspireがmulti-language AppHostsをより本格的に扱うための土台作りと見るべきです。
TypeScript AppHostを使っているなら、旧 withEnvironment* を見つけた時点で統一APIへ置き換えるのが基本です。Python、Java、Go、Rustなどを含むpolyglot AppHostを評価している場合も、生成SDKの命名規則に沿った同等APIがどう出力されるかを確認してください。
カスタムintegration開発者は、IExpressionValue を単なる新しい型として見るのではなく、「runtime valueとmanifest expressionの両方を必要とする値を、polyglot AppHostから安全に扱うための共通口」として捉えると判断しやすくなります。
まずは旧メソッドの検索、CLIとプロジェクトの更新、生成SDKの再確認から始めてください。そのうえで、ローカル実行とpublish時の両方で環境変数が意図どおり解決されるかを確認すれば、Aspire 13.3のwithEnvironment統一APIへ安全に移行できます。

コメント