ASP.NET Core MVC + React + Web API の通信構成まとめ(View内Reactコンポーネント構成)
概要
ASP.NET Core を利用したフロントエンド開発では、一般的に次のような SPA 構成が紹介されることが多いです。
React (SPA)
↓
ASP.NET Core Web API
しかし既存の ASP.NET Core MVC アプリケーションでは、次のように Razor View を起点にしつつ UI の一部を React に置き換える構成を採用することも多くあります。
ASP.NET Core MVC
↓
Razor View
↓
React Component
↓
Web API
この構成では役割分担が明確になります。
- MVC が画面(View)を提供
- React が UI コンポーネント
- Web API がデータ提供
構成(本記事で扱う2つのパターン)
ASP.NET Core MVC に React を組み込む場合、実運用では 次の2つの構成を使い分けることが多いです。
構成① 本番構成(Production)
React を Razor View 内のコンポーネントとして使用し、ビルド済み JavaScript を MVC の wwwroot から配信する構成です。
(React も MVC と同じホストから配信される)
構成② 開発構成(Development)
開発時は React の Vite Dev Server(HMR) を使用することが多く、React と ASP.NET Core API が 別オリジンになります。
構成①(本番構成 / wwwroot 配信)
- React を View 内に埋め込む場合、React の ビルド成果物(JS/CSS)を MVC の
wwwrootから配信します。 - その結果、ブラウザから見ると React も API も同一オリジンになります。
そのため React 側は相対パスで API を呼べます。
fetch('/api/TodoItems')
例(実際のリクエストのイメージ)
- 画面:
https://localhost:7106/Home/Index - API:
https://localhost:7106/api/TodoItems
✅ 同一オリジンなので CORS 設定は不要です。
React → ASP.NET Core API 通信コード
React
const fetchTodos = async () => {
const response = await fetch('/api/TodoItems')
if (!response.ok) {
throw new Error(`API Error: ${response.status}`)
}
const data = await response.json()
setTodos(data)
}
ASP.NET Core Controller
[ApiController]
[Route("api/[controller]")]
public class TodoItemsController : ControllerBase
{
[HttpGet]
public ActionResult<IEnumerable<TodoItem>> GetTodoItems()
{
return Ok(_todoItems);
}
}
構成②(開発構成 / Vite Dev Server)
開発時に Vite Dev Server(HMR) を使用する場合、例えば以下のように 別オリジンになります。
- React:
http://localhost:5173 - API :
https://localhost:7106
この状態で fetch('/api/TodoItems') を呼ぶと、ブラウザ的には
http://localhost:5173/api/TodoItems
に向かうため、そのままでは API に届きません。
そこで次のいずれかの対応が必要です。
方法① Vite Proxy を利用する(推奨)
vite.config.ts
export default {
server: {
proxy: {
"/api": {
target: "https://localhost:7106",
changeOrigin: true,
secure: false
}
}
}
}
React
fetch('/api/TodoItems')
通信イメージ
React (5173) → Vite Proxy → ASP.NET Core API (7106)
方法② CORS を許可する
Program.cs(※ UseRouting() の後、MapControllers() の前で UseCors() を呼ぶ)
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowVite",
policy => policy
.WithOrigins("http://localhost:5173")
.AllowAnyHeader()
.AllowAnyMethod());
});
app.UseRouting();
app.UseCors("AllowVite");
app.MapControllers();
React
fetch("https://localhost:7106/api/TodoItems")
通信の流れ(本番構成の例)
まとめ
| 構成 | React 配信 | オリジン | API呼び出し | CORS |
|---|---|---|---|---|
| 構成① 本番(wwwroot) | MVC wwwroot
|
同一 | fetch('/api/...') |
不要 |
| 構成② 開発(Vite) | Vite Dev Server | 別 | Proxy or 絶対URL | 必要(Proxy or CORS) |
この方法は次のようなケースに適しています。
- 既存 MVC アプリに React を段階導入したい
- UI の一部だけ React 化したい
- SPA に全面移行せずに API 化を進めたい