{"id":5751,"date":"2026-10-05T00:03:20","date_gmt":"2026-10-04T15:03:20","guid":{"rendered":"https:\/\/blog.id774.net\/entry\/?p=5751"},"modified":"2026-10-04T12:20:49","modified_gmt":"2026-10-04T03:20:49","slug":"%e5%8f%82%e7%85%a7%e5%ae%9f%e8%a3%85%e3%81%af%e8%a8%ad%e8%a8%88%e5%88%a4%e6%96%ad%e3%82%92%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b","status":"publish","type":"post","link":"https:\/\/blog.id774.net\/entry\/2026\/10\/05\/5751\/","title":{"rendered":"\u53c2\u7167\u5b9f\u88c5\u306f\u8a2d\u8a08\u5224\u65ad\u3092\u4fdd\u5b58\u3059\u308b"},"content":{"rendered":"<p>SPA \u3092\u4e00\u3064\u52d5\u304b\u3059\u3068\u3053\u308d\u307e\u3067\u306a\u3089\u3001React \u3067\u753b\u9762\u3092\u4f5c\u308a\u3001HTTP API \u3092\u7528\u610f\u3057\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u63a5\u7d9a\u3059\u308c\u3070\u5f62\u306b\u306a\u308b\u3002\u3057\u304b\u3057\u3001\u696d\u52d9\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u3057\u3066\u7d99\u7d9a\u5229\u7528\u3067\u304d\u308b\u72b6\u614b\u307e\u3067\u9032\u3081\u308b\u3068\u3001\u753b\u9762\u3068 API \u306e\u5916\u5074\u306b\u5225\u306e\u8a2d\u8a08\u554f\u984c\u304c\u73fe\u308c\u308b\u3002\u5229\u7528\u8005\u3092\u8b58\u5225\u3059\u308b\u8a8d\u8a3c\u3001\u64cd\u4f5c\u53ef\u80fd\u7bc4\u56f2\u3092\u6c7a\u3081\u308b\u8a8d\u53ef\u3001\u8907\u6570\u66f4\u65b0\u3092\u4e00\u3064\u306e\u696d\u52d9\u64cd\u4f5c\u3068\u3057\u3066\u78ba\u5b9a\u3059\u308b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3001\u5f8c\u304b\u3089\u64cd\u4f5c\u4e8b\u5b9f\u3092\u8ffd\u8de1\u3059\u308b\u76e3\u67fb\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u306e\u4fdd\u5b58\u3001\u30e1\u30fc\u30eb\u3084\u30a4\u30d9\u30f3\u30c8\u306e\u914d\u9001\u3001\u69cb\u6210\u7ba1\u7406\u3001\u30c6\u30b9\u30c8\u3001\u7d99\u7d9a\u7684\u30a4\u30f3\u30c6\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u30c7\u30d7\u30ed\u30a4\u3067\u3042\u308b\u3002spa-reference \u306f\u3001\u3053\u308c\u3089\u3092\u4e00\u3064\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u5fc3\u306e\u696d\u52d9 SPA \u306e\u4e2d\u3067\u6574\u5408\u3059\u308b\u3088\u3046\u306b\u7d44\u307f\u5408\u308f\u305b\u3001\u8a2d\u8a08\u5224\u65ad\u307e\u3067\u8ffd\u8de1\u3067\u304d\u308b\u5f62\u3067\u516c\u958b\u3057\u305f\u53c2\u7167\u5b9f\u88c5\u3067\u3042\u308b<a href=\"#ref1\">[1]<\/a>\u3002<\/p>\n<p>\u540c\u3058 React \u3068 NestJS \u3092\u4f7f\u3063\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3082\u3001\u3053\u306e\u6a2a\u65ad\u7684\u306a\u8cac\u52d9\u306e\u7f6e\u304d\u65b9\u306b\u3088\u3063\u3066\u30b7\u30b9\u30c6\u30e0\u306e\u6027\u8cea\u306f\u5909\u308f\u308b\u3002\u8a8d\u53ef\u3092\u30d6\u30e9\u30a6\u30b6\u5074\u306e\u8868\u793a\u5236\u5fa1\u3060\u3051\u306b\u7f6e\u3051\u3070\u3001HTTP API \u3092\u76f4\u63a5\u547c\u3076\u7d4c\u8def\u3092\u9632\u3052\u306a\u3044\u3002\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u66f4\u65b0\u306e\u76f4\u5f8c\u306b\u30e1\u30fc\u30eb\u3092\u540c\u671f\u9001\u4fe1\u3059\u308c\u3070\u3001\u4fdd\u5b58\u3060\u3051\u6210\u529f\u3057\u3066\u901a\u77e5\u304c\u5931\u6557\u3059\u308b\u72b6\u614b\u3092\u8003\u3048\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002HTTP \u306e\u5165\u529b\u3068\u30a8\u30e9\u30fc\u3092\u5b9f\u88c5\u30b3\u30fc\u30c9\u3060\u3051\u3067\u5b9a\u7fa9\u3059\u308c\u3070\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u5909\u66f4\u6642\u306b\u3001\u3069\u3061\u3089\u304c\u5951\u7d04\u306e\u6b63\u672c\u306a\u306e\u304b\u304c\u66d6\u6627\u306b\u306a\u308b\u3002\u500b\u3005\u306e\u6280\u8853\u306f\u540c\u3058\u3067\u3082\u3001\u8cac\u52d9\u5883\u754c\u3068\u5931\u6557\u6642\u306e\u610f\u5473\u304c\u9055\u3048\u3070\u3001\u3067\u304d\u3042\u304c\u308b\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306f\u5225\u7269\u306b\u306a\u308b\u3002<\/p>\n<p>\u53c2\u7167\u5b9f\u88c5\u306e\u4fa1\u5024\u306f\u3001\u8981\u4ef6\u304b\u3089\u8a2d\u8a08\u3001\u5b9f\u88c5\u3001\u691c\u8a3c\u307e\u3067\u306e\u5224\u65ad\u3092\u8ffd\u8de1\u3067\u304d\u308b\u3053\u3068\u306b\u3042\u308b\u3002\u7b2c\u4e00\u306b\u3001\u5bfe\u8c61\u3068\u3059\u308b\u8981\u4ef6\u3092\u5b9a\u3081\u308b\u3002\u7b2c\u4e8c\u306b\u3001\u305d\u306e\u8981\u4ef6\u304b\u3089\u8cac\u52d9\u5883\u754c\u3001\u5951\u7d04\u3001\u4e00\u8cab\u6027\u306e\u7bc4\u56f2\u3092\u5c0e\u304f\u3002\u7b2c\u4e09\u306b\u3001\u305d\u306e\u69cb\u9020\u3092\u5177\u4f53\u7684\u306a\u6280\u8853\u3078\u5199\u3057\u3001\u5b9f\u88c5\u3001\u6587\u66f8\u3001\u30c6\u30b9\u30c8\u3001CI \u3067\u540c\u3058\u5224\u65ad\u3092\u7dad\u6301\u3059\u308b\u3002spa-reference \u3092\u5b9f\u88c5\u3060\u3051\u304b\u3089\u898b\u308b\u3068\u3001React\u3001NestJS\u3001PostgreSQL\u3001AWS \u3092\u4f7f\u3063\u305f\u4e00\u3064\u306e Web \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u898b\u3048\u308b\u3002\u8981\u4ef6\u3001\u57fa\u672c\u8a2d\u8a08\u3001\u8a73\u7d30\u8a2d\u8a08\u3001\u30dd\u30ea\u30b7\u30fc\u3001OpenAPI\u3001\u30c6\u30b9\u30c8\u3001CI \u307e\u3067\u3092\u4e00\u7d9a\u304d\u306e\u5224\u65ad\u4f53\u7cfb\u3068\u3057\u3066\u8aad\u3080\u3068\u3001\u6280\u8853\u540d\u306e\u80cc\u5f8c\u306b\u3042\u308b\u300c\u306a\u305c\u3053\u306e\u5883\u754c\u306a\u306e\u304b\u300d\u300c\u3069\u3053\u307e\u3067\u3092\u4fdd\u8a3c\u3059\u308b\u306e\u304b\u300d\u3068\u3044\u3046\u8a2d\u8a08\u601d\u60f3\u304c\u898b\u3048\u3066\u304f\u308b\u3002<\/p>\n<hr>\n<h2>1. \u53c2\u7167\u5b9f\u88c5\u306f\u5224\u65ad\u3092\u4fdd\u5b58\u3059\u308b<\/h2>\n<p>spa-reference \u306e\u8981\u4ef6\u5b9a\u7fa9\u3067\u306f\u3001reference \u3068\u3044\u3046\u8a9e\u3092\u610f\u56f3\u7684\u306b\u4f7f\u3063\u3066\u3044\u308b\u3002\u76ee\u7684\u306f\u3001\u65e2\u5b58\u306e\u6280\u8853\u3068\u6a2a\u65ad\u7684\u306a\u8cac\u52d9\u3092\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u5fc3\u306e\u696d\u52d9 SPA \u3068\u3044\u3046\u5177\u4f53\u7684\u306a\u6761\u4ef6\u306e\u4e0b\u3067\u3069\u3046\u7d44\u307f\u5408\u308f\u305b\u308b\u304b\u3092\u793a\u3059\u3053\u3068\u306b\u3042\u308b\u3002\u3053\u306e\u69cb\u6210\u306f\u3001\u6761\u4ef6\u304c\u4e00\u81f4\u3059\u308b\u3068\u304d\u306b\u6bd4\u8f03\u3068\u63a1\u7528\u306e\u57fa\u6e96\u3068\u3057\u3066\u4f7f\u3048\u308b\u53c2\u7167\u5b9f\u88c5\u3068\u3057\u3066\u4f4d\u7f6e\u4ed8\u3051\u3066\u3044\u308b<a href=\"#ref2\">[2]<\/a>\u3002<\/p>\n<p>\u3053\u306e\u4f4d\u7f6e\u4ed8\u3051\u306b\u3088\u3063\u3066\u3001\u53c2\u7167\u5bfe\u8c61\u306f\u30b3\u30fc\u30c9\u305d\u306e\u3082\u306e\u304b\u3089\u8a2d\u8a08\u5224\u65ad\u3078\u5e83\u304c\u308b\u3002\u305f\u3068\u3048\u3070\u73fe\u5728\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u5358\u4f4d\u3067\u3042\u308b\u3068\u3044\u3046\u5b9f\u88c5\u4e8b\u5b9f\u306b\u306f\u3001\u8981\u4ef6\u3068\u57fa\u672c\u8a2d\u8a08\u306b\u8a18\u9332\u3055\u308c\u305f\u7406\u7531\u304c\u5bfe\u5fdc\u3059\u308b\u3002\u5358\u306b\u5b9f\u88c5\u304c\u5c0f\u3055\u3044\u305f\u3081\u4e00\u3064\u306b\u307e\u3068\u307e\u308b\u5834\u5408\u3082\u3042\u308c\u3070\u3001\u5c06\u6765\u5206\u5272\u3059\u308b\u305f\u3081\u306e\u5883\u754c\u3092\u8a2d\u3051\u305f\u4e0a\u3067\u610f\u56f3\u7684\u306b\u4e00\u3064\u3078\u4fdd\u3064\u5834\u5408\u3082\u3042\u308b\u3002\u8981\u4ef6\u3068\u57fa\u672c\u8a2d\u8a08\u306b\u300c\u73fe\u5728\u306f\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u3068\u3057\u3001\u5c06\u6765\u5206\u96e2\u53ef\u80fd\u306a\u6a5f\u80fd\u5883\u754c\u3092\u4fdd\u6301\u3059\u308b\u300d\u3068\u8a18\u9332\u3059\u308b\u3053\u3068\u3067\u3001\u73fe\u5728\u306e\u69cb\u9020\u3092\u610f\u56f3\u3055\u308c\u305f\u8a2d\u8a08\u5224\u65ad\u3068\u3057\u3066\u518d\u73fe\u3067\u304d\u308b\u3002<\/p>\n<p>\u540c\u3058\u3053\u3068\u306f API \u306b\u3082\u5f53\u3066\u306f\u307e\u308b\u3002\u3042\u308b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u304c 409 \u3092\u8fd4\u3059\u3068\u304d\u3001\u305d\u308c\u3092\u516c\u958b\u5951\u7d04\u3068\u3057\u3066\u7dad\u6301\u3059\u308b\u6839\u62e0\u306f OpenAPI \u3068\u8a73\u7d30\u8a2d\u8a08\u306b\u7f6e\u304f\u3002OpenAPI \u306b 409 \u3068\u6a5f\u68b0\u53ef\u8aad\u306a\u30a8\u30e9\u30fc\u30b3\u30fc\u30c9\u3092\u5b9a\u7fa9\u3057\u3001\u8a73\u7d30\u8a2d\u8a08\u306b\u30d0\u30fc\u30b8\u30e7\u30f3\u7af6\u5408\u3068\u72b6\u614b\u691c\u8a3c\u306e\u8a55\u4fa1\u9806\u5e8f\u307e\u3067\u8a18\u9332\u3059\u308c\u3070\u3001\u5229\u7528\u8005\u304b\u3089\u89b3\u6e2c\u3055\u308c\u308b\u632f\u308b\u821e\u3044\u3068\u3057\u3066\u56fa\u5b9a\u3067\u304d\u308b\u3002\u516c\u958b\u5951\u7d04\u3068\u3057\u3066\u7dad\u6301\u3059\u308b\u632f\u308b\u821e\u3044\u3092\u5225\u306e\u6b63\u672c\u3067\u660e\u793a\u3059\u308b\u3053\u3068\u3067\u3001\u5b9f\u88c5\u3068\u4ed5\u69d8\u306e\u95a2\u4fc2\u3092\u8ffd\u8de1\u3067\u304d\u308b\u3002<\/p>\n<p>\u3053\u306e\u7acb\u5834\u306f\u3001Martin Fowler \u304c best practice \u306e\u4ee3\u308f\u308a\u306b\u8ff0\u3079\u308b Sensible Default \u3068\u8fd1\u3044\u3002Sensible Default \u306f\u3001\u8ffd\u52a0\u306e\u4e8b\u60c5\u304c\u306a\u3051\u308c\u3070\u63a1\u7528\u3067\u304d\u308b\u65e2\u77e5\u306e\u51fa\u767a\u70b9\u3067\u3042\u308a\u3001\u6761\u4ef6\u304c\u5909\u308f\u308c\u3070\u518d\u8a55\u4fa1\u3055\u308c\u308b\u3002\u3042\u3089\u3086\u308b\u72b6\u6cc1\u306b\u5bfe\u3059\u308b\u6700\u9069\u89e3\u3092\u5ba3\u8a00\u3059\u308b\u3088\u308a\u3001\u300c\u3053\u306e\u5236\u7d04\u96c6\u5408\u3067\u306f\u3001\u3053\u306e\u69cb\u6210\u3092\u51fa\u767a\u70b9\u306b\u3067\u304d\u308b\u300d\u3068\u793a\u3059\u8003\u3048\u65b9\u3067\u3042\u308b<a href=\"#ref3\">[3]<\/a>\u3002spa-reference \u306e reference \u3082\u540c\u69d8\u306b\u3001\u6280\u8853\u9078\u629e\u3092\u7d76\u5bfe\u5316\u3059\u308b\u3088\u308a\u3001\u9078\u629e\u304c\u6210\u7acb\u3059\u308b\u6761\u4ef6\u3092\u53ef\u8996\u5316\u3059\u308b\u3053\u3068\u306b\u91cd\u70b9\u3092\u7f6e\u3044\u3066\u3044\u308b\u3002<\/p>\n<p>\u53c2\u7167\u5b9f\u88c5\u306b\u306f\u3001\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u306b\u52a0\u3048\u3066\u4e0a\u4f4d\u5224\u65ad\u3092\u4fdd\u6301\u3059\u308b\u6b63\u672c\u304c\u5fc5\u8981\u3067\u3042\u308b\u3002\u30b3\u30fc\u30c9\u306f\u300c\u73fe\u5728\u3069\u3046\u52d5\u304f\u304b\u300d\u3092\u6700\u3082\u76f4\u63a5\u7684\u306b\u793a\u3057\u3001REQUIREMENTS\u3001BASIC_DESIGN\u3001DETAILED_DESIGN\u3001POLICY\u3001OpenAPI \u306f\u300c\u306a\u305c\u305d\u306e\u69cb\u9020\u3092\u7dad\u6301\u3059\u308b\u306e\u304b\u300d\u300c\u5909\u66f4\u6642\u306b\u3069\u306e\u5224\u65ad\u3092\u57fa\u6e96\u306b\u3059\u308b\u306e\u304b\u300d\u3092\u4fdd\u6301\u3059\u308b\u3002\u305d\u308c\u305e\u308c\u304c\u7570\u306a\u308b\u7a2e\u985e\u306e\u5909\u66f4\u7406\u7531\u3092\u53d7\u3051\u6301\u3064\u3053\u3068\u3067\u3001\u8981\u4ef6\u3001\u8a2d\u8a08\u3001\u5b9f\u88c5\u898f\u5247\u3001\u901a\u4fe1\u4ed5\u69d8\u306e\u8cac\u52d9\u3092\u5206\u3051\u3066\u7ba1\u7406\u3067\u304d\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6b63\u672c<\/th>\n<th>\u4fdd\u6301\u3059\u308b\u5224\u65ad<\/th>\n<th>\u5206\u96e2\u3059\u308b\u7406\u7531<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>REQUIREMENTS<\/td>\n<td>\u5bfe\u8c61\u3068\u3059\u308b\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3001\u5fc5\u8981\u80fd\u529b\u3001\u73fe\u5728\u5bfe\u5fdc\u3059\u308b\u7bc4\u56f2\u3001\u5c06\u6765\u69cb\u60f3\u3068\u306e\u5883\u754c\u3092\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>\u5b9f\u88c5\u65b9\u5f0f\u304c\u5909\u308f\u3063\u3066\u3082\u3001\u4f55\u3092\u6e80\u305f\u3059\u305f\u3081\u306e\u30b7\u30b9\u30c6\u30e0\u306a\u306e\u304b\u3068\u3044\u3046\u8981\u6c42\u3092\u72ec\u7acb\u3057\u3066\u5224\u5b9a\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>BASIC_DESIGN<\/td>\n<td>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u8cac\u52d9\u3001\u4f9d\u5b58\u65b9\u5411\u3001\u914d\u7f6e\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5883\u754c\u3001\u5c06\u6765\u5206\u96e2\u53ef\u80fd\u306a\u5883\u754c\u3092\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>\u500b\u3005\u306e\u30af\u30e9\u30b9\u3084 file \u306e\u5f62\u3088\u308a\u9577\u304f\u7dad\u6301\u3059\u308b\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u4e0a\u306e\u95a2\u4fc2\u3092\u3001\u5b9f\u88c5\u8a73\u7d30\u304b\u3089\u5206\u96e2\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>DETAILED_DESIGN<\/td>\n<td>\u8a8d\u8a3c\u3001\u8a8d\u53ef\u3001\u7af6\u5408\u3001\u5931\u6557\u6642\u51e6\u7406\u3001\u56de\u5fa9\u3001\u5916\u90e8\u526f\u4f5c\u7528\u306a\u3069\u3001\u5b9f\u88c5\u7d50\u679c\u3092\u5909\u3048\u308b\u610f\u5473\u8ad6\u3092\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>\u540c\u3058\u57fa\u672c\u69cb\u9020\u3067\u3082\u5b9f\u88c5\u8005\u306b\u3088\u3063\u3066\u7d50\u679c\u304c\u5909\u308f\u308a\u5f97\u308b\u51e6\u7406\u9806\u5e8f\u3084\u5931\u6557\u6761\u4ef6\u3092\u56fa\u5b9a\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>POLICY<\/td>\n<td>\u5909\u66f4\u6642\u306b\u4f55\u3092\u512a\u5148\u3057\u3001\u3069\u306e\u8907\u96d1\u6027\u3092\u5897\u3084\u3055\u305a\u3001\u3069\u3053\u307e\u3067\u691c\u8a3c\u3059\u308b\u304b\u3068\u3044\u3046\u4fdd\u5b88\u5224\u65ad\u3092\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>\u500b\u5225\u5909\u66f4\u306e\u305f\u3073\u306b\u5224\u65ad\u57fa\u6e96\u3092\u4f5c\u308a\u76f4\u3055\u305a\u3001\u5c06\u6765\u306e\u5909\u66f4\u3067\u3082\u540c\u3058\u8a2d\u8a08\u539f\u5247\u3092\u9069\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>OpenAPI<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6\u304b\u3089\u89b3\u6e2c\u3067\u304d\u308b HTTP \u306e\u30d1\u30b9\u3001\u5165\u529b\u3001\u51fa\u529b\u3001\u30a8\u30e9\u30fc\u3001\u8a8d\u8a3c\u65b9\u5f0f\u3092\u6a5f\u68b0\u53ef\u8aad\u306a\u5951\u7d04\u3068\u3057\u3066\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>React\u3001NestJS\u3001TypeScript \u306a\u3069\u306e\u5b9f\u88c5\u65b9\u5f0f\u304b\u3089\u901a\u4fe1\u5951\u7d04\u3092\u5207\u308a\u96e2\u3057\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3068\u691c\u8a3c\u51e6\u7406\u306e\u5171\u901a\u5165\u529b\u306b\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u6b63\u672c\u3092\u5206\u5272\u3059\u308b\u3068\u3001\u5909\u66f4\u6642\u306e\u5224\u65ad\u306b\u3082\u56e0\u679c\u95a2\u4fc2\u304c\u751f\u307e\u308c\u308b\u3002\u8981\u6c42\u305d\u306e\u3082\u306e\u304c\u5909\u308f\u3063\u305f\u5834\u5408\u306f REQUIREMENTS \u304b\u3089\u8a2d\u8a08\u3068\u5b9f\u88c5\u3078\u5909\u66f4\u304c\u6ce2\u53ca\u3059\u308b\u3002HTTP \u306e\u516c\u958b\u4ed5\u69d8\u3060\u3051\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u306f OpenAPI \u3068\u3001\u305d\u306e\u5951\u7d04\u3092\u5b9f\u73fe\u3059\u308b\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u30c6\u30b9\u30c8\u304c\u5bfe\u8c61\u306b\u306a\u308b\u3002\u5b9f\u88c5\u5185\u90e8\u3092\u6574\u7406\u3057\u3066\u3082\u516c\u958b\u5951\u7d04\u3068\u8981\u6c42\u304c\u5909\u308f\u3089\u306a\u3051\u308c\u3070\u3001\u305d\u308c\u3089\u306e\u6b63\u672c\u307e\u3067\u6a5f\u68b0\u7684\u306b\u66f8\u304d\u63db\u3048\u308b\u5fc5\u8981\u306f\u306a\u3044\u3002\u5909\u66f4\u7406\u7531\u3054\u3068\u306b\u6b63\u672c\u3092\u5206\u3051\u308b\u3053\u3068\u3067\u3001\u5909\u66f4\u7bc4\u56f2\u3082\u5236\u5fa1\u3067\u304d\u308b\u3002<\/p>\n<p>\u3053\u308c\u306f template \u3068\u306e\u9055\u3044\u306b\u3082\u3064\u306a\u304c\u308b\u3002template \u306e\u4e2d\u5fc3\u7684\u306a\u4fa1\u5024\u306f\u3001\u8907\u88fd\u3057\u3066\u958b\u767a\u3092\u958b\u59cb\u3067\u304d\u308b\u521d\u671f\u72b6\u614b\u306b\u3042\u308b\u3002\u53c2\u7167\u5b9f\u88c5\u306f\u3001\u5b8c\u6210\u3057\u305f\u69cb\u9020\u3092\u89b3\u5bdf\u3057\u3001\u63a1\u7528\u6761\u4ef6\u3068\u8a2d\u8a08\u7406\u7531\u3092\u6bd4\u8f03\u3059\u308b\u305f\u3081\u306b\u3082\u4f7f\u308f\u308c\u308b\u3002spa-reference \u306e\u8981\u4ef6\u3067\u306f\u3001\u518d\u5229\u7528\u3059\u308b\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3084\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u8981\u7d20\u3068\u3001\u63a1\u7528\u5148\u3067\u5909\u66f4\u3055\u308c\u308b template \u3084 boilerplate \u306e\u8981\u7d20\u3092\u533a\u5225\u3059\u308b\u3053\u3068\u307e\u3067\u5b9a\u3081\u3066\u3044\u308b<a href=\"#ref2\">[2]<\/a>\u3002\u53c2\u7167\u5143\u3068\u540c\u3058\u69cb\u9020\u3092\u6c38\u4e45\u306b\u7dad\u6301\u3055\u305b\u308b\u3053\u3068\u3088\u308a\u3001\u3069\u306e\u90e8\u5206\u304c\u5171\u901a\u539f\u5247\u3067\u3001\u3069\u306e\u90e8\u5206\u304c\u6848\u4ef6\u56fa\u6709\u306b\u5909\u5316\u3057\u3066\u3088\u3044\u304b\u3092\u8b58\u5225\u3067\u304d\u308b\u3053\u3068\u3092\u512a\u5148\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u7d50\u679c\u3068\u3057\u3066\u3001spa-reference \u304c\u4fdd\u5b58\u3057\u3066\u3044\u308b\u306e\u306f\u300cReact \u3068 NestJS \u3067\u3053\u3046\u66f8\u3044\u305f\u300d\u3068\u3044\u3046\u5b9f\u88c5\u4f8b\u3060\u3051\u3067\u306f\u306a\u3044\u3002\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u5fc3\u306e\u696d\u52d9 SPA \u3068\u3044\u3046\u6761\u4ef6\u3092\u7f6e\u304d\u3001\u305d\u306e\u6761\u4ef6\u304b\u3089\u8cac\u52d9\u3001\u4e00\u8cab\u6027\u3001\u516c\u958b\u5951\u7d04\u3001\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u3068\u306e\u5883\u754c\u3092\u6c7a\u3081\u3001\u5177\u4f53\u7684\u306a\u6280\u8853\u3078\u843d\u3068\u3057\u3001\u305d\u306e\u5bfe\u5fdc\u3092\u6587\u66f8\u3068\u691c\u8a3c\u7cfb\u3067\u7dad\u6301\u3059\u308b\u3068\u3044\u3046\u5224\u65ad\u7d4c\u8def\u305d\u306e\u3082\u306e\u3092\u4fdd\u5b58\u3057\u3066\u3044\u308b\u3002\u5225\u306e\u6848\u4ef6\u3067 React \u3084 AWS \u3092\u63a1\u7528\u3057\u306a\u304f\u3066\u3082\u3001\u3069\u306e\u6761\u4ef6\u3092\u78ba\u8a8d\u3057\u3066\u304b\u3089\u69cb\u9020\u3092\u9078\u3076\u304b\u3068\u3044\u3046\u5224\u65ad\u65b9\u6cd5\u306f\u518d\u5229\u7528\u3067\u304d\u308b\u3002\u53c2\u7167\u5b9f\u88c5\u306e\u5bff\u547d\u3092\u6c7a\u3081\u308b\u306e\u306f\u7279\u5b9a\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u7248\u3088\u308a\u3001\u3053\u306e\u5224\u65ad\u7d4c\u8def\u304c\u8ffd\u8de1\u53ef\u80fd\u306a\u72b6\u614b\u3067\u6b8b\u3063\u3066\u3044\u308b\u304b\u3069\u3046\u304b\u3067\u3042\u308b\u3002<\/p>\n<hr>\n<h2>2. \u8981\u4ef6\u306f\u9069\u7528\u7bc4\u56f2\u3092\u72ed\u3081\u3066\u8a2d\u8a08\u5224\u65ad\u3092\u53ef\u80fd\u306b\u3059\u308b<\/h2>\n<p>spa-reference \u304c\u5bfe\u8c61\u3068\u3059\u308b\u306e\u306f\u3001\u5bfe\u8a71\u7684\u3067\u3001\u8a8d\u8a3c\u3092\u4f34\u3044\u3001\u72b6\u614b\u3092\u66f4\u65b0\u3059\u308b\u696d\u52d9 Web \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3042\u308b\u3002\u5229\u7528\u8005\u304c\u30ed\u30b0\u30a4\u30f3\u3057\u3001\u30d5\u30a9\u30fc\u30e0\u3001\u4e00\u89a7\u3001\u8a73\u7d30\u753b\u9762\u3092\u884c\u304d\u6765\u3057\u306a\u304c\u3089\u3001CRUD\u3001\u696d\u52d9\u72b6\u614b\u9077\u79fb\u3001\u8a8d\u53ef\u3001\u95a2\u4fc2\u30c7\u30fc\u30bf\u306e\u66f4\u65b0\u3092\u7d99\u7d9a\u7684\u306b\u884c\u3046\u7a2e\u985e\u306e\u30b7\u30b9\u30c6\u30e0\u3092\u4e2d\u5fc3\u306b\u7f6e\u3044\u3066\u3044\u308b<a href=\"#ref2\">[2]<\/a>\u3002\u3053\u306e\u9069\u7528\u7bc4\u56f2\u304c\u3001\u5f8c\u7d9a\u3059\u308b\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3068\u6280\u8853\u9078\u5b9a\u306b\u3064\u3044\u3066\u3001\u4f55\u3092\u6bd4\u8f03\u5bfe\u8c61\u306b\u3057\u3001\u3069\u306e\u6027\u8cea\u3092\u512a\u5148\u3057\u3066\u5224\u65ad\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5165\u529b\u6761\u4ef6\u306b\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n<p>\u300cWeb \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u300d\u3068\u3044\u3046\u5206\u985e\u3060\u3051\u3067\u306f\u3001\u8a2d\u8a08\u6761\u4ef6\u304c\u5e83\u3059\u304e\u308b\u3002\u691c\u7d22\u6d41\u5165\u3092\u91cd\u8996\u3059\u308b\u516c\u958b\u30b3\u30f3\u30c6\u30f3\u30c4\u30b5\u30a4\u30c8\u3068\u3001\u8a8d\u8a3c\u5f8c\u306b\u5229\u7528\u8005\u304c\u696d\u52d9\u72b6\u614b\u3092\u66f4\u65b0\u3057\u7d9a\u3051\u308b\u7533\u8acb\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u3001\u540c\u3058\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3082\u512a\u5148\u9806\u4f4d\u304c\u7570\u306a\u308b\u3002\u524d\u8005\u3067\u306f\u521d\u671f\u8868\u793a\u3001\u691c\u7d22\u30a8\u30f3\u30b8\u30f3\u306b\u3088\u308b\u7d22\u5f15\u5316\u3001\u9759\u7684\u914d\u4fe1\u306a\u3069\u304c\u4e3b\u8981\u306a\u5224\u65ad\u6750\u6599\u306b\u306a\u308a\u5f97\u308b\u3002\u5f8c\u8005\u3067\u306f\u3001\u8ab0\u304c\u3069\u306e\u30c7\u30fc\u30bf\u3092\u5909\u66f4\u3067\u304d\u308b\u304b\u3001\u8907\u6570\u306e\u66f4\u65b0\u3092\u3069\u3053\u307e\u3067\u4e00\u4f53\u3068\u3057\u3066\u78ba\u5b9a\u3059\u308b\u304b\u3001\u540c\u6642\u64cd\u4f5c\u304c\u7af6\u5408\u3057\u305f\u3068\u304d\u306b\u4f55\u3092\u8fd4\u3059\u304b\u3001\u5909\u66f4\u5c65\u6b74\u3092\u3069\u306e\u3088\u3046\u306b\u6b8b\u3059\u304b\u3068\u3044\u3046\u554f\u984c\u304c\u4e2d\u5fc3\u306b\u306a\u308b\u3002\u5bfe\u8c61\u3092\u5f8c\u8005\u3078\u9650\u5b9a\u3059\u308b\u3053\u3068\u3067\u3001\u8a2d\u8a08\u4e0a\u6bd4\u8f03\u3059\u3079\u304d\u6027\u8cea\u304c\u5177\u4f53\u5316\u3059\u308b\u3002<\/p>\n<p>\u5177\u4f53\u7684\u306a\u984c\u6750\u306b\u306f\u7533\u8acb\u3068\u627f\u8a8d\u3092\u9078\u3093\u3067\u3044\u308b\u3002Requester \u304c\u7533\u8acb\u3092\u4f5c\u6210\u3057\u3001DRAFT \u304b\u3089 SUBMITTED \u3078\u9032\u3081\u3001Approver \u304c APPROVED \u307e\u305f\u306f REJECTED \u3078\u9077\u79fb\u3055\u305b\u308b\u3002Administrator \u306f\u7533\u8acb\u72b6\u614b\u3068\u76e3\u67fb\u5c65\u6b74\u3092\u78ba\u8a8d\u3059\u308b\u3002\u3053\u306e\u696d\u52d9\u30e2\u30c7\u30eb\u306f\u5c0f\u3055\u3044\u304c\u3001\u5358\u7d14\u306a CRUD \u3088\u308a\u4e00\u6bb5\u591a\u304f\u306e\u8a2d\u8a08\u6761\u4ef6\u3092\u767a\u751f\u3055\u305b\u308b\u3002\u7533\u8acb\u306f\u4fdd\u5b58\u5f8c\u3082\u73fe\u5728\u72b6\u614b\u306b\u3088\u3063\u3066\u8a31\u53ef\u3055\u308c\u308b\u64cd\u4f5c\u304c\u5909\u308f\u308a\u3001\u5b9f\u884c\u4e3b\u4f53\u306b\u3088\u3063\u3066\u6a29\u9650\u304c\u5909\u308f\u308a\u3001\u66f4\u65b0\u7d50\u679c\u306b\u5fdc\u3058\u3066\u76e3\u67fb\u3084\u901a\u77e5\u307e\u3067\u767a\u751f\u3059\u308b\u304b\u3089\u3067\u3042\u308b\u3002<\/p>\n<p>\u305f\u3068\u3048\u3070 SUBMITTED \u306e\u7533\u8acb\u3092 Approver \u304c\u627f\u8a8d\u3059\u308b\u3068\u304d\u3001\u78ba\u8a8d\u3059\u3079\u304d\u5bfe\u8c61\u306f status \u306b\u52a0\u3048\u3066\u8907\u6570\u3042\u308b\u3002\u307e\u305a\u3001\u305d\u306e\u5229\u7528\u8005\u304c\u8a8d\u8a3c\u6e08\u307f\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u6b21\u306b Approver \u3068\u3057\u3066\u64cd\u4f5c\u53ef\u80fd\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u305d\u306e\u3046\u3048\u3067\u5bfe\u8c61\u306e\u7533\u8acb\u304c\u5b58\u5728\u3057\u3001\u5229\u7528\u8005\u306b\u305d\u306e\u64cd\u4f5c\u6a29\u9650\u304c\u3042\u308a\u3001\u30d6\u30e9\u30a6\u30b6\u304c\u53d6\u5f97\u3057\u305f\u5f8c\u306b\u5225\u306e\u5229\u7528\u8005\u304c\u66f4\u65b0\u3057\u3066\u3044\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3001\u73fe\u5728\u72b6\u614b\u304c\u627f\u8a8d\u53ef\u80fd\u3067\u3042\u308b\u3053\u3068\u3092\u5224\u5b9a\u3059\u308b\u3002\u627f\u8a8d\u304c\u6210\u7acb\u3059\u308c\u3070\u3001\u72b6\u614b\u5909\u66f4\u3068\u76e3\u67fb\u8a18\u9332\u306f\u540c\u3058\u696d\u52d9\u7d50\u679c\u3068\u3057\u3066\u77db\u76fe\u306a\u304f\u78ba\u5b9a\u3057\u3001\u305d\u306e\u5f8c\u306b\u901a\u77e5\u3068\u3044\u3046\u5916\u90e8\u526f\u4f5c\u7528\u3092\u51e6\u7406\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u3053\u306e\u4e00\u3064\u306e\u64cd\u4f5c\u3060\u3051\u3067\u3001\u8a8d\u8a3c\u3001\u8a8d\u53ef\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001\u72b6\u614b\u6a5f\u68b0\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3001\u76e3\u67fb\u3001\u5916\u90e8\u914d\u9001\u3068\u3044\u3046\u8907\u6570\u306e\u8cac\u52d9\u304c\u63a5\u7d9a\u3055\u308c\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u8981\u4ef6\u4e0a\u306e\u6027\u8cea<\/th>\n<th>\u8a2d\u8a08\u4e0a\u767a\u751f\u3059\u308b\u554f\u3044<\/th>\n<th>\u5224\u65ad\u3092\u8aa4\u3063\u305f\u5834\u5408\u306b\u8d77\u304d\u308b\u3053\u3068<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u8a8d\u8a3c\u6e08\u307f\u5229\u7528\u8005\u304c\u64cd\u4f5c\u3059\u308b<\/td>\n<td>\u672c\u4eba\u78ba\u8a8d\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e\u6a29\u9650\u3092\u3069\u306e\u5883\u754c\u3067\u78ba\u5b9a\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6\u304c\u7533\u544a\u3057\u305f role \u3084\u672a\u691c\u8a3c\u306e identity \u3092\u4fe1\u7528\u3059\u308b\u3068\u3001\u753b\u9762\u4e0a\u306e\u5236\u5fa1\u3068\u30b5\u30fc\u30d0\u30fc\u5074\u306e\u8a8d\u53ef\u304c\u4e56\u96e2\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u72b6\u614b\u9077\u79fb\u304c\u3042\u308b<\/td>\n<td>\u3069\u306e\u72b6\u614b\u304b\u3089\u3069\u306e\u64cd\u4f5c\u3092\u8a31\u53ef\u3057\u3001\u8907\u6570\u306e\u5931\u6557\u6761\u4ef6\u304c\u540c\u6642\u306b\u6210\u7acb\u3057\u305f\u3068\u304d\u306b\u3069\u306e\u7d50\u679c\u3092\u8fd4\u3059\u304b\u3092\u56fa\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u5b9f\u88c5\u7b87\u6240\u3054\u3068\u306b\u5224\u5b9a\u9806\u5e8f\u304c\u7570\u306a\u308b\u3068\u3001\u540c\u3058\u5165\u529b\u3067\u3082 API \u306e\u5fdc\u7b54\u3084\u696d\u52d9\u7d50\u679c\u304c\u5909\u308f\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u540c\u3058\u30c7\u30fc\u30bf\u3092\u8907\u6570\u5229\u7528\u8005\u304c\u66f4\u65b0\u3059\u308b<\/td>\n<td>\u53d6\u5f97\u5f8c\u306b\u66f4\u65b0\u3055\u308c\u305f\u30c7\u30fc\u30bf\u3078\u306e stale \u66f4\u65b0\u3092\u3069\u306e\u3088\u3046\u306b\u691c\u51fa\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u7af6\u5408\u3092\u691c\u51fa\u3057\u306a\u3051\u308c\u3070\u3001\u5f8c\u304b\u3089\u4fdd\u5b58\u3057\u305f\u64cd\u4f5c\u304c\u5148\u884c\u3059\u308b\u6b63\u5f53\u306a\u66f4\u65b0\u3092\u9ed9\u3063\u3066\u4e0a\u66f8\u304d\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u8907\u6570\u306e\u95a2\u4fc2\u30c7\u30fc\u30bf\u3092\u66f4\u65b0\u3059\u308b<\/td>\n<td>\u72b6\u614b\u5909\u66f4\u3001\u76e3\u67fb\u8a18\u9332\u3001\u914d\u9001 intent \u306a\u3069\u3001\u3069\u3053\u307e\u3067\u3092\u4e00\u3064\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u3057\u3066\u78ba\u5b9a\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u696d\u52d9\u72b6\u614b\u3060\u3051\u66f4\u65b0\u3055\u308c\u76e3\u67fb\u8a18\u9332\u304c\u6b20\u843d\u3059\u308b\u306a\u3069\u3001\u4e00\u3064\u306e\u64cd\u4f5c\u304b\u3089\u76f8\u4e92\u306b\u77db\u76fe\u3057\u305f\u6c38\u7d9a\u72b6\u614b\u304c\u751f\u3058\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308b<\/td>\n<td>\u95a2\u4fc2\u30c7\u30fc\u30bf\u3068\u30d0\u30a4\u30ca\u30ea\u30c7\u30fc\u30bf\u306e\u4fdd\u5b58\u8cac\u52d9\u3092\u5206\u3051\u3064\u3064\u3001\u4e00\u89a7\u3001\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306e\u8a8d\u53ef\u3092\u3069\u3053\u3067\u7d71\u4e00\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u4fdd\u5b58\u5148\u3054\u3068\u306b\u8a8d\u53ef\u898f\u5247\u304c\u5206\u6563\u3059\u308b\u3068\u3001\u30e1\u30bf\u30c7\u30fc\u30bf\u3092\u95b2\u89a7\u3067\u304d\u306a\u3044\u5229\u7528\u8005\u304c\u5b9f\u4f53\u3060\u3051\u53d6\u5f97\u3067\u304d\u308b\u7d4c\u8def\u304c\u751f\u307e\u308c\u5f97\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u901a\u77e5\u304c\u3042\u308b<\/td>\n<td>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u66f4\u65b0\u3068\u30e1\u30fc\u30eb\u3084\u30a4\u30d9\u30f3\u30c8\u914d\u9001\u3092\u3001\u7570\u306a\u308b\u5931\u6557\u5883\u754c\u3092\u6301\u3064\u51e6\u7406\u3068\u3057\u3066\u3069\u3046\u63a5\u7d9a\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u696d\u52d9\u30c7\u30fc\u30bf\u306e commit \u3068\u5916\u90e8\u914d\u9001\u3092\u76f4\u63a5\u9023\u7d50\u3059\u308b\u3068\u3001\u4e00\u65b9\u3060\u3051\u6210\u529f\u3059\u308b\u4e8c\u91cd\u66f8\u304d\u8fbc\u307f\u306e\u4e0d\u6574\u5408\u304c\u767a\u751f\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u76e3\u67fb\u304c\u3042\u308b<\/td>\n<td>\u696d\u52d9\u4e0a\u6b8b\u3059\u5c65\u6b74\u3068\u3001\u969c\u5bb3\u89e3\u6790\u306b\u4f7f\u3046\u904b\u7528\u30ed\u30b0\u3092\u7570\u306a\u308b\u60c5\u5831\u3068\u3057\u3066\u3069\u3053\u3078\u8a18\u9332\u3059\u308b\u304b\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u4e21\u8005\u3092\u540c\u4e00\u8996\u3059\u308b\u3068\u3001\u696d\u52d9\u8a3c\u8de1\u304c\u30ed\u30b0 retention \u306b\u4f9d\u5b58\u3057\u305f\u308a\u3001\u904b\u7528\u30ed\u30b0\u3078\u4e0d\u8981\u306a\u696d\u52d9\u60c5\u5831\u304c\u84c4\u7a4d\u3057\u305f\u308a\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u7533\u8acb\u3068\u627f\u8a8d\u3068\u3044\u3046\u984c\u6750\u306f\u3001\u3053\u306e\u3088\u3046\u306a\u8a2d\u8a08\u5224\u65ad\u3092\u6700\u5c0f\u9650\u306e\u30c9\u30e1\u30a4\u30f3\u3067\u5b9f\u969b\u306b\u767a\u751f\u3055\u305b\u308b\u305f\u3081\u306b\u7f6e\u3044\u3066\u3044\u308b\u3002\u4efb\u610f\u306e\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u8a2d\u5b9a\u3067\u304d\u308b\u30a8\u30f3\u30b8\u30f3\u307e\u3067\u5b9f\u88c5\u3059\u308b\u3068\u3001\u72b6\u614b\u5b9a\u7fa9\u3001\u7ba1\u7406\u753b\u9762\u3001\u8a2d\u5b9a\u6c38\u7d9a\u5316\u3001\u5b9f\u884c\u6642\u89e3\u91c8\u306a\u3069\u5225\u306e\u8907\u96d1\u6027\u304c\u52a0\u308f\u308b\u3002\u8a8d\u53ef\u3001\u72b6\u614b\u9077\u79fb\u3001\u7af6\u5408\u3001\u76e3\u67fb\u3001\u901a\u77e5\u306e\u76f8\u4e92\u4f5c\u7528\u3092\u540c\u6642\u306b\u89b3\u6e2c\u3059\u308b\u305f\u3081\u3001DRAFT\u3001SUBMITTED\u3001APPROVED\u3001REJECTED \u3068\u3044\u3046\u56fa\u5b9a\u3055\u308c\u305f\u72b6\u614b\u6a5f\u68b0\u3092\u4f7f\u3044\u3001\u53c2\u7167\u5b9f\u88c5\u3068\u3057\u3066\u78ba\u8a8d\u3057\u305f\u3044\u8a2d\u8a08\u554f\u984c\u304c\u73fe\u308c\u308b\u7bc4\u56f2\u3078\u8907\u96d1\u6027\u3092\u9650\u5b9a\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u9069\u7528\u5bfe\u8c61\u3060\u3051\u3067\u306a\u304f\u3001\u5bfe\u8c61\u5916\u306e\u9818\u57df\u3082\u8981\u4ef6\u3068\u3057\u3066\u610f\u5473\u3092\u6301\u3064\u3002\u691c\u7d22\u30a8\u30f3\u30b8\u30f3\u5411\u3051\u516c\u958b\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u4e2d\u5fc3\u306e\u30b5\u30a4\u30c8\u3001SSR \u3084 SSG \u3092\u4e3b\u8981\u8981\u4ef6\u3068\u3059\u308b\u30b5\u30a4\u30c8\u3001\u30cd\u30a4\u30c6\u30a3\u30d6\u30e2\u30d0\u30a4\u30eb\u3001\u30c7\u30fc\u30bf\u5206\u6790\u3001\u30b9\u30c8\u30ea\u30fc\u30e0\u51e6\u7406\u3001IoT\u3001\u6a5f\u68b0\u5b66\u7fd2\u57fa\u76e4\u306f\u3001\u73fe\u5728\u306e\u53c2\u7167\u5bfe\u8c61\u306e\u4e2d\u5fc3\u304b\u3089\u5916\u3057\u3066\u3044\u308b<a href=\"#ref2\">[2]<\/a>\u3002\u3053\u308c\u3089\u3092\u4e00\u3064\u306e\u8a2d\u8a08\u3067\u540c\u6642\u306b\u6e80\u305f\u305d\u3046\u3068\u3059\u308c\u3070\u3001\u6c42\u3081\u3089\u308c\u308b\u5b9f\u884c\u30e2\u30c7\u30eb\u3001\u30c7\u30fc\u30bf\u7279\u6027\u3001\u914d\u4fe1\u65b9\u5f0f\u3001\u969c\u5bb3\u30e2\u30c7\u30eb\u304c\u5927\u304d\u304f\u7570\u306a\u308b\u305f\u3081\u3001\u57fa\u6e96\u3068\u306a\u308b\u5224\u65ad\u8ef8\u305d\u306e\u3082\u306e\u304c\u66d6\u6627\u306b\u306a\u308b\u3002<\/p>\n<p>\u5c06\u6765\u306e\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u5316\u3001Java \u306b\u3088\u308b\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u5b9f\u88c5\u3001\u8907\u6570\u30af\u30e9\u30a6\u30c9\u5bfe\u5fdc\u306b\u3064\u3044\u3066\u3082\u3001\u73fe\u5728\u306e\u8981\u4ef6\u3068\u5c06\u6765\u65b9\u5411\u3092\u5206\u96e2\u3057\u3066\u3044\u308b<a href=\"#ref2\">[2]<\/a>\u3002\u3053\u306e\u533a\u5225\u306b\u3088\u3063\u3066\u3001\u300c\u5c06\u6765\u3042\u308a\u5f97\u308b\u300d\u3068\u3044\u3046\u60c5\u5831\u3068\u73fe\u5728\u306e\u5b9f\u88c5\u8981\u4ef6\u3092\u5225\u306e\u78ba\u5ea6\u3067\u6271\u3048\u308b\u3002\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u5316\u3092\u60f3\u5b9a\u3057\u3066\u6a5f\u80fd\u5883\u754c\u306f\u6b8b\u3057\u3001\u73fe\u5728\u306e\u8981\u4ef6\u304c\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u3067\u6e80\u305f\u305b\u308b\u9593\u306f\u3001\u30b5\u30fc\u30d3\u30b9 discovery \u3084\u5206\u6563\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u5c06\u6765\u8981\u4ef6\u304c\u5177\u4f53\u5316\u3057\u305f\u6bb5\u968e\u306e\u9078\u629e\u80a2\u3068\u3057\u3066\u4fdd\u7559\u3059\u308b\u3002\u5c06\u6765\u65b9\u5411\u306f\u5883\u754c\u8a2d\u8a08\u3078\u5f71\u97ff\u3092\u4e0e\u3048\u3001\u73fe\u5728\u306e\u5b9f\u884c\u6642\u8907\u96d1\u6027\u306f\u73fe\u5728\u8981\u4ef6\u304b\u3089\u6c7a\u3081\u308b\u3002<\/p>\n<p>\u6280\u8853\u9078\u5b9a\u306f\u3001\u3053\u306e\u3088\u3046\u306b\u9069\u7528\u7bc4\u56f2\u3092\u72ed\u3081\u305f\u5f8c\u3067\u521d\u3081\u3066\u6bd4\u8f03\u53ef\u80fd\u306b\u306a\u308b\u3002\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u5fc3\u306e\u696d\u52d9 SPA \u3068\u3044\u3046\u6761\u4ef6\u304c\u7f6e\u304b\u308c\u308b\u3068\u3001SEO \u3092\u4e3b\u76ee\u7684\u3068\u3057\u305f rendering strategy \u3088\u308a\u3001\u8a8d\u8a3c\u5f8c\u306e\u64cd\u4f5c\u3001\u95a2\u4fc2\u30c7\u30fc\u30bf\u306e\u4e00\u8cab\u6027\u3001\u72b6\u614b\u9077\u79fb\u3001\u7af6\u5408\u5236\u5fa1\u3001\u76e3\u67fb\u53ef\u80fd\u6027\u306e\u6bd4\u91cd\u304c\u4e0a\u304c\u308b\u3002\u72b6\u614b\u5909\u66f4\u3068\u8907\u6570\u306e\u6c38\u7d9a\u30c7\u30fc\u30bf\u3092\u6574\u5408\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u5224\u65ad\u6750\u6599\u306b\u306a\u308a\u3001\u30d6\u30e9\u30a6\u30b6\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u8cac\u52d9\u3092\u5b89\u5b9a\u3055\u305b\u308b\u305f\u3081 API \u5951\u7d04\u304c\u5fc5\u8981\u306b\u306a\u308a\u3001\u5916\u90e8\u901a\u77e5\u3092\u4f34\u3046\u305f\u3081\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u5916\u90e8\u526f\u4f5c\u7528\u306e\u5883\u754c\u3092\u8a2d\u8a08\u3059\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002<\/p>\n<p>\u8981\u4ef6\u3092\u6df1\u6398\u308a\u3059\u308b\u3068\u304d\u306f\u3001\u3069\u306e\u7a2e\u985e\u306e\u554f\u984c\u3092\u89e3\u304f\u53c2\u7167\u5b9f\u88c5\u306a\u306e\u304b\u3092\u9650\u5b9a\u3057\u3001\u305d\u306e\u6761\u4ef6\u304b\u3089\u767a\u751f\u3059\u308b\u5931\u6557\u3001\u7af6\u5408\u3001\u8cac\u52d9\u3001\u4fdd\u8a3c\u7bc4\u56f2\u307e\u3067\u660e\u3089\u304b\u306b\u3059\u308b\u3002spa-reference \u3067\u306f\u3001\u3053\u306e\u9650\u5b9a\u306b\u3088\u3063\u3066\u5f8c\u7d9a\u306e React\u3001NestJS\u3001PostgreSQL\u3001OpenAPI\u3001Cognito\u3001transactional outbox \u306a\u3069\u3092\u3001\u305d\u308c\u305e\u308c\u304c\u3069\u306e\u8981\u6c42\u3092\u53d7\u3051\u6301\u3064\u306e\u304b\u304c\u660e\u793a\u3055\u308c\u305f\u8a2d\u8a08\u5224\u65ad\u3068\u3057\u3066\u8a55\u4fa1\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>3. Simplicity is robustness \u3092\u8907\u96d1\u6027\u4e88\u7b97\u3068\u3057\u3066\u8aad\u3080<\/h2>\n<p>spa-reference \u306e\u6700\u4e0a\u4f4d\u30dd\u30ea\u30b7\u30fc\u306f\u300cSimplicity is robustness.\u300d\u3067\u3042\u308b\u3002\u672c\u7a3f\u3067\u306f\u3001\u3053\u306e\u539f\u5247\u3092\u8907\u96d1\u6027\u4e88\u7b97\u3068\u3057\u3066\u8aad\u3080\u3002\u3053\u306e\u539f\u5247\u306f\u3001\u30b3\u30fc\u30c9\u91cf\u3088\u308a\u3082\u3001\u30b7\u30b9\u30c6\u30e0\u304c\u4fdd\u6301\u3057\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u6982\u5ff5\u3001\u72b6\u614b\u3001\u4f9d\u5b58\u95a2\u4fc2\u3001\u526f\u4f5c\u7528\u3001\u969c\u5bb3\u7d4c\u8def\u3001\u904b\u7528\u4e0a\u306e\u524d\u63d0\u306e\u7dcf\u91cf\u3092\u8a55\u4fa1\u5bfe\u8c61\u306b\u3059\u308b\u3002\u540c\u3058\u8981\u4ef6\u3092\u6e80\u305f\u3059\u4e8c\u3064\u306e\u8a2d\u8a08\u304c\u3042\u308b\u306a\u3089\u3001\u5236\u5fa1\u30d5\u30ed\u30fc\u304c\u5c11\u306a\u304f\u3001\u72b6\u614b\u304c\u5c11\u306a\u304f\u3001\u4f9d\u5b58\u95a2\u4fc2\u304c\u5c11\u306a\u304f\u3001\u904b\u7528\u6642\u306b\u78ba\u8a8d\u3059\u3079\u304d\u6761\u4ef6\u304c\u5c11\u306a\u3044\u69cb\u6210\u3092\u9078\u3076\u3002\u5b89\u5168\u6027\u3001\u4e92\u63db\u6027\u3001\u6587\u66f8\u3001\u691c\u8a3c\u306f\u7dad\u6301\u3057\u3001\u8981\u4ef6\u306b\u5fc5\u8981\u306a\u8907\u96d1\u6027\u3068\u5c06\u6765\u53ef\u80fd\u6027\u306e\u305f\u3081\u306b\u8ffd\u52a0\u3055\u308c\u308b\u8907\u96d1\u6027\u3092\u533a\u5225\u3059\u308b<a href=\"#ref4\">[4]<\/a>\u3002<\/p>\n<p>\u8907\u96d1\u6027\u306f\u5b9f\u88c5\u6642\u306e\u7406\u89e3\u8ca0\u8377\u306b\u52a0\u3048\u3001\u72b6\u614b\u3001\u4f9d\u5b58\u95a2\u4fc2\u3001\u969c\u5bb3\u7d4c\u8def\u3001\u904b\u7528\u624b\u9806\u3078\u6ce2\u53ca\u3059\u308b\u3002\u72b6\u614b\u3092\u4e00\u3064\u5897\u3084\u305b\u3070\u3001\u305d\u306e\u72b6\u614b\u3078\u5165\u308b\u6761\u4ef6\u3001\u305d\u3053\u304b\u3089\u51fa\u308b\u6761\u4ef6\u3001\u4e0d\u6b63\u72b6\u614b\u3001\u6c38\u7d9a\u5316\u3001\u5fa9\u65e7\u3001\u30c6\u30b9\u30c8\u304c\u5897\u3048\u308b\u3002\u5916\u90e8\u4f9d\u5b58\u3092\u4e00\u3064\u5897\u3084\u305b\u3070\u3001\u63a5\u7d9a\u8a2d\u5b9a\u3001\u8a8d\u8a3c\u60c5\u5831\u3001\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3001\u518d\u8a66\u884c\u3001\u969c\u5bb3\u6642\u306e\u6271\u3044\u3001\u76e3\u8996\u3001\u5229\u7528\u4e0d\u53ef\u6642\u306e\u6319\u52d5\u3092\u6c7a\u3081\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3092\u4e00\u3064\u5897\u3084\u305b\u3070\u3001\u901a\u5e38\u7cfb\u306e\u901a\u4fe1\u7d4c\u8def\u306b\u52a0\u3048\u3066\u3001\u9045\u5ef6\u3001\u5207\u65ad\u3001\u90e8\u5206\u5931\u6557\u3001\u518d\u9001\u3001\u91cd\u8907\u51e6\u7406\u3068\u3044\u3063\u305f distributed system \u56fa\u6709\u306e\u72b6\u614b\u304c\u5897\u3048\u308b\u3002\u5c40\u6240\u7684\u306b\u306f\u5c0f\u3055\u306a\u8ffd\u52a0\u3067\u3082\u3001\u8a2d\u8a08\u3001\u5b9f\u88c5\u3001\u904b\u7528\u3001\u691c\u8a3c\u3078\u6ce2\u53ca\u3059\u308b\u3053\u3068\u3067\u8cbb\u7528\u304c\u5897\u5e45\u3059\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u8ffd\u52a0\u3059\u308b\u69cb\u9020<\/th>\n<th>\u76f4\u63a5\u5897\u3048\u308b\u3082\u306e<\/th>\n<th>\u4e8c\u6b21\u7684\u306b\u5897\u3048\u308b\u3082\u306e<\/th>\n<th>spa-reference \u3067\u306e\u5224\u65ad<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u65b0\u3057\u3044\u72b6\u614b<\/td>\n<td>\u72b6\u614b\u5024\u3068\u9077\u79fb\u6761\u4ef6\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u4e0d\u6b63\u9077\u79fb\u3001\u5fa9\u65e7\u3001\u6c38\u7d9a\u5316\u3001\u8868\u793a\u3001\u30c6\u30b9\u30c8\u306e\u7d44\u307f\u5408\u308f\u305b\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u73fe\u5728\u306e\u696d\u52d9\u8981\u4ef6\u306b\u5fc5\u8981\u306a DRAFT\u3001SUBMITTED\u3001APPROVED\u3001REJECTED \u306b\u9650\u5b9a\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u65b0\u3057\u3044\u4f9d\u5b58\u95a2\u4fc2<\/td>\n<td>\u8a2d\u5b9a\u3068 API \u5229\u7528\u7b87\u6240\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u30d0\u30fc\u30b8\u30e7\u30f3\u7ba1\u7406\u3001\u969c\u5bb3\u6642\u51e6\u7406\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30ec\u30d3\u30e5\u30fc\u3001CI\u3001\u904b\u7528\u624b\u9806\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u65e2\u5b58\u306e platform \u3084\u4f9d\u5b58\u95a2\u4fc2\u304c\u8cac\u52d9\u3092\u5341\u5206\u306b\u6e80\u305f\u3059\u5834\u5408\u306f\u305d\u308c\u3092\u5229\u7528\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c<\/td>\n<td>\u901a\u4fe1\u30d7\u30ed\u30c8\u30b3\u30eb\u3068\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3001\u518d\u8a66\u884c\u3001\u90e8\u5206\u5931\u6557\u3001\u8a8d\u8a3c\u3001\u89b3\u6e2c\u3001\u91cd\u8907\u51e6\u7406\u3092\u8a2d\u8a08\u3059\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002<\/td>\n<td>\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u5185\u306e\u6a5f\u80fd\u306f\u30d7\u30ed\u30bb\u30b9\u5185\u547c\u3073\u51fa\u3057\u3068\u3057\u3001\u73fe\u5728\u5fc5\u8981\u306a\u7b87\u6240\u3060\u3051 HTTP \u5883\u754c\u3092\u6301\u3064\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u62bd\u8c61\u5316\u30ec\u30a4\u30e4\u30fc<\/td>\n<td>\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3001\u30a2\u30c0\u30d7\u30bf\u30fc\u3001\u30de\u30c3\u30d4\u30f3\u30b0\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u5b9f\u88c5\u6280\u8853\u3068\u306e\u5bfe\u5fdc\u95a2\u4fc2\u3092\u8ffd\u3046\u8a8d\u77e5\u8ca0\u8377\u3068\u5909\u66f4\u7b87\u6240\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u73fe\u5728\u306e\u8cac\u52d9\u5883\u754c\u3092\u8868\u3059\u5834\u5408\u306b\u5c0e\u5165\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u5b9f\u884c\u6642\u8a2d\u5b9a<\/td>\n<td>\u8a2d\u5b9a\u5024\u3068\u5206\u5c90\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u7d44\u307f\u5408\u308f\u305b\u3054\u3068\u306e\u8d77\u52d5\u6761\u4ef6\u3001\u8aa4\u8a2d\u5b9a\u3001\u30c6\u30b9\u30c8\u30de\u30c8\u30ea\u30af\u30b9\u3001\u6587\u66f8\u304c\u5897\u3048\u308b\u3002<\/td>\n<td>\u73fe\u5728\u5fc5\u8981\u306a\u5b9f\u884c\u6642\u30e2\u30fc\u30c9\u3068\u6a5f\u80fd\u9078\u629e\u3092\u56fa\u5b9a\u3057\u3066\u6271\u3046\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u8907\u96d1\u6027\u306f\u5c0e\u5165\u6642\u3060\u3051\u3067\u306a\u304f\u3001\u7a3c\u50cd\u4e2d\u3082\u4fdd\u6709\u30b3\u30b9\u30c8\u304c\u7d9a\u304f\u3002\u30b5\u30fc\u30d3\u30b9\u30ec\u30b8\u30b9\u30c8\u30ea\u30fc\u3092\u8ffd\u52a0\u3059\u308c\u3070\u3001\u5c0e\u5165\u4f5c\u696d\u304c\u7d42\u308f\u3063\u305f\u5f8c\u3082 registry \u81ea\u4f53\u306e\u53ef\u7528\u6027\u3001\u767b\u9332\u72b6\u614b\u3001\u63a2\u7d22\u5931\u6557\u3092\u8003\u3048\u7d9a\u3051\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u518d\u8a66\u884c\u6a5f\u69cb\u3092\u8ffd\u52a0\u3059\u308c\u3070\u3001\u901a\u4fe1\u6210\u529f\u7387\u3060\u3051\u3067\u306a\u304f\u3001\u518d\u9001\u306b\u3088\u308b\u4e8c\u91cd\u5b9f\u884c\u3084 backoff \u4e2d\u306e\u9045\u5ef6\u3082\u4ed5\u69d8\u306b\u306a\u308b\u3002\u62bd\u8c61\u5316\u3092\u5897\u3084\u305b\u3070\u3001\u5143\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u72ec\u81ea\u30ec\u30a4\u30e4\u30fc\u306e\u53cc\u65b9\u3092\u7406\u89e3\u3059\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002\u8907\u96d1\u6027\u306f\u5b9f\u88c5\u7b87\u6240\u306b\u9589\u3058\u305a\u3001\u30b7\u30b9\u30c6\u30e0\u306e\u610f\u5473\u8ad6\u3078\u4f1d\u64ad\u3059\u308b\u3002<\/p>\n<p>\u65e2\u7a3f\u300c\u7406\u89e3\u30fb\u8a2d\u8a08\u30fb\u5236\u5ea6\u306f\u306a\u305c\u5358\u7d14\u5316\u3078\u53ce\u675f\u3059\u308b\u306e\u304b\u300d\u3067\u306f\u3001\u904b\u7528\u306b\u3088\u3063\u3066\u5b9f\u969b\u306e\u5229\u7528\u983b\u5ea6\u3084\u5931\u6557\u7d4c\u8def\u304c\u89b3\u6e2c\u3055\u308c\u308b\u307b\u3069\u3001\u4f7f\u308f\u308c\u306a\u3044\u5206\u5c90\u3084\u904e\u5270\u306a\u9078\u629e\u80a2\u304c\u9664\u53bb\u3055\u308c\u3001\u5c11\u6570\u306e\u5b89\u5b9a\u7d4c\u8def\u3078\u69cb\u9020\u304c\u53ce\u675f\u3059\u308b\u3068\u8ad6\u3058\u305f<a href=\"#ref5\">[5]<\/a>\u3002spa-reference \u3067\u306f\u3001\u3053\u306e\u8003\u3048\u65b9\u3092\u4fdd\u5b88\u5f8c\u306e\u6574\u7406\u3068\u521d\u671f\u8a2d\u8a08\u306e\u53cc\u65b9\u306b\u9069\u7528\u3057\u3066\u3044\u308b\u3002\u89b3\u6e2c\u6e08\u307f\u306e\u73fe\u5728\u8981\u4ef6\u304b\u3089\u8cac\u52d9\u5883\u754c\u3092\u56fa\u5b9a\u3057\u3001\u305d\u306e\u5883\u754c\u306e\u5185\u5074\u306b\u5c06\u6765\u306e\u7f6e\u63db\u4f59\u5730\u3092\u6b8b\u3059\u3002<\/p>\n<p>\u3053\u306e\u533a\u5225\u306f\u3001\u5c06\u6765\u6027\u3092\u8cac\u52d9\u5883\u754c\u3068\u3057\u3066\u78ba\u4fdd\u3059\u308b\u8003\u3048\u65b9\u3067\u3042\u308b\u3002\u305f\u3068\u3048\u3070\u5c06\u6765\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u6a5f\u80fd\u3092\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u3068\u3057\u3066\u5206\u96e2\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u3063\u3066\u3082\u3001\u73fe\u5728\u306e Requests\u3001Approvals\u3001Attachments\u3001Audit \u306f\u540c\u3058 NestJS \u30d7\u30ed\u30bb\u30b9\u5185\u3067\u52d5\u304f\u3002\u4e00\u65b9\u3067\u3001\u305d\u308c\u305e\u308c\u306e\u8cac\u52d9\u3068\u4f9d\u5b58\u65b9\u5411\u306f\u5206\u3051\u308b\u3002\u73fe\u5728\u306f\u95a2\u6570\u547c\u3073\u51fa\u3057\u3067\u63a5\u7d9a\u3057\u306a\u304c\u3089\u3001\u5c06\u6765\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3092\u7f6e\u304f\u4f59\u5730\u306f\u30e2\u30b8\u30e5\u30fc\u30eb\u5883\u754c\u3068\u5951\u7d04\u306b\u6b8b\u3059\u3002\u5c06\u6765\u5909\u66f4\u53ef\u80fd\u6027\u306f\u3001\u5909\u66f4\u7406\u7531\u304c\u7570\u306a\u308b\u3082\u306e\u3092\u73fe\u5728\u304b\u3089\u5206\u3051\u3066\u304a\u304f\u3053\u3068\u3067\u78ba\u4fdd\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>Herbert A. Simon \u306f\u8907\u96d1\u306a\u30b7\u30b9\u30c6\u30e0\u306b\u3064\u3044\u3066\u3001\u6bd4\u8f03\u7684\u81ea\u5f8b\u3057\u305f subsystem \u304c\u968e\u5c64\u7684\u306b\u7d50\u5408\u3059\u308b\u69cb\u9020\u3092\u5206\u6790\u3057\u305f<a href=\"#ref6\">[6]<\/a>\u3002\u3053\u306e\u898b\u65b9\u3067\u306f\u3001\u8907\u96d1\u6027\u3092\u6271\u3046\u3046\u3048\u3067\u3001\u5185\u90e8\u306e\u8a73\u7d30\u3092\u5c40\u6240\u5316\u3067\u304d\u308b\u5358\u4f4d\u3092\u6301\u3064\u3053\u3068\u304c\u91cd\u8981\u306b\u306a\u308b\u3002David Parnas \u3082\u3001\u30e2\u30b8\u30e5\u30fc\u30eb decomposition \u306e\u57fa\u6e96\u3092\u51e6\u7406\u624b\u9806\u304b\u3089\u5909\u66f4\u3055\u308c\u5f97\u308b\u8a2d\u8a08\u5224\u65ad\u3078\u79fb\u3057\u3001\u30e2\u30b8\u30e5\u30fc\u30eb\u5185\u3078\u77e5\u8b58\u3092\u96a0\u3059\u3053\u3068\u3067\u4ed6\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u304c\u6301\u3064\u5185\u90e8\u77e5\u8b58\u3092\u6e1b\u3089\u3059\u69cb\u9020\u3092\u793a\u3057\u305f<a href=\"#ref7\">[7]<\/a>\u3002<\/p>\n<p>spa-reference \u306b\u5f53\u3066\u306f\u3081\u308b\u3068\u3001\u5c06\u6765\u306e\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u5316\u306b\u5099\u3048\u3066\u30b5\u30fc\u30d3\u30b9\u6570\u3092\u5897\u3084\u3059\u3053\u3068\u3088\u308a\u3001Requests \u304c Attachments \u306e\u30b9\u30c8\u30ec\u30fc\u30b8\u5b9f\u88c5\u3092\u77e5\u308b\u3001Approvals \u304c Cognito API \u3092\u76f4\u63a5\u547c\u3076\u3001\u30c9\u30e1\u30a4\u30f3\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c AWS SDK \u578b\u3092\u4fdd\u6301\u3059\u308b\u3068\u3044\u3063\u305f\u77e5\u8b58\u306e\u6f0f\u51fa\u3092\u9632\u3050\u65b9\u304c\u3001\u5909\u66f4\u53ef\u80fd\u6027\u306b\u76f4\u63a5\u52b9\u304f\u3002\u5883\u754c\u3092\u8d8a\u3048\u308b\u77e5\u8b58\u304c\u5c11\u306a\u3051\u308c\u3070\u3001\u5f8c\u304b\u3089\u30c7\u30d7\u30ed\u30a4\u5358\u4f4d\u3092\u5206\u3051\u308b\u5834\u5408\u3082\u5909\u66f4\u7bc4\u56f2\u3092\u5c40\u6240\u5316\u3067\u304d\u308b\u3002\u9006\u306b\u6700\u521d\u304b\u3089\u30b5\u30fc\u30d3\u30b9\u3092\u5206\u5272\u3057\u3066\u3082\u3001\u30c9\u30e1\u30a4\u30f3\u77e5\u8b58\u3068\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u77e5\u8b58\u304c\u76f8\u4e92\u306b\u6f0f\u308c\u3066\u3044\u308c\u3070\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u306e\u6570\u3060\u3051\u5897\u3048\u3066\u5909\u66f4\u5bb9\u6613\u6027\u306f\u5f97\u3089\u308c\u306a\u3044\u3002<\/p>\n<p>\u3053\u306e\u8003\u3048\u65b9\u304b\u3089\u3001spa-reference \u306f\u5c06\u6765\u69cb\u60f3\u3068\u73fe\u5728\u5b9f\u88c5\u3092\u660e\u78ba\u306b\u5206\u3051\u3066\u3044\u308b\u3002\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u3001Java\u3001\u30de\u30eb\u30c1\u30af\u30e9\u30a6\u30c9\u3068\u3044\u3046\u65b9\u5411\u306f requirements \u306b\u6b8b\u3057\u3001\u73fe\u6642\u70b9\u3067\u306f\u6a5f\u80fd\u5883\u754c\u306e\u4fdd\u6301\u306b\u53cd\u6620\u3059\u308b\u3002\u30b5\u30fc\u30d3\u30b9\u30ec\u30b8\u30b9\u30c8\u30ea\u30fc\u3001\u5206\u6563\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u8abf\u505c\u3001\u52d5\u7684\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3001\u8907\u6570\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u7d71\u4e00\u3059\u308b\u79fb\u690d\u6027\u30ec\u30a4\u30e4\u30fc\u306f\u3001\u5b9f\u969b\u306e\u8981\u4ef6\u304c\u5177\u4f53\u5316\u3057\u305f\u6bb5\u968e\u3067\u5c0e\u5165\u3059\u308b\u3002\u5c06\u6765\u65b9\u5411\u306f\u73fe\u5728\u306e\u5883\u754c\u3092\u4fdd\u3064\u5236\u7d04\u3068\u3057\u3066\u50cd\u304d\u3001\u8a2d\u8a08\u4e0a\u306e\u4f59\u5730\u3068\u5b9f\u884c\u6642\u306e\u8907\u96d1\u6027\u3092\u5206\u3051\u3066\u7ba1\u7406\u3059\u308b\u3002<\/p>\n<p>\u8907\u96d1\u6027\u4e88\u7b97\u3068\u3044\u3046\u898b\u65b9\u3092\u3059\u308b\u3068\u3001\u3053\u306e\u5224\u65ad\u306f\u8cbb\u7528\u5bfe\u52b9\u679c\u3068\u3057\u3066\u8aac\u660e\u3067\u304d\u308b\u3002\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3092\u4eca\u8ffd\u52a0\u3059\u308c\u3070\u3001\u305d\u306e\u8cbb\u7528\u306f\u4eca\u65e5\u304b\u3089\u767a\u751f\u3059\u308b\u3002\u4e00\u65b9\u3001\u5c06\u6765\u30b5\u30fc\u30d3\u30b9\u5206\u5272\u304c\u5b9f\u969b\u306b\u5fc5\u8981\u306b\u306a\u308b\u304b\u306f\u672a\u78ba\u5b9a\u3067\u3042\u308b\u3002\u8cac\u52d9\u5883\u754c\u3060\u3051\u3092\u73fe\u5728\u4f5c\u308b\u5834\u5408\u3001\u652f\u6255\u3046\u8cbb\u7528\u306f\u30e2\u30b8\u30e5\u30fc\u30eb decomposition \u3068\u5951\u7d04\u306e\u7dad\u6301\u306b\u9650\u5b9a\u3055\u308c\u308b\u3002\u5c06\u6765\u672c\u5f53\u306b\u72ec\u7acb\u30c7\u30d7\u30ed\u30a4\u3001\u5225\u30c1\u30fc\u30e0\u3001\u500b\u5225\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u3001\u969c\u5bb3\u9694\u96e2\u3068\u3044\u3063\u305f\u8981\u6c42\u304c\u751f\u3058\u305f\u6642\u70b9\u3067\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u306b\u4f34\u3046\u8cbb\u7528\u3092\u652f\u6255\u3048\u3070\u3088\u3044\u3002\u73fe\u5728\u78ba\u5b9a\u3057\u3066\u3044\u308b\u8981\u6c42\u3068\u5c06\u6765\u306e\u53ef\u80fd\u6027\u3092\u540c\u3058\u78ba\u5ea6\u3067\u6271\u308f\u306a\u3044\u3053\u3068\u304c\u3001\u8907\u96d1\u6027\u306e\u524d\u6255\u3044\u3092\u9632\u3050\u3002<\/p>\n<p>\u300cSimplicity is robustness.\u300d\u306f\u3001\u8981\u4ef6\u3092\u6e80\u305f\u3059\u305f\u3081\u306b\u5fc5\u8981\u306a\u8907\u96d1\u6027\u3078\u8cbb\u7528\u3092\u6255\u3044\u3001\u73fe\u5728\u8aac\u660e\u3001\u691c\u8a3c\u3001\u904b\u7528\u3059\u308b\u72b6\u614b\u7a7a\u9593\u3092\u5c0f\u3055\u304f\u4fdd\u3064\u8cc7\u6e90\u914d\u5206\u306e\u539f\u5247\u3067\u3042\u308b\u3002\u5c06\u6765\u8981\u4ef6\u3078\u306e\u5099\u3048\u306f\u8cac\u52d9\u5883\u754c\u306b\u6b8b\u3057\u3001\u72b6\u614b\u3084\u4f9d\u5b58\u95a2\u4fc2\u306e\u8ffd\u52a0\u306f\u8981\u4ef6\u304c\u5177\u4f53\u5316\u3057\u305f\u6642\u70b9\u3067\u884c\u3046\u3002spa-reference \u3067\u306f\u3001\u305d\u306e\u7d50\u679c\u3068\u3057\u3066\u3001\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u660e\u793a\u3055\u308c\u305f\u6a5f\u80fd\u5883\u754c\u3001\u56fa\u5b9a\u3055\u308c\u305f\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3001\u5fc5\u8981\u7b87\u6240\u3060\u3051\u306e\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u3068\u3044\u3046\u69cb\u9020\u304c\u9078\u3070\u308c\u3066\u3044\u308b\u3002\u5358\u7d14\u3055\u306f\u3001\u73fe\u5728\u8aac\u660e\u3057\u3001\u691c\u8a3c\u3057\u3001\u904b\u7528\u3057\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u72b6\u614b\u7a7a\u9593\u3092\u5c0f\u3055\u304f\u4fdd\u3064\u305f\u3081\u306b\u4f7f\u308f\u308c\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>4. \u8ad6\u7406\u5883\u754c\u3092\u5148\u306b\u4f5c\u308a\u3001\u7269\u7406\u5206\u6563\u306f\u5fc5\u8981\u6642\u306b\u884c\u3046<\/h2>\n<p>\u73fe\u5728\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u3001\u4e00\u3064\u306e NestJS \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3067\u3042\u308a\u3001\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u5358\u4f4d\u3067\u3042\u308b\u3002\u305d\u306e\u5185\u90e8\u306b BFF \u3068 Requests\u3001Approvals\u3001Attachments\u3001Audit \u306a\u3069\u306e\u6a5f\u80fd\u5883\u754c\u3092\u7f6e\u304d\u3001\u540c\u3058\u30d7\u30ed\u30bb\u30b9\u5185\u306b\u3042\u308b\u6a5f\u80fd\u306f\u901a\u5e38\u306e\u95a2\u6570\u547c\u3073\u51fa\u3057\u3068\u3057\u3066\u63a5\u7d9a\u3059\u308b\u3002\u5c06\u6765\u30ea\u30e2\u30fc\u30c8\u5b9f\u88c5\u3078\u5909\u66f4\u3067\u304d\u308b\u5883\u754c\u3092\u6b8b\u3057\u3064\u3064\u3001\u73fe\u5728\u306e\u30ed\u30fc\u30ab\u30eb\u51e6\u7406\u306f\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u5185\u306e\u95a2\u6570\u547c\u3073\u51fa\u3057\u3067\u63a5\u7d9a\u3059\u308b<a href=\"#ref8\">[8]<\/a>\u3002<\/p>\n<p>\u3053\u306e\u69cb\u6210\u3067\u306f\u3001\u8ad6\u7406\u7684\u306a\u5883\u754c\u3068\u7269\u7406\u7684\u306a\u5206\u6563\u3092\u5225\u306e\u5224\u65ad\u3068\u3057\u3066\u6271\u3046\u3002Requests \u3068 Approvals \u306e\u8cac\u52d9\u5206\u96e2\u306f\u3001\u5909\u66f4\u7406\u7531\u3001\u4f9d\u5b58\u65b9\u5411\u3001\u516c\u958b\u3059\u308b\u64cd\u4f5c\u3092\u6574\u7406\u3059\u308b\u8a2d\u8a08\u5224\u65ad\u3067\u3042\u308b\u3002\u5225\u30d7\u30ed\u30bb\u30b9\u3078\u306e\u914d\u7f6e\u306f\u3001\u901a\u4fe1\u3001\u914d\u7f6e\u3001\u76e3\u8996\u3001\u969c\u5bb3\u9694\u96e2\u3001\u72ec\u7acb\u30c7\u30d7\u30ed\u30a4\u307e\u3067\u542b\u3080\u904b\u7528\u4e0a\u306e\u5224\u65ad\u3067\u3042\u308b\u3002\u8cac\u52d9\u5883\u754c\u3092\u5148\u306b\u5b9a\u7fa9\u3057\u3001\u7269\u7406\u5206\u6563\u306f\u72ec\u7acb\u904b\u7528\u306e\u5fc5\u8981\u6027\u304c\u5177\u4f53\u5316\u3057\u305f\u6bb5\u968e\u3067\u5224\u65ad\u3059\u308b\u3002<\/p>\n<p>\u305f\u3068\u3048\u3070 Approvals \u304c Requests \u306e\u72b6\u614b\u3092\u53c2\u7167\u3057\u3066\u627f\u8a8d\u51e6\u7406\u3092\u884c\u3046\u5834\u5408\u3001\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u5185\u306a\u3089\u3001\u578b\u4ed8\u304d\u306e\u95a2\u6570\u547c\u3073\u51fa\u3057\u3068\u3057\u3066\u4f9d\u5b58\u95a2\u4fc2\u3092\u8868\u73fe\u3067\u304d\u308b\u3002\u3053\u308c\u3092\u5225\u30b5\u30fc\u30d3\u30b9\u5316\u3059\u308b\u3068\u3001\u540c\u3058\u8cac\u52d9\u5883\u754c\u306b\u5bfe\u3057\u3066\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u30b9\u30ad\u30fc\u30de\u3001\u30ec\u30b9\u30dd\u30f3\u30b9\u30b9\u30ad\u30fc\u30de\u3001\u8a8d\u8a3c\u3001\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3001\u518d\u8a66\u884c\u3001\u969c\u5bb3\u6642\u306e fallback\u3001\u53ef\u89b3\u6e2c\u6027\u304c\u8ffd\u52a0\u3055\u308c\u308b\u3002\u3055\u3089\u306b\u3001\u547c\u3073\u51fa\u3057\u5148\u304c\u51e6\u7406\u3092\u5b8c\u4e86\u3057\u305f\u306e\u306b\u5fdc\u7b54\u3060\u3051\u5931\u308f\u308c\u305f\u5834\u5408\u3001\u518d\u8a66\u884c\u306b\u3088\u308b\u91cd\u8907\u5b9f\u884c\u307e\u3067\u8003\u3048\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u8ad6\u7406\u5883\u754c\u3092\u4e00\u3064\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3078\u5909\u63db\u3059\u308b\u3060\u3051\u3067\u3001\u6271\u3046\u72b6\u614b\u7a7a\u9593\u306f\u5927\u304d\u304f\u5897\u3048\u308b\u3002<\/p>\n<p>Martin Fowler \u306e Monolith First \u306f\u3001\u30de\u30a4\u30af\u30ed\u30b5\u30fc\u30d3\u30b9\u304c\u6709\u52b9\u306a\u72b6\u6cc1\u3067\u3082\u904b\u7528\u4e0a\u306e\u8ffd\u52a0\u8cbb\u7528\u304c\u3042\u308a\u3001\u5883\u754c\u304c\u660e\u78ba\u306b\u306a\u308b\u524d\u304b\u3089\u5206\u6563\u3055\u305b\u308b\u3068\u3001\u305d\u306e\u8cbb\u7528\u3092\u65e9\u671f\u306b\u8ca0\u3046\u3068\u8ad6\u3058\u3066\u3044\u308b\u3002Fowler \u81ea\u8eab\u3082\u3053\u308c\u3092\u7d4c\u9a13\u5247\u3068\u3057\u3066\u4f4d\u7f6e\u4ed8\u3051\u3066\u3044\u308b<a href=\"#ref9\">[9]<\/a>\u3002spa-reference \u3082\u3001\u73fe\u5728\u306e\u8981\u4ef6\u304c\u4e00\u3064\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3067\u6e80\u305f\u305b\u308b\u3053\u3068\u3092\u57fa\u6e96\u306b\u3001\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u5358\u4f4d\u3092\u73fe\u5728\u69cb\u6210\u3068\u3057\u3066\u63a1\u7528\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u4e00\u3064\u306e\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u5358\u4f4d\u3092\u63a1\u7528\u3059\u308b\u3068\u3001\u696d\u52d9\u64cd\u4f5c\u3092\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u3068\u540c\u4e00\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u4e2d\u3067\u6271\u3048\u308b\u7bc4\u56f2\u304c\u5e83\u3044\u3002Requests \u306e\u72b6\u614b\u66f4\u65b0\u3001Audit \u306e\u8a18\u9332\u3001outbox \u3078\u306e\u914d\u9001\u4e88\u5b9a\u767b\u9332\u3092\u4e00\u3064\u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u542b\u3081\u308b\u3053\u3068\u3067\u3001\u30b5\u30fc\u30d3\u30b9\u9593\u901a\u4fe1\u3084\u5206\u6563\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u8abf\u505c\u3092\u4f34\u308f\u305a\u306b\u51e6\u7406\u3092\u5b8c\u7d50\u3067\u304d\u308b\u3002\u76f4\u63a5\u7684\u306b\u306f\u51e6\u7406\u7cfb\u304c\u5358\u7d14\u306b\u306a\u308a\u3001\u305d\u306e\u7d50\u679c\u3068\u3057\u3066\u969c\u5bb3\u6642\u306b\u78ba\u8a8d\u3059\u3079\u304d\u5834\u6240\u3001\u518d\u8a66\u884c\u6761\u4ef6\u3001\u76e3\u8996\u5bfe\u8c61\u3082\u6e1b\u308b\u3002<\/p>\n<p>\u30c7\u30d7\u30ed\u30a4\u5358\u4f4d\u306f\u4e00\u3064\u3067\u3082\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\/src \u4ee5\u4e0b\u3067\u306f\u30ea\u30af\u30a8\u30b9\u30c8\u3001approval\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u3001audit \u306a\u3069\u3092\u5225\u306e\u6a5f\u80fd\u3068\u3057\u3066\u6271\u3044\u3001\u5916\u90e8\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3078\u306e\u63a5\u7d9a\u3082\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306b\u9589\u3058\u8fbc\u3081\u308b\u3002\u5909\u66f4\u7406\u7531\u3054\u3068\u306e\u8ad6\u7406\u5883\u754c\u3092\u5148\u306b\u4f5c\u308b\u3053\u3068\u3067\u3001\u73fe\u5728\u306e\u904b\u7528\u8cbb\u7528\u3092\u6291\u3048\u306a\u304c\u3089\u5c06\u6765\u306e\u5206\u96e2\u6761\u4ef6\u3092\u89b3\u6e2c\u3067\u304d\u308b\u3002<\/p>\n<p>\u30d6\u30e9\u30a6\u30b6\u5074\u306b\u306f BFF \u3092\u4e00\u3064\u7f6e\u304f\u3002Microsoft \u306e Backends for Frontends pattern \u306f\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u56fa\u6709\u306e\u8981\u6c42\u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u5883\u754c\u306b\u9589\u3058\u8fbc\u3081\u3089\u308c\u308b\u4e00\u65b9\u3001\u30b5\u30fc\u30d3\u30b9\u8ffd\u52a0\u306b\u3088\u308b\u904b\u7528\u8cbb\u7528\u3084\u8ffd\u52a0\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u901a\u4fe1\u3082\u8003\u616e\u3059\u3079\u304d\u3068\u6574\u7406\u3057\u3066\u3044\u308b<a href=\"#ref10\">[10]<\/a>\u3002spa-reference \u3067\u306f\u73fe\u5728\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u4e00\u3064\u306e Web SPA \u306a\u306e\u3067\u3001BFF \u3082\u4e00\u3064\u3067\u8db3\u308a\u308b\u3002BFF \u306f\u30d6\u30e9\u30a6\u30b6\u5411\u3051 HTTP \u5883\u754c\u3092\u62c5\u3044\u3001\u5185\u90e8\u6a5f\u80fd\u306e\u914d\u7f6e\u3092\u30d6\u30e9\u30a6\u30b6\u3078\u516c\u958b\u3057\u306a\u3044\u3002<\/p>\n<p>BFF \u306f\u30d7\u30ed\u30ad\u30b7\u306b\u52a0\u3048\u3066\u3001\u30d6\u30e9\u30a6\u30b6\u304b\u3089\u898b\u305f\u8a8d\u8a3c\u3001\u8a8d\u53ef\u3001\u5165\u529b\u691c\u8a3c\u3001\u30a8\u30e9\u30fc\u5f62\u5f0f\u3001API \u5951\u7d04\u306e\u5883\u754c\u3092\u4e00\u304b\u6240\u306b\u96c6\u3081\u308b\u3002\u73fe\u5728 Requests \u304c\u540c\u3058 NestJS \u30d7\u30ed\u30bb\u30b9\u5185\u306b\u3042\u3063\u3066\u3082\u3001\u5c06\u6765\u5225\u30b5\u30fc\u30d3\u30b9\u3078\u79fb\u3063\u3066\u3082\u3001\u30d6\u30e9\u30a6\u30b6\u306f\u540c\u3058 HTTP \u5951\u7d04\u3092\u4f7f\u3048\u308b\u3002BFF \u306f\u3001\u5185\u90e8\u914d\u7f6e\u306e\u5909\u66f4\u306b\u5bfe\u3057\u3066\u30d6\u30e9\u30a6\u30b6\u5951\u7d04\u3092\u5b89\u5b9a\u3055\u305b\u308b\u5883\u754c\u3068\u3057\u3066\u6a5f\u80fd\u3059\u308b\u3002<\/p>\n<p>BFF \u3068\u6a5f\u80fd\u5883\u754c\u306e\u9593\u3067\u306f\u3001\u914d\u7f6e\u60c5\u5831\u3092\u5185\u90e8\u306b\u4fdd\u6301\u3059\u308b\u3002BFF \u306f\u300c\u3053\u306e\u64cd\u4f5c\u306f Requests \u6a5f\u80fd\u304c\u62c5\u5f53\u3059\u308b\u300d\u3068\u77e5\u308a\u3001\u30d6\u30e9\u30a6\u30b6\u306b\u306f\u516c\u958b API \u3060\u3051\u3092\u793a\u3059\u3002\u5185\u90e8 route \u30de\u30c3\u30d4\u30f3\u30b0\u3092\u30c7\u30d7\u30ed\u30a4-time \u306e\u69cb\u6210\u3068\u3057\u3066\u6271\u3048\u3070\u3001\u516c\u958b API \u3092\u7dad\u6301\u3057\u305f\u307e\u307e\u914d\u7f6e\u3092\u5909\u66f4\u3067\u304d\u308b\u3002\u5c06\u6765\u6027\u306f\u3001\u5951\u7d04\u3068\u914d\u7f6e\u306e\u5206\u96e2\u306b\u3088\u3063\u3066\u78ba\u4fdd\u3055\u308c\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5883\u754c<\/th>\n<th>\u73fe\u5728\u306e\u5b9f\u88c5<\/th>\n<th>\u73fe\u5728\u306e\u5b9f\u88c5\u65b9\u91dd<\/th>\n<th>\u4fdd\u6301\u3057\u3066\u3044\u308b\u5c06\u6765\u4f59\u5730<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u30d6\u30e9\u30a6\u30b6\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9<\/td>\n<td>BFF \u306e HTTP API \u3092\u552f\u4e00\u306e\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u696d\u52d9\u5883\u754c\u3068\u3057\u3066\u660e\u793a\u3059\u308b\u3002<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6\u306f BFF \u306e\u516c\u958b\u5951\u7d04\u3060\u3051\u3092\u77e5\u308b\u3002<\/td>\n<td>\u5185\u90e8\u6a5f\u80fd\u306e\u914d\u7f6e\u3092\u5909\u66f4\u3057\u3066\u3082\u3001\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u5951\u7d04\u3092\u7dad\u6301\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>BFF \u3068\u5185\u90e8\u6a5f\u80fd<\/td>\n<td>\u30ed\u30fc\u30ab\u30eb\u6a5f\u80fd\u306f\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u5185\u3067\u547c\u3073\u51fa\u3059\u3002<\/td>\n<td>\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u547c\u3073\u51fa\u3057\u3092\u4f7f\u3044\u3001\u5206\u6563\u901a\u4fe1\u306b\u4f34\u3046\u8ffd\u52a0\u72b6\u614b\u3092\u5b9f\u884c\u6642\u8981\u4ef6\u304b\u3089\u5916\u3059\u3002<\/td>\n<td>\u660e\u793a\u3055\u308c\u305f\u5883\u754c\u3092\u4fdd\u3063\u305f\u307e\u307e remote \u5b9f\u88c5\u3078\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u6a5f\u80fd\u9593<\/td>\n<td>Requests\u3001Approvals\u3001Attachments\u3001Audit \u3054\u3068\u306b\u8cac\u52d9\u3068\u4f9d\u5b58\u65b9\u5411\u3092\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u696d\u52d9\u5224\u65ad\u3092 Requests\u3001Approvals\u3001Attachments\u3001Audit \u306e\u5404\u6a5f\u80fd\u5883\u754c\u3078\u914d\u7f6e\u3059\u308b\u3002<\/td>\n<td>\u5909\u66f4\u7406\u7531\u3001\u8ca0\u8377\u7279\u6027\u3001\u30c1\u30fc\u30e0\u3001\u30ea\u30ea\u30fc\u30b9\u30b5\u30a4\u30af\u30eb\u304c\u72ec\u7acb\u3057\u305f\u6642\u70b9\u3067\u30b5\u30fc\u30d3\u30b9\u5206\u5272\u3092\u691c\u8a0e\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u30c7\u30fc\u30bf\u4e00\u8cab\u6027<\/td>\n<td>\u73fe\u5728\u4e00\u3064\u306e PostgreSQL \u4e92\u63db\u306e\u6c38\u7d9a\u5316\u3068\u30ed\u30fc\u30ab\u30eb\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u4f7f\u3046\u3002<\/td>\n<td>\u73fe\u5728\u306e\u6574\u5408\u6027\u306f\u30ed\u30fc\u30ab\u30eb\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3067\u6271\u3046\u3002<\/td>\n<td>\u5c06\u6765 remote \u6a5f\u80fd\u304c\u5fc5\u8981\u306b\u306a\u3063\u305f\u5834\u5408\u306b\u3001\u6574\u5408\u6027\u5883\u754c\u3092\u518d\u5b9a\u7fa9\u3059\u308b\u4f4d\u7f6e\u304c\u660e\u78ba\u306b\u306a\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>AWS \u56fa\u6709\u5b9f\u88c5<\/td>\n<td>\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u5185\u90e8\u3078\u9589\u3058\u8fbc\u3081\u308b\u3002<\/td>\n<td>Cognito\u3001S3\u3001SES\u3001SNS \u306e SDK \u578b\u306f\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u5185\u90e8\u306b\u7559\u3081\u308b\u3002<\/td>\n<td>\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3084\u30ed\u30fc\u30ab\u30eb\u5b9f\u88c5\u3092\u30a2\u30c0\u30d7\u30bf\u30fc\u5358\u4f4d\u3067\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>BFF \u3068\u5185\u90e8\u6a5f\u80fd\u306f\u73fe\u5728\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u5185\u306e\u95a2\u6570\u547c\u3073\u51fa\u3057\u3067\u63a5\u7d9a\u3057\u3001\u969c\u5bb3\u30e2\u30c7\u30eb\u3092\u30d7\u30ed\u30bb\u30b9\u5185\u306b\u4fdd\u3063\u3066\u3044\u308b\u3002\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3092\u7f6e\u304f\u3068\u3001\u547c\u3073\u51fa\u3057\u5148\u3060\u3051\u505c\u6b62\u3059\u308b\u3001\u901a\u4fe1\u3060\u3051\u5931\u6557\u3059\u308b\u3001\u51e6\u7406\u306f\u5b8c\u4e86\u3057\u305f\u304c\u30ec\u30b9\u30dd\u30f3\u30b9\u304c\u5931\u308f\u308c\u308b\u3001\u30b5\u30fc\u30d3\u30b9 discovery \u304c\u53e4\u3044\u3001\u8a8d\u8a3c\u60c5\u5831\u304c\u671f\u9650\u5207\u308c\u306b\u306a\u308b\u3068\u3044\u3063\u305f\u72b6\u614b\u304c\u8ffd\u52a0\u3055\u308c\u308b\u3002\u5206\u6563\u306b\u3088\u3063\u3066\u5f97\u308b\u72ec\u7acb\u6027\u304c\u5177\u4f53\u5316\u3059\u308b\u307e\u3067\u306f\u3001\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u306e\u5883\u754c\u304c\u73fe\u5728\u8981\u4ef6\u306b\u5bfe\u5fdc\u3059\u308b\u3002<\/p>\n<p>\u9006\u306b\u3001\u5206\u6563\u304c\u5fc5\u8981\u306b\u306a\u308b\u6761\u4ef6\u306f\u6bd4\u8f03\u7684\u660e\u78ba\u3067\u3042\u308b\u3002\u6a5f\u80fd\u3054\u3068\u306b\u72ec\u7acb\u3057\u305f\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\u304c\u5fc5\u8981\u306b\u306a\u308b\u3001\u969c\u5bb3\u9694\u96e2\u306e\u5fc5\u8981\u6027\u304c\u9ad8\u307e\u308b\u3001\u5225\u30c1\u30fc\u30e0\u304c\u72ec\u7acb\u3057\u305f\u30ea\u30ea\u30fc\u30b9\u30b5\u30a4\u30af\u30eb\u3092\u6301\u3064\u3001\u6280\u8853\u30b9\u30bf\u30c3\u30af\u3084\u30c7\u30fc\u30bf\u6240\u6709\u6a29\u3092\u5206\u3051\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3001\u3068\u3044\u3063\u305f\u8981\u6c42\u304c\u73fe\u308c\u308c\u3070\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3078\u79fb\u3059\u3053\u3068\u3067\u5f97\u3089\u308c\u308b\u5229\u76ca\u304c\u5177\u4f53\u5316\u3059\u308b\u3002\u305d\u306e\u6642\u70b9\u3067\u521d\u3081\u3066\u3001\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3001\u518d\u8a66\u884c\u3001idempotency\u3001\u30b5\u30fc\u30d3\u30b9\u8a8d\u8a3c\u3001\u53ef\u89b3\u6e2c\u6027\u306a\u3069\u306e\u8907\u96d1\u6027\u306b\u8cbb\u7528\u3092\u6255\u3046\u610f\u5473\u304c\u751f\u307e\u308c\u308b\u3002<\/p>\n<p>\u3053\u306e\u8a2d\u8a08\u3067\u306f\u3001\u300c\u5f8c\u3067\u5206\u3051\u3089\u308c\u308b\u3088\u3046\u306b\u3059\u308b\u300d\u3068\u300c\u4eca\u304b\u3089\u5206\u3051\u3066\u304a\u304f\u300d\u3092\u610f\u56f3\u7684\u306b\u533a\u5225\u3057\u3066\u3044\u308b\u3002\u524d\u8005\u306b\u5fc5\u8981\u306a\u306e\u306f\u3001\u8cac\u52d9\u3001\u5951\u7d04\u3001\u4f9d\u5b58\u65b9\u5411\u3001\u30c7\u30fc\u30bf\u6240\u6709\u306e\u5019\u88dc\u5883\u754c\u3092\u660e\u78ba\u306b\u3059\u308b\u3053\u3068\u3067\u3042\u308b\u3002\u5f8c\u8005\u306b\u306f\u3001\u305d\u308c\u306b\u52a0\u3048\u3066\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3001\u30c7\u30d7\u30ed\u30a4\u3001\u64cd\u4f5c\u3001failure recovery \u306e\u4ed5\u7d44\u307f\u304c\u5fc5\u8981\u306b\u306a\u308b\u3002\u73fe\u5728\u306e spa-reference \u306f\u524d\u8005\u307e\u3067\u3092\u5b9f\u88c5\u3057\u3001\u5f8c\u8005\u306f\u5b9f\u969b\u306e\u8981\u6c42\u304c\u767a\u751f\u3057\u305f\u6642\u70b9\u3067\u5224\u65ad\u3059\u308b\u3002<\/p>\n<p>\u3053\u306e\u8003\u3048\u65b9\u306f AWS \u56fa\u6709\u5b9f\u88c5\u306b\u3082\u9069\u7528\u3055\u308c\u308b\u3002\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30b3\u30fc\u30c9\u304c S3 \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3084 Cognito token structure \u3092\u76f4\u63a5\u6271\u3046\u3068\u3001\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u77e5\u8b58\u304c\u6a5f\u80fd\u5185\u90e8\u3078\u5e83\u304c\u308b\u3002\u305d\u3053\u3067\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b9\u30c8\u30ec\u30fc\u30b8\u3001identity\u3001mail\u3001\u30a4\u30d9\u30f3\u30c8 publication \u3092\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u80cc\u5f8c\u3078\u7f6e\u304f\u3002AWS \u30e2\u30fc\u30c9\u3067\u306f S3\u3001Cognito\u3001SES\u3001SNS \u3092\u4f7f\u3044\u3001\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3067\u306f\u30ed\u30fc\u30ab\u30eb\u5b9f\u88c5\u3078\u5dee\u3057\u66ff\u3048\u308b\u3002\u3053\u3053\u3067\u3082\u5c06\u6765\u6027\u3092\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u62bd\u8c61\u5316\u306e\u6570\u3067\u4f5c\u308b\u306e\u3067\u306f\u306a\u304f\u3001\u73fe\u5728\u5909\u66f4\u3055\u308c\u5f97\u308b\u8cac\u52d9\u3060\u3051\u3092\u5883\u754c\u3068\u3057\u3066\u56fa\u5b9a\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u5206\u6563\u53ef\u80fd\u6027\u306f\u3001\u5909\u66f4\u7406\u7531\u3092\u7570\u306a\u308b\u5358\u4f4d\u3078\u5206\u3051\u3001\u305d\u306e\u5358\u4f4d\u306e\u516c\u958b\u5951\u7d04\u3068\u4f9d\u5b58\u65b9\u5411\u3092\u660e\u78ba\u306b\u3057\u3001\u914d\u7f6e\u60c5\u5831\u3092\u5916\u90e8\u5951\u7d04\u304b\u3089\u72ec\u7acb\u3055\u305b\u308b\u3053\u3068\u3067\u4fdd\u3064\u3002spa-reference \u306f\u3001\u4e00\u3064\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u306e\u4e2d\u306b\u5c06\u6765\u5206\u96e2\u53ef\u80fd\u306a\u5883\u754c\u3092\u7f6e\u304d\u3001\u73fe\u5728\u306e\u5358\u7d14\u3055\u3068\u5c06\u6765\u306e\u5909\u66f4\u53ef\u80fd\u6027\u3092\u540c\u6642\u306b\u78ba\u4fdd\u3057\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>5. \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5883\u754c\u304b\u3089 PostgreSQL \u3068 outbox \u3092\u9078\u3076<\/h2>\n<p>\u8a73\u7d30\u8a2d\u8a08\u3067\u306f\u3001\u7533\u8acb\u306e\u72b6\u614b\u9077\u79fb\u3001\u76e3\u67fb\u8a18\u9332\u3001\u5916\u90e8\u901a\u77e5\u306e\u610f\u56f3\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3092\u500b\u5225\u306e\u5b9f\u88c5\u6280\u6cd5\u3068\u3057\u3066\u4e26\u3079\u3066\u3044\u306a\u3044\u3002\u4e00\u3064\u306e\u696d\u52d9\u64cd\u4f5c\u304c\u6210\u529f\u3057\u305f\u3068\u304d\u3001\u3069\u306e\u4e8b\u5b9f\u304c\u540c\u6642\u306b\u6210\u7acb\u3057\u3066\u3044\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u304b\u3068\u3044\u3046\u610f\u5473\u304b\u3089\u51e6\u7406\u9806\u5e8f\u3092\u5b9a\u7fa9\u3057\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u4fdd\u5b58\u6280\u8853\u3092\u9078\u3076\u524d\u306b\u6c7a\u3081\u308b\u306e\u306f\u3001\u30c7\u30fc\u30bf\u3092\u3069\u3053\u3078\u7f6e\u304f\u304b\u3067\u306f\u306a\u304f\u3001\u3069\u3053\u307e\u3067\u3092\u4e00\u3064\u306e\u6210\u529f\u307e\u305f\u306f\u5931\u6557\u3068\u3057\u3066\u6271\u3046\u304b\u3068\u3044\u3046\u6574\u5408\u6027\u5883\u754c\u3067\u3042\u308b\u3002<\/p>\n<p>\u305f\u3068\u3048\u3070 Approver \u304c\u7533\u8acb\u3092\u627f\u8a8d\u3059\u308b\u3068\u3001\u5c11\u306a\u304f\u3068\u3082\u4e09\u3064\u306e\u4e8b\u5b9f\u304c\u767a\u751f\u3059\u308b\u3002\u7533\u8acb\u72b6\u614b\u304c APPROVED \u3078\u5909\u308f\u308b\u3002\u8ab0\u304c\u3044\u3064\u627f\u8a8d\u3057\u305f\u304b\u3068\u3044\u3046\u76e3\u67fb\u8a18\u9332\u304c\u6b8b\u308b\u3002\u627f\u8a8d\u3055\u308c\u305f\u3068\u3044\u3046\u4e8b\u5b9f\u3092\u30e1\u30fc\u30eb\u3084\u30a4\u30d9\u30f3\u30c8\u3068\u3057\u3066\u5f8c\u304b\u3089\u914d\u9001\u3059\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002\u3053\u306e\u3046\u3061\u7533\u8acb\u3060\u3051\u304c APPROVED \u306b\u306a\u308a\u3001\u76e3\u67fb\u8a18\u9332\u304c\u5b58\u5728\u3057\u306a\u3044\u72b6\u614b\u306f\u696d\u52d9\u4e0a\u306e\u77db\u76fe\u3067\u3042\u308b\u3002\u53cd\u5bfe\u306b\u76e3\u67fb\u8a18\u9332\u3060\u3051\u5b58\u5728\u3057\u3066\u7533\u8acb\u304c SUBMITTED \u306e\u307e\u307e\u3067\u3082\u77db\u76fe\u3059\u308b\u3002\u72b6\u614b\u5909\u66f4\u3068\u76e3\u67fb\u8a18\u9332\u306f\u3001\u540c\u3058\u696d\u52d9\u64cd\u4f5c\u306e\u7d50\u679c\u3068\u3057\u3066\u4e00\u7dd2\u306b\u78ba\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/p>\n<p>spa-reference \u306f\u3001\u3053\u306e\u6574\u5408\u6027\u5883\u754c\u3092 PostgreSQL \u306e\u30ed\u30fc\u30ab\u30eb\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u5bfe\u5fdc\u3055\u305b\u3066\u3044\u308b\u3002\u73fe\u5728\u306e\u8a73\u7d30\u8a2d\u8a08\u3067\u306f isolation \u30ec\u30d9\u30eb\u306b READ COMMITTED \u3092\u4f7f\u3044\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u4f34\u3046\u72b6\u614b\u5909\u66f4\u3067\u306f\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5185\u3067\u5bfe\u8c61\u306e\u7533\u8acb\u884c\u3092\u30ed\u30c3\u30af\u3057\u3066\u304b\u3089\u3001\u30ea\u30bd\u30fc\u30b9\u56fa\u6709\u306e\u8a8d\u53ef\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u6bd4\u8f03\u3001\u73fe\u5728\u72b6\u614b\u306e\u691c\u8a3c\u3001\u66f4\u65b0\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u52a0\u7b97\u3001updatedAt \u306e\u66f4\u65b0\u3001\u76e3\u67fb\u3068 outbox \u306e\u8a18\u9332\u3092\u884c\u3044\u3001\u6700\u5f8c\u306b\u30b3\u30df\u30c3\u30c8\u3059\u308b<a href=\"#ref11\">[11]<\/a>\u3002<\/p>\n<p>READ COMMITTED \u3092\u9078\u3093\u3060\u3060\u3051\u3067\u306f\u540c\u6642\u66f4\u65b0\u306e\u610f\u5473\u306f\u6c7a\u307e\u3089\u306a\u3044\u3002\u4e8c\u4eba\u306e\u5229\u7528\u8005\u304c\u540c\u3058\u7533\u8acb\u3092\u30d0\u30fc\u30b8\u30e7\u30f3 3 \u3068\u3057\u3066\u8aad\u307f\u3001\u305d\u306e\u5f8c\u305d\u308c\u305e\u308c\u627f\u8a8d\u3068\u5374\u4e0b\u3092\u5b9f\u884c\u3057\u305f\u5834\u5408\u3092\u8003\u3048\u308b\u3002\u5148\u306b\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3057\u305f\u51e6\u7406\u304c\u30d0\u30fc\u30b8\u30e7\u30f3 4 \u3078\u66f4\u65b0\u3057\u3066\u30b3\u30df\u30c3\u30c8\u3059\u308b\u3068\u3001\u5f8c\u304b\u3089\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3057\u305f\u51e6\u7406\u306f\u73fe\u5728\u306e\u30d0\u30fc\u30b8\u30e7\u30f3 4 \u3068\u81ea\u5206\u304c\u9001\u3063\u305f\u30d0\u30fc\u30b8\u30e7\u30f3 3 \u306e\u4e0d\u4e00\u81f4\u3092\u691c\u51fa\u3059\u308b\u3002\u3053\u308c\u306b\u3088\u3063\u3066\u3001\u5f8c\u7740\u306e\u64cd\u4f5c\u304c\u5148\u884c\u64cd\u4f5c\u3092\u7121\u8a00\u3067\u4e0a\u66f8\u304d\u3059\u308b\u4ee3\u308f\u308a\u306b CONCURRENCY_CONFLICT \u3068\u3057\u3066\u89b3\u6e2c\u3055\u308c\u308b\u3002<\/p>\n<p>PostgreSQL \u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3 isolation \u306f\u3001\u4e26\u884c\u3057\u3066\u5b9f\u884c\u3055\u308c\u308b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u4e92\u3044\u306e\u5909\u66f4\u3092\u3069\u306e\u3088\u3046\u306b\u89b3\u6e2c\u3059\u308b\u304b\u3092\u898f\u5b9a\u3059\u308b<a href=\"#ref12\">[12]<\/a>\u3002spa-reference \u3067\u306f isolation \u30ec\u30d9\u30eb\u3060\u3051\u3078\u7af6\u5408\u51e6\u7406\u3092\u59d4\u306d\u305a\u3001\u884c\u30ed\u30c3\u30af\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u7d44\u307f\u5408\u308f\u305b\u3066\u696d\u52d9\u4e0a\u306e stale \u66f4\u65b0\u3092\u660e\u793a\u7684\u306b\u691c\u51fa\u3059\u308b\u3002\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u540c\u6642\u5b9f\u884c\u3092\u5236\u5fa1\u3059\u308b\u3053\u3068\u3068\u3001\u5229\u7528\u8005\u3078\u3069\u306e\u7af6\u5408\u3092\u901a\u77e5\u3059\u308b\u304b\u306f\u5225\u306e\u8cac\u52d9\u3060\u304b\u3089\u3067\u3042\u308b\u3002<\/p>\n<p>\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u78ba\u8a8d\u9806\u5e8f\u3082\u516c\u958b\u3055\u308c\u308b\u610f\u5473\u3092\u6301\u3064\u3002\u8a73\u7d30\u8a2d\u8a08\u3067\u306f\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u306e\u6bd4\u8f03\u3092\u72b6\u614b\u306e\u691c\u8a3c\u3088\u308a\u5148\u306b\u884c\u3046<a href=\"#ref11\">[11]<\/a>\u3002\u305d\u306e\u305f\u3081\u3001\u5229\u7528\u8005\u304c\u53e4\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u3001\u305d\u306e\u6642\u70b9\u306e\u6700\u65b0\u72b6\u614b\u3067\u306f\u64cd\u4f5c\u81ea\u4f53\u3082\u4e0d\u6b63\u306b\u306a\u3063\u3066\u3044\u308b\u5834\u5408\u3001\u8fd4\u3059\u306e\u306f REQUEST_INVALID_STATE \u3067\u306f\u306a\u304f CONCURRENCY_CONFLICT \u3067\u3042\u308b\u3002\u3053\u308c\u306f\u5185\u90e8\u306e if \u6587\u306e\u4e26\u3073\u65b9\u3067\u306f\u306a\u304f\u3001\u300c\u5229\u7528\u8005\u304c\u898b\u3066\u3044\u305f\u72b6\u614b\u304c\u3059\u3067\u306b\u53e4\u3044\u300d\u3068\u3044\u3046\u4e8b\u5b9f\u3092\u5148\u306b\u901a\u77e5\u3059\u308b API \u5951\u7d04\u3067\u3042\u308b\u3002<\/p>\n<p>\u30d0\u30fc\u30b8\u30e7\u30f3\u306f\u3001\u5909\u66f4\u3068\u898b\u306a\u3059\u64cd\u4f5c\u3067\u4e00\u5f8b\u306b\u5897\u3048\u308b\u308f\u3051\u3067\u3082\u306a\u3044\u3002\u73fe\u5728\u306e\u8a2d\u8a08\u3067\u306f\u3001draft \u66f4\u65b0\u3001submit\u3001approve\u3001reject \u3067\u4e00\u3064\u5897\u3048\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u306e\u8ffd\u52a0\u3067\u306f\u30ea\u30af\u30a8\u30b9\u30c8\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u5909\u66f4\u3057\u306a\u3044<a href=\"#ref11\">[11]<\/a>\u3002\u30d0\u30fc\u30b8\u30e7\u30f3\u304c\u8868\u3057\u3066\u3044\u308b\u306e\u306f\u5358\u306a\u308b\u66f4\u65b0\u56de\u6570\u3067\u306f\u306a\u304f\u3001\u7533\u8acb\u672c\u4f53\u306e\u72b6\u614b\u3084\u5185\u5bb9\u306b\u5bfe\u3059\u308b\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u306e\u57fa\u6e96\u3067\u3042\u308b\u3002\u4f55\u3092\u7af6\u5408\u3068\u3057\u3066\u6271\u3046\u304b\u3092\u5148\u306b\u5b9a\u7fa9\u3057\u3001\u305d\u306e\u610f\u5473\u306b\u5408\u308f\u305b\u3066\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u66f4\u65b0\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>Prisma 7 \u306f\u3001\u8907\u6570\u306e\u8aad\u307f\u66f8\u304d\u3092\u4e00\u3064\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u3057\u3066\u5b9f\u884c\u3057\u3001\u9014\u4e2d\u3067\u5931\u6557\u3059\u308c\u3070\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3059\u308b API \u3092\u63d0\u4f9b\u3059\u308b<a href=\"#ref13\">[13]<\/a>\u3002spa-reference \u3067\u306f\u3001PostgreSQL \u304c\u62c5\u3046\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u30ed\u30c3\u30af\u306e\u610f\u5473\u3092 TypeScript \u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304b\u3089\u5229\u7528\u3059\u308b\u305f\u3081\u306e\u6c38\u7d9a\u5316\u5b9f\u88c5\u3068\u3057\u3066 Prisma \u3092\u7f6e\u3044\u3066\u3044\u308b\u3002Prisma \u3092\u4f7f\u3046\u3053\u3068\u81ea\u4f53\u304c\u8a2d\u8a08\u306e\u8d77\u70b9\u3067\u306f\u306a\u304f\u3001\u300c\u72b6\u614b\u5909\u66f4\u3068\u305d\u306e\u696d\u52d9\u8a18\u9332\u3092\u540c\u3058 atomic \u5883\u754c\u3078\u7f6e\u304f\u300d\u3068\u3044\u3046\u8a2d\u8a08\u3092\u5b9f\u88c5\u3059\u308b\u624b\u6bb5\u3067\u3042\u308b\u3002<\/p>\n<p>\u3053\u306e\u5883\u754c\u306f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u90e8\u307e\u3067\u306f\u5f37\u304f\u5b9a\u7fa9\u3067\u304d\u308b\u304c\u3001SES \u3084 SNS \u307e\u3067\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u53c2\u52a0\u3055\u305b\u308b\u3053\u3068\u306f\u3067\u304d\u306a\u3044\u3002\u7533\u8acb\u3092 APPROVED \u306b\u3057\u3066\u30b3\u30df\u30c3\u30c8\u3057\u305f\u5f8c\u3001\u305d\u306e\u5834\u3067 SES \u3092\u547c\u3073\u51fa\u3059\u5b9f\u88c5\u3067\u306f\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u66f4\u65b0\u3060\u3051\u6210\u529f\u3057\u3066\u30e1\u30fc\u30eb\u9001\u4fe1\u304c\u5931\u6557\u3059\u308b\u7d4c\u8def\u304c\u6b8b\u308b\u3002\u5916\u90e8\u9001\u4fe1\u3092\u5148\u306b\u5b9f\u884c\u3059\u308c\u3070\u9006\u306e\u554f\u984c\u304c\u751f\u3058\u3001\u30e1\u30fc\u30eb\u306f\u5c4a\u3044\u305f\u306e\u306b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3057\u3066\u7533\u8acb\u306f\u627f\u8a8d\u3055\u308c\u3066\u3044\u306a\u3044\u3001\u3068\u3044\u3046\u72b6\u614b\u3092\u4f5c\u308a\u5f97\u308b\u3002<\/p>\n<p>\u3053\u306e\u4e8c\u3064\u306e\u66f8\u304d\u8fbc\u307f\u3092\u4e00\u3064\u306e\u51e6\u7406\u306b\u898b\u305b\u3066\u3082\u3001\u5b9f\u969b\u306e\u539f\u5b50\u6027\u306f\u5f97\u3089\u308c\u306a\u3044\u3002\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u5916\u90e8 API \u306f\u5225\u3005\u306e\u5931\u6557\u5883\u754c\u3092\u6301\u3061\u3001\u4e00\u65b9\u306e\u6210\u529f\u3092\u3082\u3046\u4e00\u65b9\u306e\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3067\u53d6\u308a\u6d88\u3059\u3053\u3068\u306f\u3067\u304d\u306a\u3044\u3002\u305d\u3053\u3067 spa-reference \u306f\u3001\u5916\u90e8\u914d\u9001\u305d\u306e\u3082\u306e\u3067\u306f\u306a\u304f\u300c\u3053\u306e\u696d\u52d9\u7d50\u679c\u3092\u914d\u9001\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u300d\u3068\u3044\u3046\u610f\u56f3\u307e\u3067\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u542b\u3081\u308b\u3002<\/p>\n<p>AWS Prescriptive Guidance \u306e transactional outbox pattern \u3082\u3001\u696d\u52d9\u30c7\u30fc\u30bf\u3068\u914d\u9001\u4e88\u5b9a\u3092\u540c\u3058\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u66f8\u304d\u8fbc\u307f\u3001\u305d\u306e\u30b3\u30df\u30c3\u30c8\u5f8c\u306b\u5225\u306e\u51e6\u7406\u304c\u5916\u90e8\u30b7\u30b9\u30c6\u30e0\u3078\u914d\u9001\u3059\u308b\u3053\u3068\u3067\u4e8c\u91cd\u66f8\u304d\u8fbc\u307f\u306e\u4e0d\u6574\u5408\u3092\u5206\u96e2\u3059\u308b<a href=\"#ref14\">[14]<\/a>\u3002spa-reference \u3067\u306f REQUEST_SUBMITTED\u3001REQUEST_APPROVED\u3001REQUEST_REJECTED \u306e\u5404\u72b6\u614b\u9077\u79fb\u306b\u3064\u3044\u3066\u3001\u540c\u3058\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5185\u306b EMAIL \u3068 EVENT \u306e\u4e8c\u3064\u306e outbox \u884c\u3092\u4f5c\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u30ea\u30af\u30a8\u30b9\u30c8 creation\u3001draft \u66f4\u65b0\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb addition \u3067\u306f\u901a\u77e5\u8981\u4ef6\u304c\u306a\u3044\u305f\u3081 outbox \u884c\u3092\u4f5c\u3089\u306a\u3044\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u51e6\u7406<\/th>\n<th>\u4fdd\u8a3c\u3059\u308b\u7bc4\u56f2<\/th>\n<th>\u540c\u3058\u5883\u754c\u3078\u7f6e\u304f\u7406\u7531<\/th>\n<th>\u5931\u6557\u6642\u306e\u610f\u5473<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u7533\u8acb\u72b6\u614b\u66f4\u65b0<\/td>\n<td>DB \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5185\u3067\u539f\u5b50\u7684\u306b\u78ba\u5b9a\u3059\u308b\u3002<\/td>\n<td>\u696d\u52d9\u64cd\u4f5c\u305d\u306e\u3082\u306e\u306a\u306e\u3067\u3001\u76e3\u67fb\u3084\u914d\u9001\u610f\u56f3\u3068\u98df\u3044\u9055\u3063\u305f\u72b6\u614b\u3092\u78ba\u5b9a\u3055\u305b\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002<\/td>\n<td>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u304c\u5931\u6557\u3059\u308c\u3070\u72b6\u614b\u5909\u66f4\u3082\u78ba\u5b9a\u3057\u306a\u3044\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u76e3\u67fb\u30a4\u30d9\u30f3\u30c8<\/td>\n<td>\u7533\u8acb\u72b6\u614b\u66f4\u65b0\u3068\u540c\u3058 DB \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3067\u78ba\u5b9a\u3059\u308b\u3002<\/td>\n<td>\u5b9f\u969b\u306b\u306f\u767a\u751f\u3057\u3066\u3044\u306a\u3044\u64cd\u4f5c\u306e\u76e3\u67fb\u8a18\u9332\u3084\u3001\u8a18\u9332\u306e\u306a\u3044\u72b6\u614b\u5909\u66f4\u3092\u6b8b\u3055\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002<\/td>\n<td>\u72b6\u614b\u66f4\u65b0\u304c\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3059\u308c\u3070\u76e3\u67fb\u30a4\u30d9\u30f3\u30c8\u3082\u30ed\u30fc\u30eb\u30d0\u30c3\u30af\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>outbox \u306e\u914d\u9001\u610f\u56f3<\/td>\n<td>\u696d\u52d9\u72b6\u614b\u3068\u540c\u3058 DB \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3067\u78ba\u5b9a\u3059\u308b\u3002<\/td>\n<td>\u5916\u90e8\u914d\u9001\u304c\u4e00\u6642\u7684\u306b\u5931\u6557\u3057\u3066\u3082\u3001\u914d\u9001\u3059\u3079\u304d\u4e8b\u5b9f\u305d\u306e\u3082\u306e\u3092\u5931\u308f\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002<\/td>\n<td>\u30b3\u30df\u30c3\u30c8\u5f8c\u306f\u30ef\u30fc\u30ab\u30fc\u304c\u914d\u9001\u3092\u518d\u8a66\u884c\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>SES \u3068 SNS \u3078\u306e\u914d\u9001<\/td>\n<td>DB \u30b3\u30df\u30c3\u30c8\u5f8c\u306e\u5225\u51e6\u7406\u3068\u3057\u3066\u5b9f\u884c\u3059\u308b\u3002<\/td>\n<td>\u5916\u90e8\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306f PostgreSQL \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u53c2\u52a0\u305b\u305a\u3001\u72ec\u7acb\u3057\u305f\u5931\u6557\u5883\u754c\u3092\u6301\u3064\u305f\u3081\u3067\u3042\u308b\u3002<\/td>\n<td>\u5931\u6557\u3057\u3066\u3082\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u306f\u7dad\u6301\u3055\u308c\u3001outbox \u306e\u72b6\u614b\u3068\u518d\u8a66\u884c\u898f\u5247\u3067\u56de\u5fa9\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>outbox \u3092\u7f6e\u304f\u3060\u3051\u3067\u306f\u3001\u914d\u9001\u51e6\u7406\u306e\u7af6\u5408\u3068\u969c\u5bb3\u56de\u5fa9\u306f\u89e3\u6c7a\u3057\u306a\u3044\u3002\u8907\u6570\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30bf\u30b9\u30af\u304c\u540c\u6642\u306b\u30ef\u30fc\u30ab\u30fc\u3092\u5b9f\u884c\u3059\u308b\u5834\u5408\u3001\u540c\u3058\u884c\u3092\u540c\u6642\u306b\u53d6\u5f97\u3059\u308b\u3068\u4e8c\u91cd\u914d\u9001\u304c\u5897\u3048\u308b\u3002\u305d\u3053\u3067\u73fe\u5728\u306e\u8a73\u7d30\u8a2d\u8a08\u3067\u306f PostgreSQL \u306e FOR UPDATE SKIP LOCKED \u306b\u76f8\u5f53\u3059\u308b\u884c\u30ed\u30c3\u30af\u3092\u4f7f\u3044\u3001\u77ed\u3044 claim \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u4e2d\u3067\u914d\u9001\u5bfe\u8c61\u3092 PROCESSING \u3078\u79fb\u3059\u3002claim \u6642\u306b\u306f attempt_count \u3092\u5897\u3084\u3057\u3001\u30e9\u30f3\u30c0\u30e0\u306a claim_token\u3001claimed_at\u300160 \u79d2\u5f8c\u306e claim_expires_at \u3092\u8a18\u9332\u3057\u3066\u304b\u3089\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30b3\u30df\u30c3\u30c8\u3059\u308b<a href=\"#ref11\">[11]<\/a>\u3002<\/p>\n<p>\u5916\u90e8 API \u547c\u3073\u51fa\u3057\u306f\u3001\u3053\u306e claim \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30b3\u30df\u30c3\u30c8\u3057\u305f\u5f8c\u306b\u884c\u3046\u3002SES \u3084 SNS \u306e\u5fdc\u7b54\u3092\u5f85\u3063\u3066\u3044\u308b\u9593\u305a\u3063\u3068\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u884c\u3092\u30ed\u30c3\u30af\u3059\u308b\u3068\u3001\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u306e\u9045\u5ef6\u304c DB \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u9577\u6642\u9593\u5316\u3078\u76f4\u7d50\u3059\u308b\u304b\u3089\u3067\u3042\u308b\u3002\u73fe\u5728\u306e\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u547c\u3073\u51fa\u3057\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u306f\u6700\u5927 15 \u79d2\u3067\u3001claim lease \u306f\u305d\u308c\u3088\u308a\u9577\u3044 60 \u79d2\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u77ed\u3044 DB \u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u9577\u3044\u5916\u90e8 I\/O \u3092\u5206\u96e2\u3059\u308b\u3053\u3068\u3067\u3001\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30ed\u30c3\u30af\u6642\u9593\u3092\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u5fdc\u7b54\u6642\u9593\u3078\u5f93\u5c5e\u3055\u305b\u306a\u3044\u3002<\/p>\n<p>\u914d\u9001\u6210\u529f\u5f8c\u3082\u3001\u30ef\u30fc\u30ab\u30fc\u306f\u81ea\u5206\u304c\u53d6\u5f97\u3057\u305f claim_token \u304c\u307e\u3060\u884c\u306b\u6b8b\u3063\u3066\u3044\u308b\u5834\u5408\u3060\u3051 DELIVERED \u3078\u66f4\u65b0\u3059\u308b\u3002\u30ef\u30fc\u30ab\u30fc\u304c\u505c\u6b62\u3057\u3001lease \u304c\u5207\u308c\u3001\u5225\u306e\u30ef\u30fc\u30ab\u30fc\u304c\u540c\u3058\u884c\u3092\u518d\u53d6\u5f97\u3057\u305f\u5f8c\u306b\u53e4\u3044\u30ef\u30fc\u30ab\u30fc\u304c\u5fa9\u5e30\u3057\u305f\u5834\u5408\u3001\u53e4\u3044\u51e6\u7406\u304c\u65b0\u3057\u3044 claim \u306e\u72b6\u614b\u3092\u4e0a\u66f8\u304d\u3057\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002\u3053\u306e token \u306b\u3088\u308b\u6240\u6709\u78ba\u8a8d\u307e\u3067\u542b\u3081\u3066\u3001\u8907\u6570\u30ef\u30fc\u30ab\u30fc\u3068\u969c\u5bb3\u56de\u5fa9\u304c\u540c\u6642\u306b\u5b58\u5728\u3059\u308b\u5834\u5408\u306e\u72b6\u614b\u9077\u79fb\u3092\u5b9a\u7fa9\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u5931\u6557\u3057\u305f\u914d\u9001\u306f\u7121\u5236\u9650\u306b\u306f\u518d\u8a66\u884c\u3057\u306a\u3044\u3002attempt_count \u304c 5 \u672a\u6e80\u306a\u3089 PENDING \u3078\u623b\u3057\u3066\u6b21\u56de\u8a66\u884c\u6642\u523b\u3092\u8a2d\u5b9a\u3057\u30015 \u56de\u76ee\u306e\u5931\u6557\u5f8c\u306f FAILED \u3068\u3057\u3066\u81ea\u52d5\u518d\u8a66\u884c\u3092\u505c\u6b62\u3059\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u3053\u3053\u306b\u3082\u300c\u518d\u8a66\u884c\u3059\u308c\u3070\u305d\u306e\u3046\u3061\u6210\u529f\u3059\u308b\u300d\u3068\u3044\u3046\u66d6\u6627\u306a\u671f\u5f85\u3067\u306f\u306a\u304f\u3001\u30b7\u30b9\u30c6\u30e0\u304c\u81ea\u52d5\u7684\u306b\u8cac\u4efb\u3092\u6301\u3064\u7bc4\u56f2\u3092\u6709\u9650\u306b\u3059\u308b\u8003\u3048\u65b9\u304c\u73fe\u308c\u3066\u3044\u308b\u3002<\/p>\n<p>\u305d\u308c\u3067\u3082\u6b63\u78ba\u306b\u4e00\u56de delivery \u306f\u6210\u7acb\u3057\u306a\u3044\u3002\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u547c\u3073\u51fa\u3057\u304c\u6210\u529f\u3057\u305f\u76f4\u5f8c\u3001outbox \u884c\u3092 DELIVERED \u3078\u66f4\u65b0\u3059\u308b\u524d\u306b\u30d7\u30ed\u30bb\u30b9\u304c\u505c\u6b62\u3059\u308b\u3068\u3001lease \u306e\u5931\u52b9\u5f8c\u306b\u540c\u3058\u914d\u9001\u304c\u518d\u5b9f\u884c\u3055\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u3002\u8a73\u7d30\u8a2d\u8a08\u306f\u3053\u308c\u3092 expected \u5c11\u306a\u304f\u3068\u3082\u4e00\u56de\u632f\u308b\u821e\u3044\u3068\u3057\u3066\u660e\u793a\u3057\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002SNS \u30a4\u30d9\u30f3\u30c8\u306b\u306f eventId \u3092\u91cd\u8907\u6392\u9664 key \u3068\u3057\u3066\u542b\u3081\u308b\u305f\u3081 downstream consumer \u5074\u3067\u91cd\u8907\u6392\u9664\u3067\u304d\u308b\u304c\u3001email \u306b\u3064\u3044\u3066\u6b63\u78ba\u306b\u4e00\u56de\u306e\u4fdd\u8a3c\u306f\u7f6e\u3044\u3066\u3044\u306a\u3044\u3002<\/p>\n<p>\u3053\u306e\u4fdd\u8a3c\u7bc4\u56f2\u306e\u9650\u5b9a\u306f\u3001transactional outbox \u3092\u63a1\u7528\u3059\u308b\u7406\u7531\u305d\u306e\u3082\u306e\u3068\u4e00\u81f4\u3059\u308b\u3002\u76ee\u7684\u306f\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u5916\u90e8\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u4e00\u3064\u306e\u5206\u6563\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u3088\u3046\u306b\u898b\u305b\u308b\u3053\u3068\u3067\u306f\u306a\u3044\u3002\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u90e8\u3067\u306f\u72b6\u614b\u5909\u66f4\u3001\u76e3\u67fb\u3001\u914d\u9001\u610f\u56f3\u3092\u539f\u5b50\u7684\u306b\u78ba\u5b9a\u3057\u3001\u305d\u306e\u5916\u5074\u3067\u306f\u5c11\u306a\u304f\u3068\u3082\u4e00\u56de\u306e\u914d\u9001\u3068\u6709\u9650\u56de\u306e\u518d\u8a66\u884c\u3092\u63d0\u4f9b\u3059\u308b\u3002\u305d\u308c\u305e\u308c\u306e\u57fa\u76e4\u304c\u5b9f\u969b\u306b\u4fdd\u8a3c\u3067\u304d\u308b\u7bc4\u56f2\u3078\u8cac\u52d9\u3092\u5206\u3051\u308b\u3053\u3068\u3067\u3001\u969c\u5bb3\u6642\u306b\u3082\u4f55\u304c\u78ba\u5b9a\u6e08\u307f\u3067\u3001\u4f55\u304c\u518d\u5b9f\u884c\u3055\u308c\u5f97\u308b\u304b\u3092\u8aac\u660e\u3067\u304d\u308b\u3002<\/p>\n<p>PostgreSQL\u3001Prisma\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001transactional outbox \u306f\u3001\u72ec\u7acb\u3057\u305f\u6d41\u884c\u6280\u8853\u3068\u3057\u3066\u96c6\u3081\u3089\u308c\u305f\u3082\u306e\u3067\u306f\u306a\u3044\u3002\u7533\u8acb\u306e\u72b6\u614b\u5909\u66f4\u3068\u76e3\u67fb\u3092\u4e00\u3064\u306e\u696d\u52d9\u7d50\u679c\u3068\u3057\u3066\u78ba\u5b9a\u3057\u305f\u3044\u3001\u540c\u6642\u66f4\u65b0\u306b\u3088\u308b silent overwrite \u3092\u9632\u304e\u305f\u3044\u3001\u5916\u90e8\u901a\u77e5\u306e\u5931\u6557\u306b\u3088\u3063\u3066\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u3092\u5dfb\u304d\u623b\u3057\u305f\u304f\u306a\u3044\u3001\u914d\u9001\u8981\u6c42\u305d\u306e\u3082\u306e\u306f\u5931\u3044\u305f\u304f\u306a\u3044\u3068\u3044\u3046\u8981\u6c42\u3092\u9806\u306b\u5206\u89e3\u3059\u308b\u3068\u3001\u305d\u308c\u305e\u308c\u306e\u5f79\u5272\u304c\u73fe\u308c\u308b\u3002\u6280\u8853\u540d\u3088\u308a\u5148\u306b\u6574\u5408\u6027\u5883\u754c\u3092\u5b9a\u7fa9\u3057\u3001\u305d\u306e\u5883\u754c\u3054\u3068\u306b\u6210\u7acb\u3059\u308b\u4fdd\u8a3c\u3092\u5272\u308a\u5f53\u3066\u308b\u3053\u3068\u304c\u3001spa-reference \u306e\u6c38\u7d9a\u5316\u3068\u901a\u77e5\u8a2d\u8a08\u306e\u4e2d\u5fc3\u306b\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>6. \u8a8d\u8a3c\u3068 API \u5951\u7d04\u306f\u5b9f\u88c5\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u304b\u3089\u5207\u308a\u96e2\u3059<\/h2>\n<p>spa-reference \u306e\u30d6\u30e9\u30a6\u30b6\u5411\u3051 API \u306f OpenAPI 3.1 \u3092\u6b63\u672c\u3068\u3057\u3066\u3044\u308b\u3002OpenAPI Specification \u306f HTTP API \u306e path\u3001method\u3001parameter\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u30dc\u30c7\u30a3\u3001\u30ec\u30b9\u30dd\u30f3\u30b9\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3 scheme \u306a\u3069\u3092\u3001\u7279\u5b9a\u306e\u5b9f\u88c5\u8a00\u8a9e\u304b\u3089\u72ec\u7acb\u3057\u305f\u5f62\u3067\u8a18\u8ff0\u3059\u308b\u4ed5\u69d8\u3067\u3042\u308b<a href=\"#ref15\">[15]<\/a>\u3002\u3053\u306e\u6027\u8cea\u3092\u5229\u7528\u3059\u308b\u3068\u3001React \u3068 NestJS \u304c\u540c\u3058 TypeScript \u3092\u4f7f\u3063\u3066\u3044\u3066\u3082\u3001\u4e21\u8005\u306e\u901a\u4fe1\u5951\u7d04\u3092 TypeScript \u306e\u5185\u90e8\u578b\u305d\u306e\u3082\u306e\u3078\u4f9d\u5b58\u3055\u305b\u305a\u306b\u6e08\u3080\u3002<\/p>\n<p>\u540c\u3058\u8a00\u8a9e\u3092\u4f7f\u3046\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3067\u306f\u3001TypeScript \u306e\u578b\u3092\u76f4\u63a5\u5171\u6709\u3059\u308b\u65b9\u6cd5\u3082\u53d6\u308c\u308b\u3002\u77ed\u671f\u7684\u306b\u306f\u8a18\u8ff0\u91cf\u3092\u6e1b\u3089\u3057\u3084\u3059\u3044\u304c\u3001\u5171\u6709\u578b\u304c\u4f55\u3092\u610f\u5473\u3059\u308b\u304b\u3092\u533a\u5225\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u5185\u90e8\u306e\u30af\u30e9\u30b9\u306f\u6c38\u7d9a\u5316\u3084\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u90fd\u5408\u3067\u5909\u5316\u3059\u308b\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u8868\u793a\u7528 model \u3082\u753b\u9762\u69cb\u6210\u306b\u5fdc\u3058\u3066\u5909\u5316\u3059\u308b\u3002\u4e00\u65b9\u3001HTTP \u3067\u5916\u90e8\u3078\u516c\u958b\u3057\u305f\u30ea\u30af\u30a8\u30b9\u30c8\u3001\u30ec\u30b9\u30dd\u30f3\u30b9\u3001status \u30b3\u30fc\u30c9\u3001error \u30b3\u30fc\u30c9\u306f\u3001\u901a\u4fe1\u76f8\u624b\u304c\u4f9d\u5b58\u3059\u308b\u5951\u7d04\u3067\u3042\u308b\u3002\u5bff\u547d\u3068\u5909\u66f4\u7406\u7531\u306e\u7570\u306a\u308b\u4e09\u7a2e\u985e\u306e\u578b\u3092\u540c\u3058\u3082\u306e\u3068\u3057\u3066\u6271\u3046\u3068\u3001\u5185\u90e8\u5b9f\u88c5\u306e\u5909\u66f4\u304c\u901a\u4fe1\u4ed5\u69d8\u3078\u6ce2\u53ca\u3057\u3084\u3059\u304f\u306a\u308b\u3002<\/p>\n<p>spa-reference \u306f\u3001\u3053\u306e\u5883\u754c\u3092 OpenAPI \u306b\u7f6e\u3044\u3066\u3044\u308b\u3002HTTP \u306e path\u3001method\u3001\u30b9\u30ad\u30fc\u30de\u3001status \u30b3\u30fc\u30c9\u3001Problem Details\u3001\u8a8d\u8a3c\u65b9\u5f0f\u3092 OpenAPI \u3078\u5b9a\u7fa9\u3057\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u304c\u5229\u7528\u3059\u308b API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u305d\u306e\u5951\u7d04\u304b\u3089\u751f\u6210\u3059\u308b<a href=\"#ref8\">[8]<\/a>\u3002\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c NestJS \u3067\u5b9f\u88c5\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u306f\u73fe\u5728\u306e\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308a\u3001\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u5951\u7d04\u306e\u6210\u7acb\u6761\u4ef6\u306b\u306f\u3057\u306a\u3044\u3002\u3053\u306e\u5206\u96e2\u306b\u3088\u3063\u3066\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u4e00\u90e8\u3092\u5c06\u6765 Java \u3084\u5225\u306e\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3078\u79fb\u3057\u3066\u3082\u3001\u540c\u3058 OpenAPI \u5951\u7d04\u3092\u6e80\u305f\u3059\u9650\u308a\u30d6\u30e9\u30a6\u30b6\u5074\u304b\u3089\u898b\u305f\u5883\u754c\u3092\u7dad\u6301\u3067\u304d\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5883\u754c<\/th>\n<th>\u6b63\u672c\u307e\u305f\u306f\u5224\u65ad\u4e3b\u4f53<\/th>\n<th>\u5207\u308a\u96e2\u3057\u3066\u3044\u308b\u3082\u306e<\/th>\n<th>\u5f97\u3089\u308c\u308b\u6027\u8cea<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Browser \u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e HTTP<\/td>\n<td>OpenAPI 3.1<\/td>\n<td>React \u306e\u8868\u793a\u578b\u3068 NestJS \u306e\u5185\u90e8\u30af\u30e9\u30b9\u3092\u901a\u4fe1\u4ed5\u69d8\u304b\u3089\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u5b9f\u88c5\u8a00\u8a9e\u3084\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u5909\u66f4\u3057\u3066\u3082\u3001\u516c\u958b API \u306e\u4e92\u63db\u6027\u3092\u72ec\u7acb\u3057\u3066\u5224\u65ad\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Frontend API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8<\/td>\n<td>OpenAPI \u304b\u3089\u751f\u6210\u3059\u308b\u30af\u30e9\u30a4\u30a2\u30f3\u30c8<\/td>\n<td>\u4eba\u624b\u3067\u91cd\u8907\u5b9a\u7fa9\u3057\u305f\u30ea\u30af\u30a8\u30b9\u30c8\u3068\u30ec\u30b9\u30dd\u30f3\u30b9\u578b\u3092\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u5951\u7d04\u5909\u66f4\u3068\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\u306e\u578b\u3092\u540c\u3058\u30bd\u30fc\u30b9\u304b\u3089\u540c\u671f\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u5229\u7528\u8005\u306e\u672c\u4eba\u78ba\u8a8d<\/td>\n<td>AWS \u30e2\u30fc\u30c9\u3067\u306f Cognito<\/td>\n<td>password \u3084\u8a8d\u8a3c\u30d7\u30ed\u30c8\u30b3\u30eb\u306e\u5b9f\u88c5\u3092\u696d\u52d9\u6a5f\u80fd\u304b\u3089\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306f\u691c\u8a3c\u6e08\u307f identity \u3092\u53d7\u3051\u53d6\u3063\u305f\u5f8c\u306e\u696d\u52d9\u5224\u65ad\u3078\u96c6\u4e2d\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u696d\u52d9\u4e0a\u306e\u8a8d\u53ef<\/td>\n<td>Backend \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3<\/td>\n<td>identity \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u30b0\u30eb\u30fc\u30d7\u60c5\u5831\u3068\u500b\u3005\u306e\u30ea\u30bd\u30fc\u30b9\u64cd\u4f5c\u6761\u4ef6\u3092\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u8ab0\u3067\u3042\u308b\u304b\u3068\u3001\u305d\u306e\u30ea\u30bd\u30fc\u30b9\u306b\u4f55\u3092\u5b9f\u884c\u3067\u304d\u308b\u304b\u3092\u5225\u306e\u898f\u5247\u3068\u3057\u3066\u7ba1\u7406\u3067\u304d\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>AWS \u56fa\u6709\u306e token \u691c\u8a3c<\/td>\n<td>Identity \u30a2\u30c0\u30d7\u30bf\u30fc<\/td>\n<td>JWKS\u3001Cognito \u30b0\u30eb\u30fc\u30d7\u3001\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u696d\u52d9\u6a5f\u80fd\u304b\u3089\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>Requests \u3084 Approvals \u306f\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u578b\u3067\u306f\u306a\u304f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u3068 role \u3092\u4f7f\u3048\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u73fe\u5728\u306e OpenAPI \u5951\u7d04\u306f\u3001\u6b63\u5e38\u7cfb\u306e JSON \u30b9\u30ad\u30fc\u30de\u3060\u3051\u3092\u8a18\u8ff0\u3057\u3066\u3044\u308b\u308f\u3051\u3067\u306f\u306a\u3044\u3002Request \u306e DRAFT\u3001SUBMITTED\u3001APPROVED\u3001REJECTED\u3001Requester\u3001Approver\u3001Administrator \u3068\u3044\u3046 role\u3001\u4e3b\u8981\u306a HTTP status\u3001CONCURRENCY_CONFLICT\u3001REQUEST_INVALID_STATE\u3001FORBIDDEN\u3001IDENTITY_PROVIDER_UNAVAILABLE \u306a\u3069\u306e\u5b89\u5b9a\u3057\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 error \u30b3\u30fc\u30c9\u3082\u516c\u958b\u5951\u7d04\u306b\u542b\u3081\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u5931\u6557\u3082\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u89b3\u6e2c\u3059\u308b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3067\u3042\u308b\u4ee5\u4e0a\u3001\u6210\u529f\u6642\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u3068\u540c\u3058\u3088\u3046\u306b\u5951\u7d04\u3068\u3057\u3066\u6271\u3046\u3002<\/p>\n<p>\u3055\u3089\u306b\u3001\u8907\u6570\u306e\u5931\u6557\u6761\u4ef6\u304c\u540c\u6642\u306b\u6210\u7acb\u3057\u305f\u5834\u5408\u306e\u8a55\u4fa1\u9806\u5e8f\u307e\u3067\u610f\u5473\u3092\u6301\u3064\u3002\u73fe\u5728\u306e\u8a2d\u8a08\u3067\u306f\u3001\u8a8d\u8a3c\u3001\u7c97\u3044 role \u5224\u5b9a\u3001\u69cb\u9020\u691c\u8a3c\u3001\u30ea\u30bd\u30fc\u30b9\u691c\u7d22\u3001\u30ea\u30bd\u30fc\u30b9\u5358\u4f4d\u306e\u8a8d\u53ef\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u3001\u72b6\u614b\u3068\u3044\u3046\u9806\u5e8f\u3092\u5b9a\u3081\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u305f\u3068\u3048\u3070 caller \u304c\u53e4\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u3092\u9001\u4fe1\u3057\u3001\u73fe\u5728\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u72b6\u614b\u3082\u305d\u306e\u64cd\u4f5c\u3092\u8a31\u3055\u306a\u3044\u5834\u5408\u3001\u30d0\u30fc\u30b8\u30e7\u30f3\u7af6\u5408\u3092\u5148\u306b\u8a55\u4fa1\u3059\u308b\u3053\u3068\u3067 CONCURRENCY_CONFLICT \u3092\u8fd4\u3059\u3002\u3053\u306e\u9806\u5e8f\u304c\u5b9f\u88c5\u8005\u3054\u3068\u306b\u5909\u308f\u308b\u3068\u3001\u540c\u3058\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u5bfe\u3059\u308b\u5916\u90e8\u6319\u52d5\u304c\u5909\u308f\u308b\u305f\u3081\u3001\u5185\u90e8\u51e6\u7406\u9806\u5e8f\u306e\u4e00\u90e8\u304c\u516c\u958b\u610f\u5473\u8ad6\u306b\u306a\u308b\u3002<\/p>\n<p>\u5951\u7d04\u3092 OpenAPI \u3078\u72ec\u7acb\u3055\u305b\u308b\u3053\u3068\u306b\u306f\u3001\u691c\u8a3c\u4e0a\u306e\u52b9\u679c\u3082\u3042\u308b\u3002\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c\u52d5\u4f5c\u3057\u3066\u3044\u3066\u3082 OpenAPI \u3068\u7570\u306a\u308b\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u8fd4\u305b\u3070\u5951\u7d04\u9055\u53cd\u3067\u3042\u308a\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u304c\u30b3\u30f3\u30d1\u30a4\u30eb\u3067\u304d\u3066\u3082\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u53e4\u3051\u308c\u3070\u6b63\u672c\u3068\u306e\u540c\u671f\u304c\u5d29\u308c\u3066\u3044\u308b\u3002spa-reference \u306e CI \u304c OpenAPI \u691c\u8a3c\u3068 API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8 freshness \u3092\u5225\u3005\u306b\u691c\u8a3c\u3059\u308b\u306e\u306f\u3001\u3053\u306e\u4e8c\u3064\u304c TypeScript \u306e\u578b\u691c\u67fb\u3060\u3051\u3067\u306f\u4fdd\u8a3c\u3055\u308c\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002\u8a00\u8a9e\u5185\u306e\u578b\u6574\u5408\u6027\u3068\u3001HTTP \u5883\u754c\u306e\u5951\u7d04\u6574\u5408\u6027\u3092\u5225\u306e\u691c\u67fb\u5bfe\u8c61\u3068\u3057\u3066\u6271\u3063\u3066\u3044\u308b\u3002<\/p>\n<p>\u8a8d\u8a3c\u306b\u3064\u3044\u3066\u3082\u3001\u30d6\u30e9\u30a6\u30b6\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u304b\u3089\u5207\u308a\u96e2\u3057\u305f\u30d7\u30ed\u30c8\u30b3\u30eb\u5883\u754c\u3092\u7f6e\u3044\u3066\u3044\u308b\u3002\u30d6\u30e9\u30a6\u30b6 SPA \u306f\u30d1\u30d6\u30ea\u30c3\u30af\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3067\u3042\u308a\u3001\u7b2c\u4e09\u8005\u306b\u77e5\u3089\u308c\u3066\u306f\u306a\u3089\u306a\u3044\u30af\u30e9\u30a4\u30a2\u30f3\u30c8 secret \u3092\u5b89\u5168\u306b\u4fdd\u6301\u3059\u308b\u5b9f\u884c\u74b0\u5883\u3092\u6301\u305f\u306a\u3044\u3002RFC 7636 \u306f\u8a8d\u53ef\u30b3\u30fc\u30c9 interception \u3078\u306e\u5bfe\u7b56\u3068\u3057\u3066 PKCE \u3092\u5b9a\u7fa9\u3057\u3066\u3044\u308b<a href=\"#ref16\">[16]<\/a>\u3002OAuth 2.0 Security Best Current Practice \u3067\u3042\u308b RFC 9700 \u3082\u3001\u30d1\u30d6\u30ea\u30c3\u30af\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u8a8d\u53ef\u30b3\u30fc\u30c9 grant \u3092\u5229\u7528\u3059\u308b\u5834\u5408\u306b PKCE \u3092\u7528\u3044\u308b\u3053\u3068\u3092\u8981\u6c42\u3057\u3066\u3044\u308b<a href=\"#ref17\">[17]<\/a>\u3002Amazon Cognito \u306f Authorization Code grant \u3068 PKCE \u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u65b9\u5f0f\u3092\u63d0\u4f9b\u3057\u3066\u3044\u308b<a href=\"#ref18\">[18]<\/a>\u3002<\/p>\n<p>AWS \u30e2\u30fc\u30c9\u306e SPA \u306f Cognito \u3078 Authorization Code + PKCE \u3067\u8a8d\u8a3c\u3092\u59d4\u306d\u308b\u3002\u30d6\u30e9\u30a6\u30b6\u304c\u696d\u52d9 API \u3092\u547c\u3076\u3068\u304d\u306b\u306f bearer access token \u3092\u9001\u308a\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c\u305d\u306e token \u3092\u691c\u8a3c\u3059\u308b\u3002ID token \u3092 API \u8a8d\u53ef\u306e\u8a3c\u62e0\u3068\u3057\u3066\u6d41\u7528\u3059\u308b\u69cb\u6210\u306b\u306f\u3057\u3066\u3044\u306a\u3044\u3002access token \u306e\u7f72\u540d\u3084 issuer \u306a\u3069\u3001Cognito \u304c\u767a\u884c\u3057\u305f token \u3068\u3057\u3066\u5fc5\u8981\u306a\u6761\u4ef6\u3092\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u5883\u754c\u3067\u78ba\u8a8d\u3057\u305f\u5f8c\u3001Cognito \u30b0\u30eb\u30fc\u30d7\u304b\u3089 Requester\u3001Approver\u3001Administrator \u3068\u3044\u3046\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e\u30ed\u30fc\u30eb\u3092\u5c0e\u304f<a href=\"#ref11\">[11]<\/a>\u3002<\/p>\n<p>\u3053\u3053\u3067 role \u3092\u30d6\u30e9\u30a6\u30b6\u304b\u3089\u7533\u544a\u3055\u305b\u306a\u3044\u3053\u3068\u304c\u8a8d\u53ef\u5883\u754c\u3092\u4fdd\u3064\u3002\u753b\u9762\u5074\u3067\u306f role \u306b\u5fdc\u3058\u3066 navigation \u3084 button \u3092\u8868\u793a\u3067\u304d\u308b\u304c\u3001\u305d\u306e\u8868\u793a\u5236\u5fa1\u306f\u5229\u7528\u8005\u4f53\u9a13\u306e\u305f\u3081\u306e\u3082\u306e\u3067\u3042\u308a\u3001\u696d\u52d9\u64cd\u4f5c\u3092\u8a31\u53ef\u3059\u308b\u6700\u7d42\u5224\u65ad\u306b\u306f\u306a\u3089\u306a\u3044\u3002\u5229\u7528\u8005\u304c HTTP \u30ea\u30af\u30a8\u30b9\u30c8\u3092\u76f4\u63a5\u4f5c\u6210\u3059\u308c\u3070\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u8868\u793a\u5236\u5fa1\u306f\u901a\u904e\u3067\u304d\u308b\u305f\u3081\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c\u6bce\u56de verified identity \u3068\u30ea\u30bd\u30fc\u30b9\u306e\u95a2\u4fc2\u304b\u3089\u8a8d\u53ef\u3092\u5224\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/p>\n<p>\u8a8d\u8a3c\u3068\u8a8d\u53ef\u3082\u540c\u3058\u5224\u65ad\u3068\u3057\u3066\u307e\u3068\u3081\u3066\u3044\u306a\u3044\u3002Cognito \u304c\u8a3c\u660e\u3059\u308b\u306e\u306f\u3001token \u304c\u3069\u306e identity \u306b\u5bfe\u3057\u3066\u767a\u884c\u3055\u308c\u3001\u3069\u306e\u30b0\u30eb\u30fc\u30d7\u306b\u5c5e\u3057\u3066\u3044\u308b\u304b\u3068\u3044\u3046\u60c5\u5831\u3067\u3042\u308b\u3002\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u5224\u65ad\u3059\u308b\u306e\u306f\u3001\u305d\u306e identity \u304c\u73fe\u5728\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u5bfe\u3057\u3066\u4f55\u3092\u5b9f\u884c\u3067\u304d\u308b\u304b\u3067\u3042\u308b\u3002Requester role \u3092\u6301\u3063\u3066\u3044\u3066\u3082\u3001\u5225\u306e Requester \u304c\u6240\u6709\u3059\u308b\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u81ea\u7531\u306b\u7de8\u96c6\u3067\u304d\u308b\u308f\u3051\u3067\u306f\u306a\u3044\u3002Approver role \u3092\u6301\u3063\u3066\u3044\u3066\u3082\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u304c DRAFT \u306a\u3089\u627f\u8a8d\u64cd\u4f5c\u306f\u6210\u7acb\u3057\u306a\u3044\u3002role \u306f\u8a8d\u53ef\u5224\u65ad\u306e\u5165\u529b\u306e\u4e00\u3064\u3067\u3042\u308a\u3001\u30ea\u30bd\u30fc\u30b9\u6240\u6709\u6a29\u3001current \u72b6\u614b\u3001\u64cd\u4f5c\u306a\u3069\u3068\u7d44\u307f\u5408\u308f\u305b\u3066\u6700\u7d42\u7684\u306a\u8a31\u53ef\u3092\u6c7a\u3081\u308b\u3002<\/p>\n<p>\u3053\u306e\u5206\u96e2\u306b\u3088\u3063\u3066\u3001identity \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u306e\u60c5\u5831\u304c\u696d\u52d9\u6a5f\u80fd\u3078\u5e83\u304c\u308b\u3053\u3068\u3082\u9632\u3044\u3067\u3044\u308b\u3002cognito:groups\u3001JWKS \u306e\u53d6\u5f97\u3001Cognito \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3068\u306e\u901a\u4fe1\u3068\u3044\u3063\u305f\u51e6\u7406\u306f\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u8cac\u52d9\u306b\u7f6e\u304b\u308c\u308b\u3002Requests \u3084 Approvals \u304c\u5fc5\u8981\u3068\u3059\u308b\u306e\u306f\u3001\u691c\u8a3c\u6e08\u307f\u306e subject\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e\u30ed\u30fc\u30eb\u3001\u5fc5\u8981\u306a\u5834\u5408\u306e verified email \u3068\u3044\u3063\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e identity \u3067\u3042\u308b\u3002\u696d\u52d9\u30b3\u30fc\u30c9\u304c Cognito SDK \u3084 token claim \u306e\u69cb\u9020\u3092\u76f4\u63a5\u89e3\u91c8\u3059\u308b\u5fc5\u8981\u306f\u306a\u3044\u3002<\/p>\n<p>\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u304c\u6210\u7acb\u3059\u308b\u306e\u3082\u3001\u3053\u306e\u5883\u754c\u304c\u3042\u308b\u305f\u3081\u3067\u3042\u308b\u3002\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u3067\u306f Cognito \u3078 redirect \u305b\u305a\u3001\u56fa\u5b9a\u3055\u308c\u305f\u30c7\u30e2 token \u3092\u30ed\u30fc\u30ab\u30eb\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u304c Requester\u3001Approver\u3001Administrator \u3078\u5bfe\u5fdc\u4ed8\u3051\u308b\u3002\u4e00\u65b9\u3001\u305d\u306e\u5f8c\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8a8d\u53ef\u3001HTTP \u5951\u7d04\u3001\u30ea\u30bd\u30fc\u30b9\u6240\u6709\u6a29\u3001\u72b6\u614b\u9077\u79fb\u306f AWS \u30e2\u30fc\u30c9\u3068\u540c\u3058\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u610f\u5473\u8ad6\u3092\u4f7f\u3046\u3002\u8a8d\u8a3c\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u7f6e\u304d\u63db\u3048\u3066\u3082\u696d\u52d9\u898f\u5247\u3092\u5909\u3048\u305a\u306b\u6e08\u3080\u3053\u3068\u81ea\u4f53\u304c\u3001\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u5883\u754c\u304c\u5b9f\u88c5\u4e0a\u6a5f\u80fd\u3057\u3066\u3044\u308b\u3053\u3068\u306e\u78ba\u8a8d\u306b\u306a\u308b\u3002<\/p>\n<p>OpenAPI \u3068\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u306f\u7570\u306a\u308b\u5bfe\u8c61\u3092\u6271\u3063\u3066\u3044\u308b\u304c\u3001\u8a2d\u8a08\u539f\u5247\u306f\u5171\u901a\u3057\u3066\u3044\u308b\u3002OpenAPI \u306f HTTP \u5951\u7d04\u3092 React\u3001NestJS\u3001TypeScript \u304b\u3089\u5207\u308a\u96e2\u3057\u3001\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u306f\u672c\u4eba\u78ba\u8a8d\u3092 Cognito \u56fa\u6709\u51e6\u7406\u304b\u3089\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u3078\u6f0f\u3089\u3055\u306a\u3044\u3002\u3069\u3061\u3089\u3082\u300c\u73fe\u5728\u4f7f\u3063\u3066\u3044\u308b\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3084\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u300d\u3092\u3001\u305d\u306e\u307e\u307e\u9577\u671f\u5951\u7d04\u3078\u6607\u683c\u3055\u305b\u306a\u3044\u305f\u3081\u306e\u5883\u754c\u3067\u3042\u308b\u3002<\/p>\n<p>\u3053\u306e\u69cb\u9020\u306b\u3088\u3063\u3066\u3001spa-reference \u306e\u516c\u958b\u5951\u7d04\u3068\u696d\u52d9\u898f\u5247\u306f\u3001\u73fe\u5728\u306e\u5b9f\u88c5\u6280\u8853\u3088\u308a\u9577\u3044\u5bff\u547d\u3092\u6301\u3066\u308b\u3002React\u3001NestJS\u3001Cognito \u306f\u73fe\u5728\u306e\u53c2\u7167\u57fa\u6e96\u3092\u69cb\u6210\u3059\u308b\u5177\u4f53\u7684\u306a\u9078\u629e\u3067\u3042\u308b\u3002\u4e00\u65b9\u3001\u3069\u306e HTTP \u30ea\u30af\u30a8\u30b9\u30c8\u304c\u6210\u7acb\u3057\u3001\u3069\u306e error \u304c\u8fd4\u308a\u3001\u8ab0\u304c\u3069\u306e\u30ea\u30bd\u30fc\u30b9\u3092\u64cd\u4f5c\u3067\u304d\u308b\u304b\u3068\u3044\u3046\u610f\u5473\u306f\u3001\u305d\u308c\u3089\u306e\u88fd\u54c1\u540d\u304b\u3089\u72ec\u7acb\u3057\u3066\u5b9a\u7fa9\u3055\u308c\u308b\u3002\u5b9f\u88c5\u6280\u8853\u3092\u9078\u3076\u3053\u3068\u3068\u3001\u305d\u306e\u6280\u8853\u3078\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5951\u7d04\u3092\u5f93\u5c5e\u3055\u305b\u308b\u3053\u3068\u3092\u5206\u3051\u308b\u70b9\u304c\u3001\u3053\u306e\u8a8d\u8a3c\u3068 API \u8a2d\u8a08\u306e\u4e2d\u5fc3\u306b\u3042\u308b\u3002<\/p>\n<hr>\n<h2>7. \u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30fc\u30b9\u30c8\u306f\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3092\u691c\u67fb\u3059\u308b<\/h2>\n<p>spa-reference \u306e\u6700\u521d\u306e\u5b9f\u884c\u7d4c\u8def\u306f AWS \u30c7\u30d7\u30ed\u30a4\u3067\u306f\u306a\u304f\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u3067\u3042\u308b\u3002clone\u3001\u30ea\u30dd\u30b8\u30c8\u30ea\u4f9d\u5b58\u95a2\u4fc2\u306e\u5c0e\u5165\u3001\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u306e\u8d77\u52d5\u3001\u30d6\u30e9\u30a6\u30b6\u3067\u4ee3\u8868\u7684\u306a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u64cd\u4f5c\u3001\u6210\u529f\u78ba\u8a8d\u3068\u3044\u3046\u9806\u5e8f\u3067\u9032\u307f\u3001\u5b9f\u884c\u6642\u306b\u306f AWS \u30a2\u30ab\u30a6\u30f3\u30c8\u3001AWS \u8a8d\u8a3c\u60c5\u5831\u3001Cognito\u3001S3\u3001SES\u3001SNS\u3001API key\u3001\u624b\u4f5c\u696d\u3067\u7528\u610f\u3057\u305f\u74b0\u5883\u5909\u6570\u30d5\u30a1\u30a4\u30eb\u3092\u8981\u6c42\u3057\u306a\u3044<a href=\"#ref2\">[2]<\/a>\u3002\u6700\u521d\u306b\u78ba\u8a8d\u3059\u308b\u5bfe\u8c61\u3092\u30af\u30e9\u30a6\u30c9\u69cb\u7bc9\u3067\u306f\u306a\u304f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u305d\u306e\u3082\u306e\u3078\u7f6e\u304f\u3053\u3068\u3067\u3001\u696d\u52d9\u6a5f\u80fd\u3068 AWS \u56fa\u6709\u69cb\u6210\u3092\u5225\u3005\u306b\u8a55\u4fa1\u3067\u304d\u308b\u3002<\/p>\n<p>\u3053\u3053\u3067\u3044\u3046\u30ed\u30fc\u30ab\u30eb\u306f\u3001\u5b8c\u5168\u306a\u30aa\u30d5\u30e9\u30a4\u30f3\u5b9f\u884c\u3092\u610f\u5473\u3057\u306a\u3044\u3002\u6700\u521d\u306e git clone\u3001npm ci\u3001PostgreSQL \u30b3\u30f3\u30c6\u30ca\u30a4\u30e1\u30fc\u30b8\u306e\u53d6\u5f97\u306b\u306f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304c\u5fc5\u8981\u306b\u306a\u308b\u3002\u3053\u308c\u3089\u306f\u5b9f\u884c\u74b0\u5883\u3092\u53d6\u5f97\u3059\u308b\u305f\u3081\u306e\u4f9d\u5b58\u95a2\u4fc2\u53d6\u5f97\u3067\u3042\u308a\u3001\u8d77\u52d5\u5f8c\u306e\u696d\u52d9\u51e6\u7406\u304c\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u3078\u4f9d\u5b58\u3059\u308b\u3053\u3068\u3068\u306f\u6027\u8cea\u304c\u7570\u306a\u308b\u3002\u5fc5\u8981\u306a artifact \u304c\u63c3\u3063\u305f\u5f8c\u306f\u3001\u4e00\u53f0\u306e\u958b\u767a\u6a5f\u4e0a\u3067 SPA\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001PostgreSQL\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u4fdd\u5b58\u3001\u30e1\u30fc\u30eb\u8a18\u9332\u3001\u30a4\u30d9\u30f3\u30c8\u8a18\u9332\u307e\u3067\u5b8c\u7d50\u3059\u308b\u3002\u3053\u306e\u533a\u5225\u306b\u3088\u3063\u3066\u3001\u300c\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4e00\u5ea6\u4f7f\u3046\u3053\u3068\u300d\u3068\u300c\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5b9f\u884c\u6642\u304c\u5916\u90e8\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u53ef\u7528\u6027\u3078\u4f9d\u5b58\u3059\u308b\u3053\u3068\u300d\u3092\u6df7\u540c\u305b\u305a\u306b\u6e08\u3080\u3002<\/p>\n<p>\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3068 AWS \u30e2\u30fc\u30c9\u306e\u5dee\u306f\u3001\u5916\u90e8\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u3078\u9650\u5b9a\u3055\u308c\u3066\u3044\u308b\u3002Cognito \u306e\u4ee3\u308f\u308a\u306b\u56fa\u5b9a\u3055\u308c\u305f\u30c7\u30e2 identity\u3001S3 \u306e\u4ee3\u308f\u308a\u306b\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u4fdd\u5b58\u3001SES \u3068 SNS \u306e\u4ee3\u308f\u308a\u306b\u30ed\u30fc\u30ab\u30eb\u914d\u9001\u8a18\u9332\u3092\u4f7f\u3046\u3002\u4e00\u65b9\u3001\u30c9\u30e1\u30a4\u30f3\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30ed\u30b8\u30c3\u30af\u3001HTTP API\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30e2\u30c7\u30eb\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u8a8d\u53ef\u3001transactional outbox \u306f\u5171\u901a\u3067\u3042\u308b<a href=\"#ref8\">[8]<\/a>\u3002APP_MODE \u306f\u30d7\u30ed\u30bb\u30b9\u8d77\u52d5\u6642\u306b\u30a2\u30c0\u30d7\u30bf\u30fc set \u3092\u9078\u3073\u3001\u305d\u306e\u5f8c\u306e\u696d\u52d9\u30b3\u30fc\u30c9\u304c\u51e6\u7406\u3054\u3068\u306b AWS \u304b\u30ed\u30fc\u30ab\u30eb\u304b\u3092\u5224\u65ad\u3059\u308b\u69cb\u9020\u306b\u306f\u3057\u3066\u3044\u306a\u3044\u3002<\/p>\n<p>\u3053\u306e\u69cb\u6210\u3067\u306f\u3001\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u304c\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u5883\u754c\u306e\u691c\u67fb\u3068\u3057\u3066\u6a5f\u80fd\u3059\u308b\u3002\u3082\u3057 Requests \u6a5f\u80fd\u304c Cognito SDK \u3092\u76f4\u63a5\u547c\u3073\u3001Attachments \u304c S3 \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u578b\u3092\u30c9\u30e1\u30a4\u30f3\u30e2\u30c7\u30eb\u306b\u4fdd\u6301\u3057\u3001Approval \u51e6\u7406\u304c SNS \u3078\u76f4\u63a5\u767a\u884c\u3057\u3066\u3044\u308c\u3070\u3001AWS \u3092\u5916\u3057\u305f\u6642\u70b9\u3067\u696d\u52d9\u30ed\u30b8\u30c3\u30af\u305d\u306e\u3082\u306e\u3092\u66f8\u304d\u63db\u3048\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002\u73fe\u5728\u306e\u5b9f\u88c5\u3067\u306f\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u51e6\u7406\u3092\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u5185\u5074\u3078\u9589\u3058\u8fbc\u3081\u3066\u3044\u308b\u305f\u3081\u3001AWS \u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u30ed\u30fc\u30ab\u30eb\u30a2\u30c0\u30d7\u30bf\u30fc\u3078\u4ea4\u63db\u3057\u3066\u3082\u3001\u7533\u8acb\u4f5c\u6210\u3001\u63d0\u51fa\u3001\u627f\u8a8d\u3001\u5374\u4e0b\u3001\u8a8d\u53ef\u3001\u76e3\u67fb\u3001outbox \u3068\u3044\u3046\u696d\u52d9\u610f\u5473\u8ad6\u3092\u7dad\u6301\u3067\u304d\u308b\u3002<\/p>\n<p>\u9006\u306b\u3001\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3092\u6210\u7acb\u3055\u305b\u308b\u305f\u3081\u306b\u696d\u52d9\u30b3\u30fc\u30c9\u3078\u591a\u6570\u306e\u6761\u4ef6\u5206\u5c90\u304c\u5fc5\u8981\u306b\u306a\u308c\u3070\u3001\u305d\u308c\u306f\u30ed\u30fc\u30ab\u30eb\u5bfe\u5fdc\u306e\u554f\u984c\u3068\u3044\u3046\u3088\u308a\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5883\u754c\u304c\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5c64\u3078\u6f0f\u308c\u3066\u3044\u308b\u5146\u5019\u306b\u306a\u308b\u3002\u305f\u3068\u3048\u3070\u696d\u52d9\u30b5\u30fc\u30d3\u30b9\u5185\u306b\u300cAPP_MODE \u304c\u30ed\u30fc\u30ab\u30eb\u306a\u3089\u30d5\u30a1\u30a4\u30eb\u3078\u66f8\u304d\u3001aws \u306a\u3089 S3 \u3078\u9001\u308b\u300d\u3068\u3044\u3046\u5206\u5c90\u304c\u73fe\u308c\u308c\u3070\u3001\u696d\u52d9\u30b5\u30fc\u30d3\u30b9\u81ea\u8eab\u304c\u30b9\u30c8\u30ec\u30fc\u30b8\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u77e5\u3063\u3066\u3044\u308b\u3053\u3068\u306b\u306a\u308b\u3002\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u9078\u629e\u3092 bootstrap \u306b\u9589\u3058\u8fbc\u3081\u308c\u3070\u3001\u696d\u52d9\u51e6\u7406\u306f\u300c\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b9\u30c8\u30ec\u30fc\u30b8\u3078\u4fdd\u5b58\u3059\u308b\u300d\u3068\u3044\u3046\u8cac\u52d9\u3060\u3051\u3092\u77e5\u308a\u3001\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u9055\u3044\u3092\u610f\u8b58\u3057\u306a\u304f\u3066\u6e08\u3080\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u8cac\u52d9<\/th>\n<th>\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9<\/th>\n<th>AWS \u30e2\u30fc\u30c9<\/th>\n<th>\u5171\u901a\u3057\u3066\u7dad\u6301\u3059\u308b\u610f\u5473<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Identity<\/td>\n<td>\u56fa\u5b9a\u30c7\u30e2 token \u3092\u30ed\u30fc\u30ab\u30eb\u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u304c Requester\u3001Approver\u3001Administrator \u3078\u5909\u63db\u3059\u308b\u3002<\/td>\n<td>Cognito access token \u3092\u691c\u8a3c\u3057\u3001\u30b0\u30eb\u30fc\u30d7\u304b\u3089\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4e0a\u306e\u30ed\u30fc\u30eb\u3092\u5c0e\u304f\u3002<\/td>\n<td>\u696d\u52d9\u6a5f\u80fd\u306f\u691c\u8a3c\u6e08\u307f identity \u3068\u30ed\u30fc\u30eb\u3092\u53d7\u3051\u53d6\u308a\u3001\u30ea\u30bd\u30fc\u30b9\u5358\u4f4d\u306e\u8a8d\u53ef\u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3067\u5224\u5b9a\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u95a2\u4fc2\u30c7\u30fc\u30bf<\/td>\n<td>Docker Compose \u4e0a\u306e PostgreSQL 17 \u3092\u4f7f\u3046\u3002<\/td>\n<td>Aurora PostgreSQL-compatible \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f7f\u3046\u3002<\/td>\n<td>\u30b9\u30ad\u30fc\u30de\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001transaction\u3001\u884c\u30ed\u30c3\u30af\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001outbox \u306e\u610f\u5473\u3092\u5171\u6709\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u672c\u4f53<\/td>\n<td>\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u578b\u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u4f7f\u3046\u3002<\/td>\n<td>S3 \u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u4f7f\u3046\u3002<\/td>\n<td>\u696d\u52d9\u30b3\u30fc\u30c9\u306f\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b9\u30c8\u30ec\u30fc\u30b8\u5883\u754c\u3092\u901a\u3058\u3066\u4fdd\u5b58\u3057\u3001\u4e00\u89a7\u3001\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3001\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u306e\u8a8d\u53ef\u898f\u5247\u3092\u5171\u6709\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u30e1\u30fc\u30eb<\/td>\n<td>\u914d\u9001\u5185\u5bb9\u3092\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u3078\u8a18\u9332\u3059\u308b\u3002<\/td>\n<td>SES \u3078\u914d\u9001\u3059\u308b\u3002<\/td>\n<td>outbox \u304b\u3089 commit \u5f8c\u306b\u914d\u9001\u3057\u3001\u696d\u52d9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u5916\u90e8\u526f\u4f5c\u7528\u3092\u5206\u96e2\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u30a4\u30d9\u30f3\u30c8\u516c\u958b<\/td>\n<td>\u30a4\u30d9\u30f3\u30c8\u3092\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30a4\u30eb\u3078\u8a18\u9332\u3059\u308b\u3002<\/td>\n<td>SNS \u3078\u767a\u884c\u3059\u308b\u3002<\/td>\n<td>\u540c\u3058 outbox \u30a4\u30d9\u30f3\u30c8\u30da\u30a4\u30ed\u30fc\u30c9\u3068\u914d\u9001\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u3092\u4f7f\u3046\u3002<\/td>\n<\/tr>\n<tr>\n<td>HTTP API<\/td>\n<td>Vite \u304c \/api \u3092\u30ed\u30fc\u30ab\u30eb\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3078\u30d7\u30ed\u30ad\u30b7\u3059\u308b\u3002<\/td>\n<td>ALB \u304c \/api\/* \u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30b5\u30fc\u30d3\u30b9\u3078\u632f\u308a\u5206\u3051\u308b\u3002<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6\u5411\u3051 OpenAPI \u5951\u7d04\u3068\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u306e\u610f\u5473\u8ad6\u3092\u5171\u6709\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3060\u3051\u306f\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3067\u3082 PostgreSQL \u3092\u305d\u306e\u307e\u307e\u4f7f\u3046\u3002\u3053\u3053\u3067 SQLite \u3084\u30e1\u30e2\u30ea\u5185 DB \u3078\u7f6e\u304d\u63db\u3048\u308b\u3068\u3001\u8d77\u52d5\u306f\u8efd\u304f\u3067\u304d\u3066\u3082\u3001\u53c2\u7167\u5b9f\u88c5\u3068\u3057\u3066\u78ba\u8a8d\u3057\u305f\u3044\u6027\u8cea\u304c\u5909\u308f\u308b\u3002spa-reference \u306f READ COMMITTED\u3001\u884c\u30ed\u30c3\u30af\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001transactional outbox \u3068\u3044\u3063\u305f PostgreSQL \u306e\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u610f\u5473\u8ad6\u3092\u8a2d\u8a08\u306b\u5229\u7528\u3057\u3066\u3044\u308b<a href=\"#ref11\">[11]<\/a>\u3002\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u3067\u3082 PostgreSQL \u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u753b\u9762\u3060\u3051\u52d5\u304f\u7c21\u6613\u30c7\u30e2\u3067\u306f\u306a\u304f\u3001\u672c\u756a\u5074\u3068\u540c\u3058\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30e2\u30c7\u30eb\u3068 concurrency \u610f\u5473\u8ad6\u3092\u5b9f\u969b\u306b\u901a\u305b\u308b\u3002<\/p>\n<p>PostgreSQL 17 \u306f Docker Compose \u3067\u8d77\u52d5\u3059\u308b\u3002Docker Compose \u306f\u8907\u6570\u306e\u30b5\u30fc\u30d3\u30b9\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3001volume \u306a\u3069\u3092\u69cb\u6210\u3068\u3057\u3066\u5b9a\u7fa9\u3057\u3001\u540c\u3058\u6761\u4ef6\u3067\u8d77\u52d5\u3059\u308b\u4ed5\u7d44\u307f\u3092\u63d0\u4f9b\u3059\u308b<a href=\"#ref19\">[19]<\/a>\u3002\u73fe\u5728\u306e compose.yaml \u306f PostgreSQL 17 \u3092\u4f7f\u3044\u3001\u30b3\u30f3\u30c6\u30ca\u5074\u306e 5432 \u3092\u30db\u30b9\u30c8\u306e 127.0.0.1:55432 \u3078\u516c\u958b\u3057\u3001\u6c38\u7d9a volume \u3068\u30d8\u30eb\u30b9\u30c1\u30a7\u30c3\u30af\u3092\u5b9a\u7fa9\u3057\u3066\u3044\u308b<a href=\"#ref20\">[20]<\/a>\u3002\u5229\u7528\u8005\u306e OS \u306b PostgreSQL \u672c\u4f53\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3001user\u3001\u30dd\u30fc\u30c8\u3001data directory \u3092\u500b\u5225\u8a2d\u5b9a\u3055\u305b\u308b\u4ee3\u308f\u308a\u306b\u3001\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u304c\u5fc5\u8981\u3068\u3059\u308b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u6761\u4ef6\u3060\u3051\u3092\u30ea\u30dd\u30b8\u30c8\u30ea\u5074\u3067\u56fa\u5b9a\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u4e00\u65b9\u3001React \u3068 NestJS \u307e\u3067 Docker Compose \u306e\u4e2d\u3078\u5165\u308c\u3066\u958b\u767a\u3059\u308b\u69cb\u6210\u306b\u306f\u3057\u3066\u3044\u306a\u3044\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u30db\u30b9\u30c8\u4e0a\u306e Node.js \u30d7\u30ed\u30bb\u30b9\u3068\u3057\u3066\u8d77\u52d5\u3057\u3001\u5916\u90e8\u4f9d\u5b58\u3067\u3042\u308b PostgreSQL \u3060\u3051\u3092\u30b3\u30f3\u30c6\u30ca\u5316\u3059\u308b\u3002\u3059\u3079\u3066\u3092\u30b3\u30f3\u30c6\u30ca\u5316\u3059\u308c\u3070\u30d7\u30ed\u30bb\u30b9\u8d77\u52d5\u6761\u4ef6\u3092\u7d71\u4e00\u3067\u304d\u308b\u53cd\u9762\u3001\u30bd\u30fc\u30b9 change \u306e\u53cd\u6620\u3001debug\u3001\u30dd\u30fc\u30c8\u30de\u30c3\u30d4\u30f3\u30b0\u3001volume\u3001\u30b3\u30f3\u30c6\u30ca\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u306a\u3069\u3001\u901a\u5e38\u306e Node.js \u958b\u767a\u306b\u306f\u4e0d\u8981\u306a\u5c64\u307e\u3067\u65e5\u5e38\u306e\u958b\u767a\u7d4c\u8def\u3078\u5165\u308b\u3002spa-reference \u3067\u306f\u3001\u518d\u73fe\u6027\u3092\u5f97\u305f\u3044\u5bfe\u8c61\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u9650\u5b9a\u3057\u3001\u305d\u308c\u4ee5\u5916\u306f\u901a\u5e38\u306e Node.js toolchain \u3092\u76f4\u63a5\u4f7f\u3046\u3002<\/p>\n<p>\u3053\u306e\u5224\u65ad\u306e\u76ee\u7684\u306f\u3001\u56fa\u5b9a\u3059\u3079\u304d\u6761\u4ef6\u3068\u3001\u958b\u767a\u8005\u304c\u76f4\u63a5\u6271\u3063\u305f\u65b9\u304c\u5358\u7d14\u306a\u6761\u4ef6\u3092\u5206\u3051\u308b\u3053\u3068\u306b\u3042\u308b\u3002PostgreSQL \u306f\u30d0\u30fc\u30b8\u30e7\u30f3\u3001\u521d\u671f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3001\u30dd\u30fc\u30c8\u3001\u30d8\u30eb\u30b9\u30c1\u30a7\u30c3\u30af\u3092\u63c3\u3048\u308b\u610f\u5473\u304c\u5927\u304d\u3044\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f package-lock.json\u3001Node.js \u30d0\u30fc\u30b8\u30e7\u30f3\u3001npm workspace \u306b\u3088\u3063\u3066\u4f9d\u5b58\u95a2\u4fc2\u3092\u56fa\u5b9a\u3067\u304d\u308b\u305f\u3081\u3001\u3055\u3089\u306b\u30b3\u30f3\u30c6\u30ca\u5b9f\u884c\u74b0\u5883\u3092\u631f\u3080\u5fc5\u7136\u6027\u304c\u4f4e\u3044\u3002\u540c\u3058\u518d\u73fe\u6027\u3068\u3044\u3046\u76ee\u7684\u3067\u3082\u3001\u8cac\u52d9\u3054\u3068\u306b\u5fc5\u8981\u306a\u4ed5\u7d44\u307f\u3092\u9078\u3093\u3067\u3044\u308b\u3002<\/p>\n<p>\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u306e\u8d77\u52d5\u81ea\u4f53\u3082\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u691c\u8a3c\u306e\u4e00\u90e8\u306b\u306a\u3063\u3066\u3044\u308b\u3002npm run \u30c7\u30e2\u306f Node.js\u3001Docker CLI\u3001Docker Compose v2\u3001Docker daemon \u3078\u306e\u30a2\u30af\u30bb\u30b9\u3001\u5229\u7528\u3059\u308b loopback \u30dd\u30fc\u30c8\u3092\u4e8b\u524d\u306b\u78ba\u8a8d\u3057\u3001PostgreSQL \u304c\u6b63\u5e38\u306b\u306a\u308b\u307e\u3067\u5f85\u3061\u3001Prisma \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u751f\u6210\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u884c\u3057\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3092\u8d77\u52d5\u3057\u305f\u5f8c\u3001\u305d\u308c\u305e\u308c\u306e\u5fdc\u7b54\u3092\u78ba\u8a8d\u3057\u3066\u304b\u3089 ready message \u3092\u51fa\u3059\u3002\u5358\u306b\u30d7\u30ed\u30bb\u30b9\u3092 spawn \u3067\u304d\u305f\u6642\u70b9\u3067\u306f\u6210\u529f\u3068\u305b\u305a\u3001\u30d6\u30e9\u30a6\u30b6\u304b\u3089\u64cd\u4f5c\u3092\u958b\u59cb\u3067\u304d\u308b\u72b6\u614b\u307e\u3067\u5230\u9054\u3057\u305f\u3053\u3068\u3092\u8d77\u52d5\u6210\u529f\u306e\u6761\u4ef6\u306b\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u5f85\u53d7\u5148\u3082\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u3067\u306f loopback \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306b\u9650\u5b9a\u3055\u308c\u308b\u3002\u958b\u767a\u6a5f\u4e0a\u3067\u8a66\u3059\u305f\u3081\u306e\u56fa\u5b9a\u30c7\u30e2 identity \u3068\u3001\u8a8d\u8a3c\u3092\u7701\u7565\u3057\u305f\u30ed\u30fc\u30ab\u30eb\u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u6301\u3064\u4ee5\u4e0a\u3001LAN \u4e0a\u3078\u516c\u958b\u3059\u308b\u5fc5\u8981\u306f\u306a\u3044\u3002\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30fc\u30b9\u30c8\u306f\u3001\u4e00\u4eba\u306e\u958b\u767a\u8005\u304c\u5b89\u5168\u306b\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3068\u4ee3\u8868\u7684\u306a\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u691c\u8a3c\u3059\u308b\u305f\u3081\u306e\u5b9f\u884c\u7d4c\u8def\u3068\u3057\u3066\u8a2d\u8a08\u3055\u308c\u3066\u3044\u308b\u3002<\/p>\n<p>\u30af\u30e9\u30a6\u30c9\u30a8\u30df\u30e5\u30ec\u30fc\u30bf\u30fc\u3092\u4e38\u3054\u3068\u5c0e\u5165\u3057\u3066\u3044\u306a\u3044\u3053\u3068\u3082\u540c\u3058\u5224\u65ad\u304b\u3089\u8aac\u660e\u3067\u304d\u308b\u3002Cognito\u3001S3\u3001SES\u3001SNS \u306e API \u3092\u30ed\u30fc\u30ab\u30eb\u3067\u6a21\u5023\u3059\u308b\u74b0\u5883\u3092\u8ffd\u52a0\u3059\u308c\u3070\u3001AWS \u30e2\u30fc\u30c9\u3068\u4f3c\u305f API \u547c\u3073\u51fa\u3057\u3092\u5b9f\u884c\u3067\u304d\u308b\u4e00\u65b9\u3001\u305d\u306e emulator \u81ea\u4f53\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3001\u8a2d\u5b9a\u3001\u5bfe\u5fdc API\u3001\u8d77\u52d5\u9806\u5e8f\u3001\u6c38\u7d9a\u72b6\u614b\u3092\u7ba1\u7406\u3059\u308b\u5fc5\u8981\u304c\u751f\u3058\u308b\u3002\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u306e\u76ee\u7684\u304c AWS API \u306e\u4e92\u63db\u6027\u8a66\u9a13\u306a\u3089\u610f\u5473\u304c\u3042\u308b\u304c\u3001spa-reference \u304c\u6700\u521d\u306e\u5b9f\u884c\u7d4c\u8def\u3067\u78ba\u8a8d\u3057\u305f\u3044\u306e\u306f\u3001\u696d\u52d9\u30ed\u30b8\u30c3\u30af\u3001HTTP \u5951\u7d04\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u610f\u5473\u8ad6\u3001\u8a8d\u53ef\u3001outbox \u304c\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u304b\u3089\u72ec\u7acb\u3057\u3066\u6210\u7acb\u3059\u308b\u3053\u3068\u3067\u3042\u308b\u3002<\/p>\n<p>\u305d\u306e\u305f\u3081\u3001AWS \u306e\u5f62\u3092\u30ed\u30fc\u30ab\u30eb\u3078\u8907\u88fd\u3059\u308b\u306e\u3067\u306f\u306a\u304f\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u5fc5\u8981\u3068\u3059\u308b\u30dd\u30fc\u30c8\u306b\u5bfe\u3057\u3066\u6700\u5c0f\u306e\u30ed\u30fc\u30ab\u30eb\u30a2\u30c0\u30d7\u30bf\u30fc\u3092\u5b9f\u88c5\u3059\u308b\u3002\u30e1\u30fc\u30eb\u306a\u3089\u9001\u4fe1\u7d50\u679c\u3092\u8a18\u9332\u3057\u3001\u30a4\u30d9\u30f3\u30c8\u306a\u3089\u767a\u884c\u5185\u5bb9\u3092\u8a18\u9332\u3057\u3001\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u306a\u3089\u30ed\u30fc\u30ab\u30eb data area \u3078\u4fdd\u5b58\u3059\u308b\u3002\u3053\u306e\u65b9\u6cd5\u3067\u306f\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc API \u306e\u518d\u73fe\u6027\u306f\u691c\u8a3c\u5bfe\u8c61\u304b\u3089\u5916\u308c\u308b\u304c\u3001\u696d\u52d9\u64cd\u4f5c\u304c\u3069\u306e\u526f\u4f5c\u7528\u3092\u8981\u6c42\u3057\u305f\u304b\u306f\u89b3\u6e2c\u3067\u304d\u308b\u3002\u30ed\u30fc\u30ab\u30eb\u30e2\u30fc\u30c9\u304c\u4fdd\u8a3c\u3059\u308b\u7bc4\u56f2\u3092\u660e\u78ba\u306b\u3057\u3001\u305d\u306e\u7bc4\u56f2\u306b\u5fc5\u8981\u306a\u4ed5\u7d44\u307f\u3060\u3051\u3092\u6301\u3064\u69cb\u6210\u3067\u3042\u308b\u3002<\/p>\n<p>\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30fc\u30b9\u30c8\u306e\u4fa1\u5024\u306f\u3001\u8d77\u52d5\u304c\u7c21\u5358\u3068\u3044\u3046\u5229\u7528\u8005\u4f53\u9a13\u3068\u3001\u5883\u754c\u304c\u6b63\u3057\u304f\u5207\u308c\u3066\u3044\u308b\u304b\u3068\u3044\u3046\u8a2d\u8a08\u691c\u67fb\u304c\u540c\u3058\u4ed5\u7d44\u307f\u3067\u6210\u7acb\u3059\u308b\u70b9\u306b\u3042\u308b\u3002AWS \u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u7528\u610f\u3057\u306a\u304f\u3066\u3082\u4ee3\u8868\u7684\u306a\u696d\u52d9\u30d5\u30ed\u30fc\u3092\u6700\u5f8c\u307e\u3067\u5b9f\u884c\u3067\u304d\u3001\u305d\u306e\u904e\u7a0b\u3067\u672c\u756a\u3068\u540c\u3058 HTTP\u3001\u8a8d\u53ef\u3001\u72b6\u614b\u9077\u79fb\u3001PostgreSQL transaction\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001outbox \u3092\u901a\u308b\u3002\u30af\u30e9\u30a6\u30c9\u56fa\u6709\u306e\u90e8\u5206\u3060\u3051\u3092\u30a2\u30c0\u30d7\u30bf\u30fc\u3068\u3057\u3066\u4ea4\u63db\u3067\u304d\u308b\u306a\u3089\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u304c\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306e\u5177\u4f53\u7684\u306a API \u304b\u3089\u72ec\u7acb\u3057\u3066\u3044\u308b\u3053\u3068\u3092\u5b9f\u884c\u7d50\u679c\u3068\u3057\u3066\u78ba\u8a8d\u3067\u304d\u308b\u3002<\/p>\n<p>\u3053\u306e\u610f\u5473\u3067\u30ed\u30fc\u30ab\u30eb\u30d5\u30a1\u30fc\u30b9\u30c8\u306f\u3001\u3069\u306e\u51e6\u7406\u304c\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u672c\u8cea\u3067\u3001\u3069\u306e\u51e6\u7406\u304c\u30c7\u30d7\u30ed\u30a4\u74b0\u5883\u306b\u5c5e\u3059\u308b\u304b\u3092\u53ef\u8996\u5316\u3059\u308b\u8a66\u9a13\u88c5\u7f6e\u3067\u3042\u308b\u3002\u30ed\u30fc\u30ab\u30eb\u3067\u7f6e\u304d\u63db\u3048\u3089\u308c\u308b\u3082\u306e\u3068\u3001\u540c\u3058\u610f\u5473\u3092\u7dad\u6301\u3059\u308b\u305f\u3081\u306b\u7f6e\u304d\u63db\u3048\u3066\u306f\u3044\u3051\u306a\u3044\u3082\u306e\u3092\u5206\u3051\u308b\u3053\u3068\u3067\u3001spa-reference \u306e\u8cac\u52d9\u5883\u754c\u305d\u306e\u3082\u306e\u3092\u5b9f\u884c\u53ef\u80fd\u306a\u5f62\u3067\u691c\u8a3c\u3057\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>8. \u6280\u8853\u30b9\u30bf\u30c3\u30af\u306f\u8981\u4ef6\u3068\u5224\u65ad\u306e\u5bfe\u5fdc\u8868\u3068\u3057\u3066\u8aad\u3080<\/h2>\n<p>\u73fe\u5728\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306f Node.js 24 \u3068 npm workspaces \u3092\u57fa\u76e4\u306b\u3057\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u518d\u5229\u7528 UI\u3001OpenAPI \u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u4e00\u3064\u306e\u30e2\u30ce\u30ec\u30dd\u3068\u3057\u3066\u7ba1\u7406\u3059\u308b<a href=\"#ref21\">[21]<\/a>\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306f React 19.3 \u7cfb\u3001React Router 8.4 \u7cfb\u3001Vite 8.3 \u7cfb\u3001TypeScript 5.9.3\u3001Vitest 5 \u7cfb\u3092\u5ba3\u8a00\u3057\u3066\u3044\u308b<a href=\"#ref22\">[22]<\/a>\u3002\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f NestJS 12.1 \u7cfb\u3001Prisma 7.10.0\u3001PostgreSQL driver\u3001AWS SDK v3\u3001jose\u3001pino\u3001zod\u3001Vitest 5 \u7cfb\u306a\u3069\u3092\u5ba3\u8a00\u3057\u3066\u3044\u308b<a href=\"#ref23\">[23]<\/a>\u3002\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u306f AWS CDK v2 \u3068 constructs \u3092\u4f7f\u3046<a href=\"#ref24\">[24]<\/a>\u3002<\/p>\n<p>\u3053\u306e\u4e00\u89a7\u3060\u3051\u306a\u3089\u3001\u4e00\u822c\u7684\u306a\u30d5\u30eb\u30b9\u30bf\u30c3\u30af Web \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u6280\u8853\u7d39\u4ecb\u3067\u7d42\u308f\u308b\u3002\u8a2d\u8a08\u4e0a\u898b\u308b\u3079\u304d\u306a\u306e\u306f\u3001\u5404\u6280\u8853\u304c\u3069\u306e\u8981\u4ef6\u3092\u5f15\u304d\u53d7\u3051\u3001\u305d\u306e\u9078\u629e\u304c\u3069\u306e\u7a0b\u5ea6\u307e\u3067\u8981\u4ef6\u304b\u3089\u62d8\u675f\u3055\u308c\u3066\u3044\u308b\u304b\u3067\u3042\u308b\u3002PostgreSQL \u306e\u3088\u3046\u306b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3001\u4e00\u8cab\u6027\u3001\u884c\u30ed\u30c3\u30af\u3068\u3044\u3046\u8981\u6c42\u304b\u3089\u5f37\u304f\u65b9\u5411\u4ed8\u3051\u3089\u308c\u308b\u3082\u306e\u3082\u3042\u308c\u3070\u3001React \u3084 NestJS \u306e\u3088\u3046\u306b\u8907\u6570\u306e\u59a5\u5f53\u306a\u5019\u88dc\u304b\u3089\u53c2\u7167\u5b9f\u88c5\u306e\u57fa\u6e96\u3068\u3057\u3066\u4e00\u3064\u3092\u63a1\u7528\u3057\u305f\u3082\u306e\u3082\u3042\u308b\u3002\u3055\u3089\u306b Vite\u3001Vitest\u3001Redocly CLI \u306e\u3088\u3046\u306b\u3001\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u305d\u306e\u3082\u306e\u3088\u308a\u3001\u305d\u306e\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3092\u5b9f\u88c5\u3001\u691c\u8a3c\u3059\u308b\u305f\u3081\u306e\u9053\u5177\u3068\u3057\u3066\u9078\u3070\u308c\u305f\u6280\u8853\u3082\u3042\u308b\u3002<\/p>\n<p>\u3053\u306e\u4e09\u7a2e\u985e\u3092\u533a\u5225\u3059\u308b\u3068\u3001\u300c\u3053\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u63a1\u7528\u3057\u3066\u3044\u308b\u300d\u3068\u3044\u3046\u4e8b\u5b9f\u3092\u3001\u305d\u306e\u9078\u629e\u304c\u6210\u7acb\u3059\u308b\u6761\u4ef6\u3068\u7d50\u3073\u4ed8\u3051\u3066\u8aad\u3081\u308b\u3002spa-reference \u306e reference \u3068\u3044\u3046\u4f4d\u7f6e\u4ed8\u3051\u306f\u3001\u63a1\u7528\u4e8b\u5b9f\u306e\u4e00\u822c\u5316\u3092\u6291\u3048\u3001\u8981\u4ef6\u304b\u3089\u5f37\u304f\u5c0e\u304b\u308c\u308b\u5224\u65ad\u3001\u8907\u6570\u5019\u88dc\u304b\u3089\u63a1\u7528\u3057\u305f\u57fa\u6e96\u5b9f\u88c5\u3001\u5185\u90e8\u3092\u5177\u4f53\u5316\u3059\u308b\u5b9f\u88c5\u6280\u8853\u3092\u5206\u3051\u308b\u3002\u5225\u6848\u4ef6\u3067\u4f55\u3092\u7dad\u6301\u3057\u3001\u4f55\u3092\u7f6e\u304d\u63db\u3048\u308b\u304b\u306f\u3001\u3053\u306e\u533a\u5206\u304b\u3089\u5224\u65ad\u3067\u304d\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6280\u8853\u30fb\u65b9\u5f0f<\/th>\n<th>\u73fe\u5728\u306e\u5f79\u5272<\/th>\n<th>\u5224\u65ad\u6839\u62e0<\/th>\n<th>\u9078\u629e\u306e\u6027\u8cea<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Node.js 24<\/td>\n<td>workspaces \u5168\u4f53\u306e\u5b9f\u884c\u57fa\u76e4\u3092\u7d71\u4e00\u3059\u308b\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u958b\u767a\u30c4\u30fc\u30eb\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u88dc\u52a9\u30b9\u30af\u30ea\u30d7\u30c8\u3001CDK \u3092\u540c\u3058 JavaScript \/ TypeScript \u306e\u9053\u5177\u7acb\u3066\u3067\u6271\u3048\u308b\u3002<\/td>\n<td>\u30ea\u30dd\u30b8\u30c8\u30ea\u57fa\u6e96\u3068\u3057\u3066\u56fa\u5b9a\u3057\u305f\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>npm workspaces<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001UI\u3001API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001infra \u3092\u4e00\u3064\u306e\u4f9d\u5b58\u95a2\u4fc2\u30b0\u30e9\u30d5\u3067\u7ba1\u7406\u3059\u308b\u3002<\/td>\n<td>\u4e00\u3064\u306e\u53c2\u7167\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u6210\u3059\u308b\u8907\u6570\u6210\u679c\u7269\u3092\u3001\u540c\u4e00\u30b3\u30df\u30c3\u30c8\u3068 CI \u306e\u4e2d\u3067\u6574\u5408\u3055\u305b\u3089\u308c\u308b\u3002<\/td>\n<td>\u30e2\u30ce\u30ec\u30dd\u65b9\u91dd\u3092\u5177\u4f53\u5316\u3059\u308b\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>React 19<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6 SPA \u306e\u753b\u9762\u3001\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3001\u72b6\u614b\u3092\u5b9f\u88c5\u3059\u308b\u3002<\/td>\n<td>\u8981\u4ef6\u304c\u5bfe\u8a71\u7684\u306a SPA \u3092\u6307\u5b9a\u3057\u3066\u3044\u308b\u3002React \u81ea\u4f53\u306f\u3001\u305d\u306e\u8981\u4ef6\u3092\u6e80\u305f\u305b\u308b\u8907\u6570\u5019\u88dc\u306e\u4e00\u3064\u3067\u3042\u308b\u3002<\/td>\n<td>\u53c2\u7167\u57fa\u6e96\u3068\u3057\u3066\u63a1\u7528\u3057\u305f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>TypeScript 5.9<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u578b\u4ed8\u304d\u3067\u5b9f\u88c5\u3059\u308b\u3002<\/td>\n<td>\u4e00\u3064\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u5185\u3067\u578b\u691c\u67fb\u3068\u958b\u767a\u74b0\u5883\u3092\u5171\u901a\u5316\u3067\u304d\u308b\u4e00\u65b9\u3001\u516c\u958b HTTP \u5951\u7d04\u306f OpenAPI \u3078\u5206\u96e2\u3067\u304d\u308b\u3002<\/td>\n<td>\u30ea\u30dd\u30b8\u30c8\u30ea\u5168\u4f53\u3092\u8cab\u304f\u5b9f\u88c5\u8a00\u8a9e\u306e\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Vite 8<\/td>\n<td>SPA \u306e\u958b\u767a\u30b5\u30fc\u30d0\u30fc\u3068\u30d3\u30eb\u30c9\u3092\u62c5\u5f53\u3059\u308b\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30d3\u30eb\u30c9\u306e\u8cac\u52d9\u3092\u62c5\u3044\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3078\u8ffd\u52a0\u306e\u72ec\u81ea\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u5c0e\u5165\u3057\u306a\u3044\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30c4\u30fc\u30eb\u306e\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>NestJS 12<\/td>\n<td>BFF\u3001controller\u3001\u4f9d\u5b58\u95a2\u4fc2 injection\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9 composition \u3092\u62c5\u5f53\u3059\u308b\u3002<\/td>\n<td>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u304c\u6301\u3064\u901a\u5e38\u306e\u30e2\u30b8\u30e5\u30fc\u30eb\u3001controller\u3001DI \u3092\u5229\u7528\u3057\u3001\u305d\u306e\u4e0a\u3078\u5225\u306e\u72ec\u81ea\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3092\u91cd\u306d\u306a\u3044\u3002<\/td>\n<td>\u53c2\u7167\u57fa\u6e96\u3068\u3057\u3066\u63a1\u7528\u3057\u305f\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>OpenAPI 3.1<\/td>\n<td>\u30d6\u30e9\u30a6\u30b6\u5411\u3051 HTTP \u5951\u7d04\u306e\u6b63\u672c\u3068\u306a\u308b\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u5b9f\u88c5\u8a00\u8a9e\u304b\u3089\u516c\u958b\u5951\u7d04\u3092\u72ec\u7acb\u3055\u305b\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u691c\u8a3c\u3001\u5951\u7d04\u30c6\u30b9\u30c8\u306e\u5171\u901a\u5165\u529b\u306b\u3059\u308b\u3002<\/td>\n<td>\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u5883\u754c\u3092\u56fa\u5b9a\u3059\u308b\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>PostgreSQL 17<\/td>\n<td>\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u3068\u30c6\u30b9\u30c8\u3067\u672c\u756a\u3068\u540c\u7cfb\u7d71\u306e\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u610f\u5473\u8ad6\u3092\u63d0\u4f9b\u3059\u308b\u3002<\/td>\n<td>\u72b6\u614b\u9077\u79fb\u3001\u76e3\u67fb\u3001outbox\u3001\u884c\u30ed\u30c3\u30af\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u540c\u3058\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u610f\u5473\u8ad6\u3067\u6271\u3046\u5fc5\u8981\u304c\u3042\u308b\u3002<\/td>\n<td>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u8981\u4ef6\u304b\u3089\u5f37\u304f\u65b9\u5411\u4ed8\u3051\u3089\u308c\u305f\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Prisma 7<\/td>\n<td>\u30b9\u30ad\u30fc\u30de\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a2\u30af\u30bb\u30b9\u3092 TypeScript \u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304b\u3089\u5b9f\u88c5\u3059\u308b\u3002<\/td>\n<td>PostgreSQL \u30b9\u30ad\u30fc\u30de\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u30ea\u30dd\u30b8\u30c8\u30ea\u7ba1\u7406\u4e0b\u306b\u7f6e\u304d\u3001\u6c38\u7d9a\u5316\u30b3\u30fc\u30c9\u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u578b\u4ed8\u304d\u5b9f\u88c5\u3078\u63a5\u7d9a\u3059\u308b\u3002<\/td>\n<td>\u6c38\u7d9a\u5316\u5c64\u3092\u5177\u4f53\u5316\u3059\u308b\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Transactional outbox<\/td>\n<td>\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u5f8c\u306b\u5fc5\u8981\u306a email \u3068\u30a4\u30d9\u30f3\u30c8\u306e\u914d\u9001\u610f\u56f3\u3092\u4fdd\u6301\u3059\u308b\u3002<\/td>\n<td>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u66f8\u304d\u8fbc\u307f\u3068\u5916\u90e8\u914d\u9001\u306e\u4e8c\u91cd\u66f8\u304d\u8fbc\u307f\u3092\u3001\u4e00\u3064\u306e\u539f\u5b50\u64cd\u4f5c\u3067\u3042\u308b\u304b\u306e\u3088\u3046\u306b\u6271\u308f\u305a\u3001\u4fdd\u8a3c\u5883\u754c\u3092\u5206\u96e2\u3059\u308b\u3002<\/td>\n<td>\u6574\u5408\u6027\u8981\u4ef6\u304b\u3089\u5c0e\u304b\u308c\u308b\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u30d1\u30bf\u30fc\u30f3\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Cognito + PKCE<\/td>\n<td>AWS \u30e2\u30fc\u30c9\u306e\u672c\u4eba\u78ba\u8a8d\u3068\u30d6\u30e9\u30a6\u30b6\u8a8d\u8a3c\u3092\u62c5\u3046\u3002<\/td>\n<td>SPA \u306e\u30d1\u30d6\u30ea\u30c3\u30af\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u8a8d\u8a3c\u30d7\u30ed\u30c8\u30b3\u30eb\u3092 identity \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3078\u59d4\u306d\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306f\u691c\u8a3c\u6e08\u307f identity \u3092\u7528\u3044\u305f\u8a8d\u53ef\u3078\u96c6\u4e2d\u3059\u308b\u3002<\/td>\n<td>\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u30d7\u30ed\u30c8\u30b3\u30eb\u3068 AWS \u30a2\u30a4\u30c7\u30f3\u30c6\u30a3\u30c6\u30a3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u7d44\u307f\u5408\u308f\u305b\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>S3<\/td>\n<td>\u6dfb\u4ed8\u30d5\u30a1\u30a4\u30eb\u672c\u4f53\u3092\u4fdd\u5b58\u3059\u308b\u3002<\/td>\n<td>\u95a2\u4fc2\u30e1\u30bf\u30c7\u30fc\u30bf\u3068 binary \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4fdd\u5b58\u8cac\u52d9\u3092\u5206\u3051\u3001\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30b9\u30c8\u30ec\u30fc\u30b8\u5883\u754c\u306e\u5185\u5074\u3078\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u56fa\u6709\u51e6\u7406\u3092\u9589\u3058\u8fbc\u3081\u308b\u3002<\/td>\n<td>AWS \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>SES<\/td>\n<td>email \u3092\u914d\u9001\u3059\u308b\u3002<\/td>\n<td>outbox \u30ef\u30fc\u30ab\u30fc\u304b\u3089\u5916\u90e8\u526f\u4f5c\u7528\u3068\u3057\u3066\u5b9f\u884c\u3057\u3001\u696d\u52d9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3068\u914d\u9001\u5931\u6557\u3092\u5225\u306e\u5883\u754c\u3067\u6271\u3046\u3002<\/td>\n<td>AWS \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>SNS<\/td>\n<td>\u696d\u52d9\u30a4\u30d9\u30f3\u30c8\u3092\u767a\u884c\u3059\u308b\u3002<\/td>\n<td>\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u5f8c\u306e\u30a4\u30d9\u30f3\u30c8\u914d\u9001\u3092\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30d7\u30ed\u30bb\u30b9\u306e\u5916\u3078\u6e21\u3057\u3001consumer \u5074\u3078\u91cd\u8907\u6392\u9664 key \u3092\u63d0\u4f9b\u3059\u308b\u3002<\/td>\n<td>AWS \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u306e\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Docker Compose<\/td>\n<td>\u30ed\u30fc\u30ab\u30eb PostgreSQL \u3092\u65e2\u77e5\u306e\u6761\u4ef6\u3067\u8d77\u52d5\u3059\u308b\u3002<\/td>\n<td>OS \u3054\u3068\u306e PostgreSQL \u5c0e\u5165\u5dee\u3092\u30b3\u30f3\u30c6\u30ca\u306b\u9589\u3058\u8fbc\u3081\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30d7\u30ed\u30bb\u30b9\u81ea\u4f53\u306f\u30db\u30b9\u30c8\u4e0a\u3067\u76f4\u63a5\u52d5\u304b\u3059\u3002<\/td>\n<td>\u30ed\u30fc\u30ab\u30eb\u958b\u767a\u7d4c\u8def\u3092\u5177\u4f53\u5316\u3059\u308b\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Vitest<\/td>\n<td>TypeScript workspaces \u306e\u81ea\u52d5\u30c6\u30b9\u30c8\u3092\u5b9f\u884c\u3059\u308b\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u30c6\u30b9\u30c8\u30e9\u30f3\u30ca\u30fc\u3092\u65e2\u5b58\u306e TypeScript \u958b\u767a\u74b0\u5883\u3078\u7d71\u5408\u3059\u308b\u3002<\/td>\n<td>\u30c6\u30b9\u30c8\u5b9f\u884c\u7cfb\u306e\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>React Testing Library<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u5229\u7528\u8005\u304b\u3089\u89b3\u6e2c\u3067\u304d\u308b\u632f\u308b\u821e\u3044\u3092\u691c\u8a3c\u3059\u308b\u3002<\/td>\n<td>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u5185\u90e8\u69cb\u9020\u3088\u308a\u3001\u753b\u9762\u64cd\u4f5c\u3001\u8868\u793a\u3001\u72b6\u614b\u5909\u5316\u3092\u30c6\u30b9\u30c8\u5bfe\u8c61\u3078\u7f6e\u304f\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30c6\u30b9\u30c8\u306e\u89b3\u6e2c\u65b9\u6cd5\u3092\u5177\u4f53\u5316\u3059\u308b\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Supertest<\/td>\n<td>NestJS \u306e HTTP \u5883\u754c\u3092\u7d71\u5408\u7684\u306b\u691c\u8a3c\u3059\u308b\u3002<\/td>\n<td>BFF \u306e\u30ea\u30af\u30a8\u30b9\u30c8\uff0f\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u3001controller \u5358\u4f53\u3088\u308a\u5b9f\u969b\u306e HTTP \u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306b\u8fd1\u3044\u4f4d\u7f6e\u3067\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<td>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9 integration \u30c6\u30b9\u30c8\u306e\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Redocly CLI<\/td>\n<td>OpenAPI \u30bd\u30fc\u30b9\u3092 CI \u3067\u691c\u8a3c\u3059\u308b\u3002<\/td>\n<td>API \u4ed5\u69d8\u3092\u95b2\u89a7\u7528\u6587\u66f8\u3060\u3051\u3067\u7d42\u308f\u3089\u305b\u305a\u3001\u6a5f\u68b0\u691c\u8a3c\u53ef\u80fd\u306a\u6210\u679c\u7269\u3068\u3057\u3066\u6271\u3046\u3002<\/td>\n<td>\u5951\u7d04\u691c\u8a3c\u30c4\u30fc\u30eb\u306e\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>AWS CDK v2<\/td>\n<td>AWS \u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092 TypeScript \u3067\u5b9a\u7fa9\u3059\u308b\u3002<\/td>\n<td>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u540c\u3058\u30ea\u30dd\u30b8\u30c8\u30ea\u3067\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3092\u30ec\u30d3\u30e5\u30fc\u3001typecheck\u3001synth \u306e\u5bfe\u8c61\u306b\u3059\u308b\u3002<\/td>\n<td>Infrastructure as Code \u3092\u5177\u4f53\u5316\u3059\u308b\u5b9f\u88c5\u9078\u629e\u3067\u3042\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Node.js \u3068 TypeScript \u3092\u30ea\u30dd\u30b8\u30c8\u30ea\u5168\u4f53\u3078\u901a\u3057\u305f\u3053\u3068\u306b\u306f\u3001\u5358\u306a\u308b\u8a00\u8a9e\u7d71\u4e00\u4ee5\u4e0a\u306e\u52b9\u679c\u304c\u3042\u308b\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u88dc\u52a9\u30b9\u30af\u30ea\u30d7\u30c8\u3001AWS CDK \u304c\u540c\u3058\u5b9f\u884c\u74b0\u5883\u306e\u7cfb\u7d71\u306b\u5165\u308b\u305f\u3081\u3001\u4e00\u3064\u306e\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u3067 API \u5951\u7d04\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092\u5909\u66f4\u3057\u3001\u540c\u3058 CI \u304b\u3089\u691c\u8a3c\u3067\u304d\u308b\u3002\u8907\u6570\u6210\u679c\u7269\u306e\u5909\u66f4\u3092\u540c\u3058\u30ea\u30dd\u30b8\u30c8\u30ea\u5883\u754c\u306b\u9589\u3058\u8fbc\u3081\u308b\u3053\u3068\u304c\u3001\u3053\u306e\u69cb\u6210\u306e\u72d9\u3044\u3067\u3042\u308b\u3002<\/p>\n<p>npm workspaces \u3082\u3001\u3053\u306e\u30e2\u30ce\u30ec\u30dd\u306e\u610f\u5473\u3068\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u3002\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u304c @spa-ref\/api-\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3068 @spa-ref\/ui \u3092\u5229\u7528\u3057\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3068 infra \u3082\u540c\u3058\u30eb\u30fc\u30c8\u306e\u30ed\u30c3\u30af\u30d5\u30a1\u30a4\u30eb\u306e\u7ba1\u7406\u4e0b\u306b\u5165\u308b\u3002OpenAPI \u3092\u5909\u66f4\u3057\u3066\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u5909\u308f\u308a\u3001\u305d\u306e\u7d50\u679c\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u578b\u691c\u67fb\u304c\u5931\u6557\u3059\u308b\u306a\u3089\u3001\u305d\u306e\u4e0d\u6574\u5408\u3092\u540c\u3058\u5909\u66f4\u5358\u4f4d\u306e\u4e2d\u3067\u691c\u51fa\u3067\u304d\u308b\u3002\u30ea\u30dd\u30b8\u30c8\u30ea\u3092\u8907\u6570\u306b\u5206\u5272\u3059\u308b\u3068\u3001\u5951\u7d04\u5909\u66f4\u306b\u30d0\u30fc\u30b8\u30e7\u30f3\u767a\u884c\u3001\u4f9d\u5b58\u66f4\u65b0\u3001\u8907\u6570\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u306e\u9806\u5e8f\u5236\u5fa1\u304c\u5fc5\u8981\u306b\u306a\u308b\u3002\u73fe\u5728\u305d\u306e\u904b\u7528\u4e0a\u306e\u72ec\u7acb\u6027\u3092\u8981\u6c42\u3057\u3066\u3044\u306a\u3044\u305f\u3081\u3001\u4e00\u3064\u306e\u30e2\u30ce\u30ec\u30dd\u306e\u65b9\u304c\u6271\u3046\u72b6\u614b\u6570\u304c\u5c11\u306a\u3044\u3002<\/p>\n<p>AWS \u30c7\u30d7\u30ed\u30a4\u306f\u3001\u901a\u4fe1\u7d4c\u8def\u3001\u79d8\u5bc6\u60c5\u5831\u3001\u30c7\u30fc\u30bf\u30d7\u30ec\u30fc\u30f3\u3001\u5b9f\u884c\u4e3b\u4f53\u3068\u3044\u3046\u8907\u6570\u306e\u8cac\u52d9\u304b\u3089\u69cb\u6210\u3055\u308c\u308b\u3002\u73fe\u5728\u306e CDK \u30b9\u30bf\u30c3\u30af\u306f\u30012 \u30a2\u30d9\u30a4\u30e9\u30d3\u30ea\u30c6\u30a3\u30fc\u30be\u30fc\u30f3\u306e VPC\u3001\u30d1\u30d6\u30ea\u30c3\u30af\u30b5\u30d6\u30cd\u30c3\u30c8\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u7528\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30b5\u30d6\u30cd\u30c3\u30c8\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u7528\u5206\u96e2\u30b5\u30d6\u30cd\u30c3\u30c8\u3001Cognito user pool\u3001Aurora PostgreSQL 17.4 Serverless v2\u3001\u975e\u516c\u958b S3 bucket\u3001SNS topic\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e Fargate \u30b5\u30fc\u30d3\u30b9\u3001\u5225\u30bf\u30b9\u30af\u3068\u3057\u3066\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001Application Load Balancer\u3001Secrets Manager\u3001IAM \u30bf\u30b9\u30af role \u3092\u69cb\u6210\u3059\u308b<a href=\"#ref25\">[25]<\/a>\u3002\u3053\u306e\u69cb\u6210\u3092\u30c8\u30dd\u30ed\u30b8\u30fc\u3068\u3057\u3066\u8aad\u3080\u3053\u3068\u3067\u3001\u5404\u30b5\u30fc\u30d3\u30b9\u304c\u53d7\u3051\u6301\u3064\u5883\u754c\u3092\u78ba\u8a8d\u3067\u304d\u308b\u3002<\/p>\n<p>VPC \u306e\u30b5\u30d6\u30cd\u30c3\u30c8\u5206\u5272\u306b\u3082\u8cac\u52d9\u304c\u3042\u308b\u3002ALB \u306e\u3088\u3046\u306b\u5916\u90e8\u304b\u3089\u5230\u9054\u3059\u308b\u5165\u53e3\u306f public \u5074\u3078\u7f6e\u304d\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30bf\u30b9\u30af\u306f\u30d7\u30e9\u30a4\u30d9\u30fc\u30c8\u30b5\u30d6\u30cd\u30c3\u30c8\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f\u5206\u96e2\u30b5\u30d6\u30cd\u30c3\u30c8\u3078\u7f6e\u304f\u3002\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f Aurora\u3001S3\u3001SES\u3001SNS \u3068\u901a\u4fe1\u3059\u308b\u304c\u3001\u30d6\u30e9\u30a6\u30b6\u306f\u305d\u308c\u3089\u3078\u76f4\u63a5\u63a5\u7d9a\u3057\u306a\u3044\u3002\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u30aa\u30ea\u30b8\u30f3\u3068\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc access \u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u5883\u754c\u3067\u5206\u3051\u308b\u3068\u3044\u3046\u57fa\u672c\u8a2d\u8a08\u304c\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af topology \u306b\u307e\u3067\u53cd\u6620\u3055\u308c\u3066\u3044\u308b\u3002<\/p>\n<p>Aurora PostgreSQL \u306f\u3001AWS \u5074\u3067\u3082\u30ed\u30fc\u30ab\u30eb PostgreSQL \u3068\u540c\u3058\u95a2\u4fc2\u30e2\u30c7\u30eb\u3092\u7dad\u6301\u3059\u308b\u5f79\u5272\u3092\u6301\u3064\u3002\u73fe\u5728\u306e CDK \u30b9\u30bf\u30c3\u30af\u306f Aurora PostgreSQL 17.4 \u306e Serverless v2 \u3092\u69cb\u6210\u3057\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u8a8d\u8a3c\u60c5\u5831\u306f Secrets Manager \u304b\u3089\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30bf\u30b9\u30af\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u30bf\u30b9\u30af\u3078\u6e21\u3059<a href=\"#ref25\">[25]<\/a>\u3002\u8a8d\u8a3c\u60c5\u5831\u3092\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u5b9f\u884c\u6642\u8a2d\u5b9a\u3084\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u306b\u7f6e\u304b\u305a\u3001\u5b9f\u884c\u4e3b\u4f53\u3078\u5fc5\u8981\u306a\u6642\u70b9\u3067\u6ce8\u5165\u3059\u308b\u3053\u3068\u3067\u3001\u30d6\u30e9\u30a6\u30b6\u3067\u5b89\u5168\u306b\u6271\u3048\u308b\u8a2d\u5b9a\u3068\u30b5\u30fc\u30d0\u30fc\u5074\u30b7\u30fc\u30af\u30ec\u30c3\u30c8\u3092\u5206\u96e2\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u901a\u5e38\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8d77\u52d5\u304b\u3089\u5206\u3051\u3066\u3044\u308b\u70b9\u3082\u3001\u6280\u8853\u9078\u5b9a\u306b\u542b\u307e\u308c\u308b\u3002CDK \u30b9\u30bf\u30c3\u30af\u306f\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u5c02\u7528\u306e Fargate \u30bf\u30b9\u30af\u3092\u5225\u306b\u6301\u3061\u3001\u901a\u5e38\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8d77\u52d5\u3068\u30b9\u30ad\u30fc\u30de\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u5225\u306e\u64cd\u4f5c\u306b\u3057\u3066\u3044\u308b<a href=\"#ref25\">[25]<\/a>\u3002\u8907\u6570\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30bf\u30b9\u30af\u304c\u540c\u6642\u8d77\u52d5\u3059\u308b\u74b0\u5883\u3067\u306f\u3001\u30c7\u30d7\u30ed\u30a4\u6642\u306e\u30b9\u30ad\u30fc\u30de\u5909\u66f4\u3068\u901a\u5e38\u8d77\u52d5\u3092\u5206\u3051\u308b\u3053\u3068\u3067\u8cac\u52d9\u3092\u660e\u78ba\u306b\u3067\u304d\u308b\u3002\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306f\u4e00\u56de\u6027\u306e\u660e\u793a\u64cd\u4f5c\u3068\u3057\u3066\u6271\u3044\u3001\u901a\u5e38\u306e\u30b5\u30fc\u30d3\u30b9\u518d\u8d77\u52d5\u306f\u65e2\u5b58\u30b9\u30ad\u30fc\u30de\u3092\u524d\u63d0\u306b\u3059\u308b\u3002<\/p>\n<p>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u305d\u308c\u305e\u308c Fargate \u30bf\u30b9\u30af\u3068\u3057\u3066\u52d5\u304d\u3001ALB \u304c \/api\/* \u3092\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3001\u305d\u308c\u4ee5\u5916\u3092\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3078\u632f\u308a\u5206\u3051\u308b<a href=\"#ref25\">[25]<\/a>\u3002Amazon ECS \u306f\u30b3\u30f3\u30c6\u30ca\u5316\u3057\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u7ba1\u7406\u3059\u308b\u30b5\u30fc\u30d3\u30b9\u3067\u3042\u308a\u3001Fargate \u306f\u30bf\u30b9\u30af\u3092 AWS \u7ba1\u7406\u306e\u30b5\u30fc\u30d0\u30fc\u30ec\u30b9\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u4e0a\u3067\u5b9f\u884c\u3059\u308b<a href=\"#ref26\">[26]<\/a>\u3002spa-reference \u306f\u73fe\u5728\u306e\u8981\u4ef6\u306b\u5bfe\u3057\u3066 Fargate \u3092\u9078\u3073\u3001\u30b3\u30f3\u30c6\u30ca\u5b9f\u884c\u57fa\u76e4\u306e\u7ba1\u7406\u3092 AWS \u5074\u3078\u5bc4\u305b\u3066\u3044\u308b\u3002<\/p>\n<p>Fargate \u306e\u59a5\u5f53\u6027\u306f\u73fe\u5728\u306e\u6761\u4ef6\u306b\u4f9d\u5b58\u3059\u308b\u3002\u65e2\u5b58\u306e Kubernetes \u57fa\u76e4\u304c\u7d44\u7e54\u6a19\u6e96\u3068\u3057\u3066\u5b58\u5728\u3059\u308b\u74b0\u5883\u3001EC2 \u4e0a\u3067\u7279\u6b8a\u306a\u5b9f\u884c\u6642\u5236\u7d04\u3092\u6301\u3064\u74b0\u5883\u3001\u5225\u30af\u30e9\u30a6\u30c9\u3092\u5bfe\u8c61\u3068\u3059\u308b\u74b0\u5883\u3067\u306f\u5225\u306e\u9078\u629e\u304c\u6210\u7acb\u3059\u308b\u3002spa-reference \u3067\u306f AWS \u3092\u73fe\u5728\u552f\u4e00\u306e\u30c7\u30d7\u30ed\u30a4\u5bfe\u8c61\u3068\u3057\u3001\u30b3\u30f3\u30c6\u30ca\u5316\u3057\u305f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3092\u6bd4\u8f03\u7684\u5c11\u306a\u3044\u904b\u7528\u6982\u5ff5\u3067\u914d\u7f6e\u3059\u308b\u3068\u3044\u3046\u6761\u4ef6\u306b\u5bfe\u3057\u3066 Fargate \u3092\u63a1\u7528\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>AWS CDK \u306e\u9078\u5b9a\u7406\u7531\u306f\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u3092 TypeScript \u3067\u5b9a\u7fa9\u3067\u304d\u308b\u3053\u3068\u306b\u52a0\u3048\u3001CloudFormation template \u3078\u5408\u6210\u3057\u3001AWS \u30ea\u30bd\u30fc\u30b9\u306e\u69cb\u6210\u3092 Infrastructure as Code \u3068\u3057\u3066\u6271\u3048\u308b\u70b9\u306b\u3042\u308b<a href=\"#ref27\">[27]<\/a>\u3002spa-reference \u3067\u306f\u30b9\u30bf\u30c3\u30af\u5b9a\u7fa9\u3092\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u540c\u3058\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u7f6e\u304f\u305f\u3081\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u304c\u5fc5\u8981\u3068\u3059\u308b Cognito issuer\u3001S3 bucket\u3001SNS topic\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3001IAM permission \u3068\u3044\u3063\u305f\u95a2\u4fc2\u3092\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5909\u66f4\u3068\u540c\u3058\u30ec\u30d3\u30e5\u30fc\u5358\u4f4d\u3067\u78ba\u8a8d\u3067\u304d\u308b\u3002<\/p>\n<p>\u901a\u5e38\u306e CI \u306f CDK synth \u307e\u3067\u3092\u691c\u8a3c\u7bc4\u56f2\u3068\u3057\u3001\u5b9f\u969b\u306e AWS \u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210\u3001\u5909\u66f4\u3001\u524a\u9664\u306f\u30c7\u30d7\u30ed\u30a4\u64cd\u4f5c\u3078\u5206\u3051\u308b\u3002\u3053\u306e\u5206\u96e2\u3082\u6280\u8853\u9078\u629e\u306e\u4e00\u90e8\u3067\u3042\u308b\u3002\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u304c\u578b\u691c\u67fb\u3067\u304d\u3001CloudFormation template \u3078\u5408\u6210\u3067\u304d\u308b\u3053\u3068\u306f\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u4e0a\u3067\u78ba\u8a8d\u3067\u304d\u308b\u3002\u5b9f\u74b0\u5883\u3078\u306e\u5909\u66f4\u306f\u30a2\u30ab\u30a6\u30f3\u30c8\u3001\u8a8d\u8a3c\u60c5\u5831\u3001\u74b0\u5883\u56fa\u6709\u8a2d\u5b9a\u3001\u5909\u66f4\u5f71\u97ff\u3092\u4f34\u3046\u305f\u3081\u3001\u5b9a\u7fa9\u306e\u59a5\u5f53\u6027\u78ba\u8a8d\u3068\u672c\u756a\u74b0\u5883\u306e\u5909\u66f4\u3092\u5225\u306e\u6a29\u9650\u5883\u754c\u3078\u7f6e\u3044\u3066\u3044\u308b\u3002<\/p>\n<p>\u30c6\u30b9\u30c8\u6280\u8853\u306f\u3001\u89b3\u6e2c\u3059\u308b\u6545\u969c\u9762\u3054\u3068\u306b\u5f79\u5272\u5206\u62c5\u3059\u308b\u3002Vitest \u306f TypeScript workspace \u306e\u30c6\u30b9\u30c8\u30e9\u30f3\u30ca\u30fc\u3068\u3057\u3066\u4f7f\u3044\u3001React Testing Library \u306f\u30d6\u30e9\u30a6\u30b6\u5229\u7528\u8005\u304b\u3089\u89b3\u6e2c\u3067\u304d\u308b\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u306e\u632f\u308b\u821e\u3044\u3092\u78ba\u8a8d\u3057\u3001Supertest \u306f NestJS \u306e HTTP \u5883\u754c\u3092\u78ba\u8a8d\u3059\u308b\u3002Redocly CLI \u306f OpenAPI \u81ea\u4f53\u3092\u691c\u8a3c\u3057\u3001Prisma CLI \u306f\u30b9\u30ad\u30fc\u30de\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u691c\u8a3c\u3057\u3001CDK synth \u306f\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3092\u691c\u8a3c\u3059\u308b\u3002\u540c\u3058\u300c\u30c6\u30b9\u30c8\u300d\u3068\u3044\u3046\u540d\u524d\u3067\u3082\u3001\u5404\u691c\u67fb\u304c\u53d7\u3051\u6301\u3064\u5bfe\u8c61\u306f\u7570\u306a\u308b\u3002<\/p>\n<p>\u6280\u8853\u30b9\u30bf\u30c3\u30af\u3092\u5224\u65ad\u306e\u5f37\u3055\u3067\u6574\u7406\u3059\u308b\u3068\u3001\u5c11\u306a\u304f\u3068\u3082\u4e09\u5c64\u306b\u5206\u3051\u3089\u308c\u308b\u3002\u7b2c\u4e00\u306f\u3001\u95a2\u4fc2\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u5883\u754c\u3001\u5b9f\u88c5\u8a00\u8a9e\u304b\u3089\u72ec\u7acb\u3057\u305f API \u5951\u7d04\u3001\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u3068\u5916\u90e8\u526f\u4f5c\u7528\u306e\u5206\u96e2\u3068\u3044\u3063\u305f\u8981\u4ef6\u3084\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u304b\u3089\u5f37\u304f\u5c0e\u304b\u308c\u308b\u5224\u65ad\u3067\u3042\u308b\u3002\u7b2c\u4e8c\u306f\u3001React\u3001NestJS\u3001AWS \u306e\u3088\u3046\u306b\u3001\u8981\u4ef6\u3092\u6e80\u305f\u3059\u8907\u6570\u306e\u5019\u88dc\u304b\u3089\u53c2\u7167\u57fa\u6e96\u3068\u3057\u3066\u63a1\u7528\u3057\u305f\u9078\u629e\u3067\u3042\u308b\u3002\u7b2c\u4e09\u306f Vite\u3001Vitest\u3001Prisma\u3001Redocly \u306a\u3069\u3001\u305d\u306e\u57fa\u6e96\u5b9f\u88c5\u3092\u52b9\u7387\u3088\u304f\u5b9f\u88c5\u3001\u691c\u8a3c\u3059\u308b\u305f\u3081\u306e\u5177\u4f53\u7684\u30c4\u30fc\u30eb\u3067\u3042\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u5224\u65ad\u5c64<\/th>\n<th>\u4ee3\u8868\u4f8b<\/th>\n<th>\u5909\u66f4\u3059\u308b\u3068\u304d\u306b\u78ba\u8a8d\u3059\u308b\u3082\u306e<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u8981\u4ef6\u30fb\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u304b\u3089\u5f37\u304f\u62d8\u675f\u3055\u308c\u308b\u9078\u629e<\/td>\n<td>\u95a2\u4fc2\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u5883\u754c\u3001\u30d6\u30e9\u30a6\u30b6\u5411\u3051 API \u5883\u754c\u3001\u5b9f\u88c5\u8a00\u8a9e\u304b\u3089\u72ec\u7acb\u3057\u305f HTTP \u5951\u7d04\u3001\u696d\u52d9\u30b3\u30df\u30c3\u30c8\u3068\u5916\u90e8\u526f\u4f5c\u7528\u306e\u5206\u96e2\u3001\u30b5\u30fc\u30d0\u30fc\u5074\u8a8d\u53ef<\/td>\n<td>\u5bfe\u8c61\u3068\u3059\u308b\u696d\u52d9\u7279\u6027\u3001\u6574\u5408\u6027\u8981\u6c42\u3001\u516c\u958b\u5951\u7d04\u3001\u969c\u5bb3\u6642\u4fdd\u8a3c\u305d\u306e\u3082\u306e\u304c\u5909\u308f\u3063\u305f\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u53c2\u7167\u57fa\u6e96\u3068\u3057\u3066\u63a1\u7528\u3057\u305f\u5b9f\u88c5\u65b9\u5f0f<\/td>\n<td>React\u3001NestJS\u3001AWS\u3001\u30e2\u30ce\u30ec\u30dd<\/td>\n<td>\u540c\u3058\u8981\u4ef6\u3092\u3088\u308a\u9069\u5207\u306b\u6e80\u305f\u3059\u7d44\u7e54\u6761\u4ef6\u3001\u65e2\u5b58\u57fa\u76e4\u3001\u904b\u7528\u6761\u4ef6\u304c\u3042\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u5b9f\u88c5\u3068\u691c\u8a3c\u3092\u5177\u4f53\u5316\u3059\u308b\u9053\u5177<\/td>\n<td>Vite\u3001Prisma\u3001Vitest\u3001React Testing Library\u3001Supertest\u3001Redocly CLI\u3001AWS CDK<\/td>\n<td>\u4e0a\u4f4d\u306e\u5951\u7d04\u3068\u8cac\u52d9\u3092\u7dad\u6301\u3057\u305f\u307e\u307e\u7f6e\u63db\u3067\u304d\u308b\u304b\u3001\u8ffd\u52a0\u6982\u5ff5\u3068\u4fdd\u5b88\u8cbb\u7528\u304c\u59a5\u5f53\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u6280\u8853\u30b9\u30bf\u30c3\u30af\u306e\u66f4\u65b0\u5224\u65ad\u3067\u306f\u3001\u65b0\u3057\u3044\u7248\u3084\u6d41\u884c\u3088\u308a\u3001\u73fe\u5728\u306e\u6280\u8853\u304c\u62c5\u3046\u5951\u7d04\u3092\u4f55\u304c\u5f15\u304d\u7d99\u3050\u304b\u3092\u898b\u308b\u3002React \u3092\u5225\u306e\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3078\u5909\u66f4\u3059\u308b\u306a\u3089\u3001OpenAPI \u5951\u7d04\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u8a8d\u53ef\u3092\u7dad\u6301\u3057\u306a\u304c\u3089\u30d6\u30e9\u30a6\u30b6\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8cac\u52d9\u3092\u5f15\u304d\u7d99\u3052\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002Prisma \u3092\u5225\u306e\u6c38\u7d9a\u5316\u6280\u8853\u3078\u5909\u66f4\u3059\u308b\u306a\u3089\u3001PostgreSQL transaction\u3001\u884c\u30ed\u30c3\u30af\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u697d\u89b3\u7684\u540c\u6642\u5b9f\u884c\u5236\u5fa1\u3001outbox \u306e\u610f\u5473\u8ad6\u3092\u7dad\u6301\u3067\u304d\u308b\u304b\u3092\u898b\u308b\u3002Fargate \u3092\u5225\u306e\u5b9f\u884c\u57fa\u76e4\u3078\u5909\u66f4\u3059\u308b\u306a\u3089\u3001\u30b3\u30f3\u30c6\u30ca\u5b9f\u884c\u3001\u30d8\u30eb\u30b9\u30c1\u30a7\u30c3\u30af\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af isolation\u3001\u30b7\u30fc\u30af\u30ec\u30c3\u30c8\u6ce8\u5165\u3001\u30c7\u30d7\u30ed\u30a4\u8cac\u4efb\u3092\u3069\u306e\u4ed5\u7d44\u307f\u304c\u5f15\u304d\u7d99\u3050\u304b\u3092\u898b\u308b\u3002<\/p>\n<p>\u6280\u8853\u540d\u3092\u57fa\u6e96\u306b\u7f6e\u304f\u3068\u3001\u5909\u66f4\u306f\u88fd\u54c1\u6bd4\u8f03\u306b\u306a\u308b\u3002\u8981\u4ef6\u3068\u8cac\u52d9\u3092\u57fa\u6e96\u306b\u7f6e\u304f\u3068\u3001\u5909\u66f4\u306f\u300c\u73fe\u5728\u3053\u306e\u6280\u8853\u304c\u6e80\u305f\u3057\u3066\u3044\u308b\u5951\u7d04\u3092\u3001\u5225\u306e\u6280\u8853\u304c\u3069\u3053\u307e\u3067\u5f15\u304d\u7d99\u3052\u308b\u304b\u300d\u3068\u3044\u3046\u6bd4\u8f03\u306b\u306a\u308b\u3002spa-reference \u306e\u6280\u8853\u30b9\u30bf\u30c3\u30af\u3092\u514b\u660e\u306b\u898b\u308b\u610f\u5473\u306f\u3001\u5404\u88fd\u54c1\u306e\u80cc\u5f8c\u306b\u3042\u308b\u8981\u6c42\u3068\u4fdd\u8a3c\u7bc4\u56f2\u3092\u660e\u3089\u304b\u306b\u3059\u308b\u3053\u3068\u306b\u3042\u308b\u3002<\/p>\n<p>OpenAPI\u3001transactional outbox\u3001\u8a8d\u53ef\u5883\u754c\u306e\u3088\u3046\u306a\u8a2d\u8a08\u4e0a\u306e\u5224\u65ad\u3068\u3001React\u3001NestJS\u3001Vite\u3001Vitest \u306e\u3088\u3046\u306a\u5177\u4f53\u7684\u9078\u629e\u306f\u3001\u7570\u306a\u308b\u5f37\u3055\u306e\u5224\u65ad\u3068\u3057\u3066\u6271\u3046\u3002\u53c2\u7167\u5b9f\u88c5\u304c\u63d0\u4f9b\u3059\u308b\u306e\u306f\u3001\u4e00\u5b9a\u306e\u8981\u4ef6\u304b\u3089\u4e00\u3064\u306e\u6574\u5408\u3057\u305f\u69cb\u6210\u3078\u5230\u9054\u3057\u305f\u5b9f\u4f8b\u3067\u3042\u308b\u3002\u5225\u306e\u8981\u4ef6\u304b\u3089\u306f\u5225\u306e\u6280\u8853\u30b9\u30bf\u30c3\u30af\u304c\u5c0e\u304b\u308c\u5f97\u308b\u304c\u3001\u8981\u4ef6\u304b\u3089\u8cac\u52d9\u3092\u5206\u89e3\u3057\u3001\u5883\u754c\u3092\u56fa\u5b9a\u3057\u3001\u305d\u306e\u5883\u754c\u3092\u5177\u4f53\u7684\u306a\u6280\u8853\u3078\u5bfe\u5fdc\u4ed8\u3051\u308b\u3068\u3044\u3046\u5224\u65ad\u65b9\u6cd5\u306f\u518d\u5229\u7528\u3067\u304d\u308b\u3002<\/p>\n<hr>\n<h2>9. CI \u306f\u5b9f\u88c5\u3068\u5951\u7d04\u306e\u5bfe\u5fdc\u95a2\u4fc2\u3092\u7d99\u7d9a\u7684\u306b\u7167\u5408\u3059\u308b<\/h2>\n<p>GitHub Actions \u306f\u3001\u30ea\u30dd\u30b8\u30c8\u30ea\u4e0a\u306e\u30a4\u30d9\u30f3\u30c8\u3092\u5951\u6a5f\u306b\u30d3\u30eb\u30c9\u3001\u30c6\u30b9\u30c8\u3001\u30c7\u30d7\u30ed\u30a4\u306a\u3069\u306e workflow \u3092\u81ea\u52d5\u5b9f\u884c\u3067\u304d\u308b CI\/CD \u57fa\u76e4\u3067\u3042\u308b<a href=\"#ref28\">[28]<\/a>\u3002spa-reference \u3067\u306f\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u3068 master \u3078\u306e push \u3092\u691c\u8a3c\u5bfe\u8c61\u3068\u3057\u3001Node.js 24 \u3068\u4f7f\u3044\u6368\u3066 PostgreSQL 17 \u3092\u7528\u610f\u3059\u308b\u3002\u305d\u306e\u4e0a\u3067 npm ci\u3001Prisma \u30af\u30e9\u30a4\u30a2\u30f3\u30c8 generation\u3001\u751f\u6210 API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u6700\u65b0\u6027\u3001format\u3001lint\u3001typecheck\u3001OpenAPI \u691c\u8a3c\u3001\u81ea\u52d5\u30c6\u30b9\u30c8\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u30d3\u30eb\u30c9\u3001Prisma \u30b9\u30ad\u30fc\u30de\u691c\u8a3c\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u691c\u8a3c\u3001CDK synth\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u3068\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u30b3\u30f3\u30c6\u30ca\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u3002<\/p>\n<p>CI \u306f\u3001\u30ea\u30dd\u30b8\u30c8\u30ea\u5185\u306b\u3042\u308b\u8907\u6570\u306e\u5bfe\u5fdc\u95a2\u4fc2\u3092\u5225\u3005\u306e\u691c\u67fb\u3067\u78ba\u8a8d\u3059\u308b\u3002package.json \u3068 package-lock.json\u3001OpenAPI \u3068\u751f\u6210 API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001Prisma \u30b9\u30ad\u30fc\u30de\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001TypeScript \u30bd\u30fc\u30b9\u3068\u578b\u5236\u7d04\u3001CDK \u30bd\u30fc\u30b9\u3068\u5408\u6210\u53ef\u80fd\u306a\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3001Dockerfile \u3068\u30d3\u30eb\u30c9\u53ef\u80fd\u306a\u30b3\u30f3\u30c6\u30ca\u30a4\u30e1\u30fc\u30b8\u306f\u3001\u305d\u308c\u305e\u308c\u58ca\u308c\u65b9\u304c\u7570\u306a\u308b\u3002\u5bfe\u5fdc\u95a2\u4fc2\u3054\u3068\u306b\u691c\u67fb\u3092\u5206\u3051\u308b\u3053\u3068\u3067\u3001\u5404\u4e0d\u6574\u5408\u3092\u305d\u306e\u8cac\u52d9\u306b\u8fd1\u3044\u4f4d\u7f6e\u3067\u691c\u51fa\u3067\u304d\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u691c\u67fb<\/th>\n<th>\u7167\u5408\u3057\u3066\u3044\u308b\u3082\u306e<\/th>\n<th>\u691c\u51fa\u3057\u305f\u3044\u4e0d\u6574\u5408<\/th>\n<th>\u96a3\u63a5\u3059\u308b\u691c\u67fb\u7bc4\u56f2<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>npm ci<\/td>\n<td>package manifest\u3001\u30ed\u30c3\u30af\u30d5\u30a1\u30a4\u30eb\u3001\u5b9f\u969b\u306b\u5c0e\u5165\u3067\u304d\u308b\u4f9d\u5b58\u95a2\u4fc2\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u30ed\u30c3\u30af\u30d5\u30a1\u30a4\u30eb\u3068 manifest \u306e\u4e0d\u6574\u5408\u3084\u3001\u56fa\u5b9a\u3055\u308c\u305f\u4f9d\u5b58\u95a2\u4fc2\u3092\u5c0e\u5165\u3067\u304d\u306a\u3044\u72b6\u614b\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u696d\u52d9\u52d5\u4f5c\u306f\u81ea\u52d5\u30c6\u30b9\u30c8\u3068\u30d3\u30eb\u30c9\u306e\u691c\u67fb\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Format \/ lint<\/td>\n<td>\u30bd\u30fc\u30b9\u3068\u30ea\u30dd\u30b8\u30c8\u30ea\u5168\u4f53\u306e\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u898f\u5247\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u66f8\u5f0f\u9038\u8131\u3001\u9759\u7684\u306b\u691c\u51fa\u3067\u304d\u308b\u5371\u967a\u306a\u8a18\u8ff0\u3001\u4e0d\u8981\u306a\u69cb\u6587\u4e0a\u306e\u4e0d\u6574\u5408\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u696d\u52d9\u8981\u4ef6\u3078\u306e\u9069\u5408\u3068\u5b9f\u884c\u6642\u306e\u632f\u308b\u821e\u3044\u306f\u81ea\u52d5\u30c6\u30b9\u30c8\u3068\u30ec\u30d3\u30e5\u30fc\u306e\u691c\u67fb\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Typecheck<\/td>\n<td>TypeScript \u30bd\u30fc\u30b9\u5185\u306e\u5024\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3001\u547c\u3073\u51fa\u3057\u95a2\u4fc2\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u578b\u306e\u4e0d\u4e00\u81f4\u3001\u5b58\u5728\u3057\u306a\u3044\u30d7\u30ed\u30d1\u30c6\u30a3\u3084\u4e0d\u6b63\u306a\u547c\u3073\u51fa\u3057\u3092\u30b3\u30f3\u30d1\u30a4\u30eb\u524d\u306b\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>HTTP \u5951\u7d04\u306f OpenAPI \u691c\u8a3c\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u696d\u52d9\u610f\u5473\u306f\u81ea\u52d5\u30c6\u30b9\u30c8\u3068\u8a2d\u8a08\u30ec\u30d3\u30e5\u30fc\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>OpenAPI \u691c\u8a3c<\/td>\n<td>OpenAPI \u30bd\u30fc\u30b9\u3068 OpenAPI 3.1 \u306e\u69cb\u9020\u5236\u7d04\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u30b9\u30ad\u30fc\u30de\u3001reference\u3001\u64cd\u4f5c\u5b9a\u7fa9\u306a\u3069\u306e\u4ed5\u69d8\u4e0a\u306e\u4e0d\u6574\u5408\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u5b9f\u52d5\u4f5c\u3068\u306e\u4e00\u81f4\u306f\u5951\u7d04\u30c6\u30b9\u30c8\u3068\u81ea\u52d5\u30c6\u30b9\u30c8\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8 freshness<\/td>\n<td>OpenAPI \u30bd\u30fc\u30b9\u3068\u751f\u6210\u6e08\u307f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>OpenAPI \u3092\u5909\u66f4\u3057\u305f\u306e\u306b\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u53e4\u3044\u307e\u307e\u6b8b\u308b\u72b6\u614b\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u751f\u6210\u3055\u308c\u305f\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u4f7f\u3046\u753b\u9762\u306e\u696d\u52d9\u64cd\u4f5c\u306f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30c6\u30b9\u30c8\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Automated tests<\/td>\n<td>\u5b9f\u88c5\u3068\u3001\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u306b\u660e\u793a\u3055\u308c\u305f\u632f\u308b\u821e\u3044\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u72b6\u614b\u9077\u79fb\u3001\u8a8d\u53ef\u3001HTTP \u30ec\u30b9\u30dd\u30f3\u30b9\u3001\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u632f\u308b\u821e\u3044\u306a\u3069\u3001\u4e8b\u524d\u306b\u5b9a\u7fa9\u3057\u305f\u671f\u5f85\u304b\u3089\u306e\u9038\u8131\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u8981\u4ef6\u30fb\u8a2d\u8a08\u306e\u610f\u5473\u3068\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u306e\u7db2\u7f85\u6027\u306f\u30ec\u30d3\u30e5\u30fc\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Prisma \u691c\u8a3c<\/td>\n<td>Prisma \u30b9\u30ad\u30fc\u30de\u3068 Prisma \u304c\u8981\u6c42\u3059\u308b model \u5b9a\u7fa9\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u30b9\u30ad\u30fc\u30de\u81ea\u4f53\u304c\u89e3\u91c8\u3067\u304d\u306a\u3044\u72b6\u614b\u3084\u3001\u5b9a\u7fa9\u4e0a\u306e\u4e0d\u6574\u5408\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u5c65\u6b74\u304b\u3089\u306e\u5230\u9054\u53ef\u80fd\u6027\u306f\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u691c\u8a3c\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Migration \u691c\u8a3c<\/td>\n<td>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u9069\u7528\u5f8c\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u73fe\u5728\u306e Prisma \u30b9\u30ad\u30fc\u30de\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3 history \u3092\u9069\u7528\u3057\u3066\u3082\u73fe\u5728\u30b9\u30ad\u30fc\u30de\u3078\u5230\u9054\u3067\u304d\u306a\u3044\u72b6\u614b\u3084\u30b9\u30ad\u30fc\u30de drift \u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u672c\u756a\u30c7\u30fc\u30bf\u91cf\u3001\u9577\u6642\u9593 lock\u3001\u5b9f\u30c7\u30fc\u30bf\u56fa\u6709\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3 risk \u306f\u30c7\u30d7\u30ed\u30a4\u8a08\u753b\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>CDK synth<\/td>\n<td>TypeScript \u306e\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3068 CloudFormation \u3078\u5408\u6210\u53ef\u80fd\u306a\u69cb\u9020\u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u578b\u3084\u69cb\u6210\u306e\u8aa4\u308a\u306b\u3088\u308a\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3092\u5408\u6210\u3067\u304d\u306a\u3044\u72b6\u614b\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u5b9f\u969b\u306e AWS \u30a2\u30ab\u30a6\u30f3\u30c8\u3078\u306e\u30c7\u30d7\u30ed\u30a4\u3068\u5909\u66f4\u5f71\u97ff\u306f\u30c7\u30d7\u30ed\u30a4\u64cd\u4f5c\u306e\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>Container \u30d3\u30eb\u30c9<\/td>\n<td>Dockerfile\u3001\u30ea\u30dd\u30b8\u30c8\u30ea content\u3001\u30d3\u30eb\u30c9 context \u3092\u7167\u5408\u3059\u308b\u3002<\/td>\n<td>\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u307e\u305f\u306f\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306e\u30b3\u30f3\u30c6\u30ca\u30a4\u30e1\u30fc\u30b8\u3092\u751f\u6210\u3067\u304d\u306a\u3044\u72b6\u614b\u3092\u691c\u51fa\u3059\u308b\u3002<\/td>\n<td>\u672c\u756a\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u4e0b\u306e\u632f\u308b\u821e\u3044\u306f\u5b9f\u884c\u74b0\u5883\u306e\u691c\u8a3c\u7bc4\u56f2\u306b\u5c5e\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>OpenAPI \u3068\u751f\u6210 API \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u95a2\u4fc2\u306f\u3001\u3053\u306e CI \u306e\u8003\u3048\u65b9\u3092\u5206\u304b\u308a\u3084\u3059\u304f\u793a\u3059\u3002spa-reference \u3067\u306f OpenAPI \u304c\u30d6\u30e9\u30a6\u30b6\u5411\u3051 HTTP \u5951\u7d04\u306e\u6b63\u672c\u3067\u3042\u308a\u3001\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30bd\u30fc\u30b9\u306f\u305d\u3053\u304b\u3089\u751f\u6210\u3055\u308c\u308b\u3002OpenAPI \u3092\u5909\u66f4\u3057\u305f\u5f8c\u306b\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u66f4\u65b0\u3092\u5fd8\u308c\u308b\u3068\u3001\u30ea\u30dd\u30b8\u30c8\u30ea\u5185\u306b\u306f\u4e92\u3044\u306b\u7570\u306a\u308b\u4e8c\u3064\u306e API \u89e3\u91c8\u304c\u6b8b\u308b\u3002CI \u306e api:check \u306f\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u518d\u751f\u6210\u3057\u3001\u305d\u306e\u7d50\u679c\u3068\u3057\u3066 tracked \u30bd\u30fc\u30b9\u306b\u5dee\u5206\u304c\u751f\u3058\u306a\u3044\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308b\u3002\u3053\u308c\u306f\u300c\u751f\u6210\u306b\u6210\u529f\u3059\u308b\u304b\u300d\u3060\u3051\u3067\u306a\u304f\u3001\u300c\u6b63\u672c\u304b\u3089\u5c0e\u304b\u308c\u308b\u751f\u6210\u7269\u304c\u3059\u3067\u306b\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u53cd\u6620\u3055\u308c\u3066\u3044\u308b\u304b\u300d\u3092\u691c\u67fb\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>Prisma \u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3082\u540c\u3058\u69cb\u9020\u3092\u6301\u3064\u3002\u30b9\u30ad\u30fc\u30de.prisma \u304c\u73fe\u5728\u5f62\u3068\u3057\u3066\u6b63\u3057\u304f\u3066\u3082\u3001\u904e\u53bb\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u9806\u306b\u9069\u7528\u3057\u3066\u540c\u3058\u72b6\u614b\u3078\u5230\u9054\u3067\u304d\u306a\u3051\u308c\u3070\u3001\u65b0\u3057\u3044\u74b0\u5883\u3092\u518d\u69cb\u7bc9\u3067\u304d\u306a\u3044\u3002CI \u3067\u306f\u4f7f\u3044\u6368\u3066 PostgreSQL \u3092\u7528\u610f\u3057\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u5b9f\u969b\u306b\u9069\u7528\u3057\u305f\u5f8c\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u304b\u3089\u5f97\u3089\u308c\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u3068\u73fe\u5728\u306e Prisma \u30b9\u30ad\u30fc\u30de\u306e\u5dee\u5206\u3092\u691c\u67fb\u3059\u308b\u3002\u73fe\u5728\u306e\u30b9\u30ad\u30fc\u30de\u4e00\u679a\u3060\u3051\u3092\u898b\u308b\u306e\u3067\u306f\u306a\u304f\u3001\u5c65\u6b74\u304b\u3089\u73fe\u5728\u72b6\u614b\u3078\u5230\u9054\u3067\u304d\u308b\u3053\u3068\u307e\u3067\u518d\u73fe\u53ef\u80fd\u6027\u306e\u4e00\u90e8\u3068\u3057\u3066\u6271\u3063\u3066\u3044\u308b\u3002<\/p>\n<p>\u3053\u306e\u691c\u67fb\u306f\u3001\u53c2\u7167\u5b9f\u88c5\u3068\u3044\u3046\u6027\u8cea\u3068\u76f4\u63a5\u95a2\u4fc2\u3059\u308b\u3002\u516c\u958b\u3055\u308c\u305f\u30bd\u30fc\u30b9\u304c\u52d5\u304f\u3060\u3051\u306a\u3089\u3001\u958b\u767a\u8005\u306e\u624b\u5143\u306b\u6b8b\u3063\u305f\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084\u751f\u6210\u7269\u306b\u3088\u3063\u3066\u5076\u7136\u6210\u529f\u3057\u3066\u3044\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u3002\u65b0\u3057\u3044 PostgreSQL \u3092 CI \u4e0a\u306b\u4f5c\u308a\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u6700\u521d\u304b\u3089\u9069\u7528\u3057\u3001\u751f\u6210\u30bd\u30fc\u30b9\u3082\u6b63\u672c\u304b\u3089\u518d\u751f\u6210\u3067\u304d\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3059\u308c\u3070\u3001\u300c\u65e2\u5b58\u74b0\u5883\u3092\u6301\u3063\u3066\u3044\u308b\u958b\u767a\u8005\u3060\u3051\u304c\u52d5\u304b\u305b\u308b\u300d\u3068\u3044\u3046\u6697\u9ed9\u4f9d\u5b58\u3092\u6e1b\u3089\u305b\u308b\u3002\u53c2\u7167\u5b9f\u88c5\u3067\u306f\u3001\u4f5c\u8005\u306e\u4f5c\u696d\u74b0\u5883\u3088\u308a\u7b2c\u4e09\u8005\u304c\u518d\u73fe\u3067\u304d\u308b\u72b6\u614b\u306e\u65b9\u304c\u91cd\u8981\u306b\u306a\u308b\u3002<\/p>\n<p>CDK synth \u3068\u5b9f\u969b\u306e\u30c7\u30d7\u30ed\u30a4\u3092\u5206\u3051\u3066\u3044\u308b\u3053\u3068\u306b\u3082\u610f\u5473\u304c\u3042\u308b\u3002\u901a\u5e38\u306e CI \u306f infrastructure \u30bd\u30fc\u30b9\u304c\u578b\u691c\u67fb\u3092\u901a\u308a\u3001CloudFormation template \u3078\u5408\u6210\u3067\u304d\u308b\u3068\u3053\u308d\u307e\u3067\u3092\u78ba\u8a8d\u3059\u308b\u3002\u5b9f\u969b\u306e AWS \u30ea\u30bd\u30fc\u30b9\u306e\u4f5c\u6210\u3001\u5909\u66f4\u3001\u524a\u9664\u306f\u5225\u306e\u30c7\u30d7\u30ed\u30a4\u64cd\u4f5c\u306b\u7f6e\u304d\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u306e\u9759\u7684\u306a\u6574\u5408\u6027\u78ba\u8a8d\u3068\u5b9f\u74b0\u5883\u3078\u306e\u5909\u66f4\u3092\u7570\u306a\u308b\u6a29\u9650\u5883\u754c\u3067\u6271\u3046\u3002<\/p>\n<p>\u30b3\u30f3\u30c6\u30ca\u30d3\u30eb\u30c9\u3082 verify job \u3068\u306f\u5225\u306e\u6545\u969c\u9762\u3092\u78ba\u8a8d\u3059\u308b\u3002TypeScript \u30d3\u30eb\u30c9\u304c\u901a\u3063\u3066\u3082 Dockerfile \u306e COPY \u5bfe\u8c61\u3001\u30d3\u30eb\u30c9 context\u3001production \u4f9d\u5b58\u95a2\u4fc2\u3001\u30b3\u30f3\u30c6\u30ca\u5185\u306e path \u306b\u554f\u984c\u304c\u3042\u308c\u3070\u30a4\u30e1\u30fc\u30b8\u306f\u751f\u6210\u3067\u304d\u306a\u3044\u3002OpenAPI \u3084\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u6574\u5408\u6027\u306f\u5225\u306e\u691c\u67fb\u304c\u62c5\u5f53\u3059\u308b\u305f\u3081\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u30bd\u30fc\u30b9\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3001API \u5951\u7d04\u3001infrastructure\u3001\u30b3\u30f3\u30c6\u30ca\u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\u3068\u3044\u3046\u7570\u306a\u308b\u6210\u679c\u7269\u3054\u3068\u306b\u691c\u67fb\u3092\u5206\u3051\u3066\u3044\u308b\u3002<\/p>\n<p>\u65e2\u7a3f\u300cAI \u304c\u30c6\u30b9\u30c8\u3092\u901a\u3057\u3066\u3082\u3001\u300c\u6b63\u3057\u3044\u300d\u3068\u306f\u9650\u3089\u306a\u3044\u300d\u3067\u306f\u3001\u30c6\u30b9\u30c8\u3092\u4ed5\u69d8\u5168\u4f53\u305d\u306e\u3082\u306e\u3068\u3057\u3066\u6271\u3046\u306e\u3067\u306f\u306a\u304f\u3001\u4ed5\u69d8\u306e\u3046\u3061\u6a5f\u68b0\u7684\u306b\u89b3\u6e2c\u3067\u304d\u308b\u6761\u4ef6\u3092\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u3078\u5199\u50cf\u3057\u305f\u3082\u306e\u3068\u3057\u3066\u6574\u7406\u3057\u305f<a href=\"#ref29\">[29]<\/a>\u3002spa-reference \u306e CI \u3082\u540c\u3058\u69cb\u9020\u3092\u6301\u3064\u3002\u81ea\u52d5\u30c6\u30b9\u30c8\u304c\u8a3c\u660e\u3059\u308b\u7bc4\u56f2\u306f\u3001\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u3068\u3057\u3066\u6a5f\u68b0\u7684\u306b\u89b3\u6e2c\u3067\u304d\u308b\u6761\u4ef6\u306b\u5bfe\u5fdc\u3059\u308b\u3002<\/p>\n<p>\u6587\u66f8\u306b\u3064\u3044\u3066\u3082\u540c\u69d8\u3067\u3042\u308b\u3002CI \u304c\u76f4\u63a5\u7167\u5408\u3067\u304d\u308b\u306e\u306f\u3001OpenAPI\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u30b9\u30ad\u30fc\u30de\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u30bd\u30fc\u30b9\u3001\u30d3\u30eb\u30c9\u6210\u679c\u7269\u306e\u3088\u3046\u306b\u6a5f\u68b0\u7684\u306a\u5bfe\u5fdc\u95a2\u4fc2\u3092\u5b9a\u7fa9\u3067\u304d\u308b\u90e8\u5206\u304c\u4e2d\u5fc3\u306b\u306a\u308b\u3002README \u306b\u66f8\u304b\u308c\u305f\u8aac\u660e\u306e\u610f\u5473\u304c\u8a2d\u8a08\u601d\u60f3\u3068\u4e00\u81f4\u3057\u3066\u3044\u308b\u304b\u3001BASIC_DESIGN \u306e\u8cac\u52d9\u8aac\u660e\u304c\u73fe\u5728\u306e\u30bd\u30fc\u30b9\u69cb\u9020\u3092\u9069\u5207\u306b\u62bd\u8c61\u5316\u3057\u3066\u3044\u308b\u304b\u3001\u3068\u3044\u3063\u305f\u610f\u5473\u8ad6\u306f\u4eba\u9593\u306e\u30ec\u30d3\u30e5\u30fc\u304c\u53d7\u3051\u6301\u3064\u3002\u6587\u66f8\u3068 CI \u306f\u76f8\u88dc\u7684\u3067\u3042\u308a\u3001\u89b3\u6e2c\u53ef\u80fd\u306a\u5bfe\u8c61\u304c\u7570\u306a\u308b\u3002<\/p>\n<p>green CI \u304c\u793a\u3059\u306e\u306f\u3001\u73fe\u5728\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u691c\u67fb\u6761\u4ef6\u3092\u6e80\u305f\u3057\u305f\u3068\u3044\u3046\u4e8b\u5b9f\u3067\u3042\u308b\u3002\u8981\u4ef6\u304c\u4e0d\u8db3\u3057\u3066\u3044\u308c\u3070\u3001\u305d\u306e\u4e0d\u8db3\u3092\u5fe0\u5b9f\u306b\u5b9f\u88c5\u3057\u305f\u30b3\u30fc\u30c9\u3067\u3082 CI \u306f\u901a\u308a\u5f97\u308b\u3002\u30c6\u30b9\u30c8\u30b1\u30fc\u30b9\u304c\u6271\u3046\u6761\u4ef6\u306e\u7bc4\u56f2\u306b\u3088\u3063\u3066\u3001\u691c\u51fa\u3067\u304d\u308b defect \u306e\u7bc4\u56f2\u3082\u6c7a\u307e\u308b\u3002\u691c\u8a3c\u7d50\u679c\u306e\u4fdd\u8a3c\u7bc4\u56f2\u306f\u3001\u691c\u67fb\u5bfe\u8c61\u3068\u89b3\u6e2c\u65b9\u6cd5\u306b\u5bfe\u5fdc\u3059\u308b\u3002<\/p>\n<p>\u3053\u306e\u9650\u5b9a\u304c\u3042\u308b\u304b\u3089\u3053\u305d CI \u306e\u5f79\u5272\u304c\u660e\u78ba\u306b\u306a\u308b\u3002\u4eba\u9593\u304c\u6bce\u56de package-lock.json\u3001\u751f\u6210\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3 history\u3001OpenAPI\u3001CDK\u3001Dockerfile \u306e\u5bfe\u5fdc\u3092\u624b\u4f5c\u696d\u3067\u78ba\u8a8d\u3059\u308b\u3068\u3001\u78ba\u8a8d\u6f0f\u308c\u304c\u7d99\u7d9a\u7684\u306b\u767a\u751f\u3059\u308b\u3002\u6a5f\u68b0\u7684\u306b\u5224\u5b9a\u3067\u304d\u308b\u4e0d\u5909\u6761\u4ef6\u3092 CI \u3078\u79fb\u3059\u3053\u3068\u3067\u3001\u4eba\u9593\u306e\u30ec\u30d3\u30e5\u30fc\u306f\u300c\u8981\u6c42\u3068\u8a2d\u8a08\u306e\u610f\u5473\u304c\u6b63\u3057\u3044\u304b\u300d\u300c\u3053\u306e\u5909\u66f4\u7406\u7531\u3067\u3053\u306e\u5883\u754c\u3092\u5909\u3048\u3066\u3088\u3044\u304b\u300d\u3068\u3044\u3063\u305f\u3001\u81ea\u52d5\u5316\u3057\u306b\u304f\u3044\u5224\u65ad\u3078\u96c6\u4e2d\u3067\u304d\u308b\u3002<\/p>\n<p>spa-reference \u306e CI \u306f\u672c\u756a\u8a8d\u8a3c\u60c5\u5831\u304b\u3089\u72ec\u7acb\u3057\u3001\u901a\u5e38\u306e\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u306f\u30ea\u30dd\u30b8\u30c8\u30ea\u691c\u8a3c\u306b\u5c02\u5ff5\u3059\u308b\u3002\u3053\u306e\u5236\u7d04\u3082\u691c\u8a3c\u8a2d\u8a08\u306e\u4e00\u90e8\u3067\u3042\u308b\u3002PostgreSQL \u30b5\u30fc\u30d3\u30b9\u3001\u30c6\u30b9\u30c8 double\u3001CDK synth\u3001\u30b3\u30f3\u30c6\u30ca\u30d3\u30eb\u30c9\u307e\u3067\u3092\u30d7\u30eb\u30ea\u30af\u30a8\u30b9\u30c8\u5185\u3067\u5b8c\u7d50\u3055\u305b\u3001\u672c\u756a\u74b0\u5883\u306e\u5909\u66f4\u3092\u5225\u306e\u64cd\u4f5c\u3078\u5206\u96e2\u3059\u308b\u3053\u3068\u3067\u3001\u516c\u958b\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u5909\u66f4\u3092\u7b2c\u4e09\u8005\u304c\u540c\u3058\u6761\u4ef6\u3067\u691c\u8a3c\u3057\u3084\u3059\u304f\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>\u53c2\u7167\u5b9f\u88c5\u306f\u516c\u958b\u5f8c\u3082\u5909\u5316\u3059\u308b\u3002\u4f9d\u5b58\u95a2\u4fc2\u306f\u66f4\u65b0\u3055\u308c\u3001\u30bd\u30fc\u30b9\u306f\u5909\u66f4\u3055\u308c\u3001OpenAPI \u306f\u62e1\u5f35\u3055\u308c\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30b9\u30ad\u30fc\u30de\u306f\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u91cd\u306d\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u5b9a\u7fa9\u3082\u5909\u5316\u3059\u308b\u3002\u5909\u66f4\u306e\u305f\u3073\u306b\u5bfe\u5fdc\u95a2\u4fc2\u3092\u4eba\u9593\u306e\u8a18\u61b6\u3060\u3051\u3067\u7dad\u6301\u3059\u308b\u3068\u3001\u6642\u9593\u306e\u7d4c\u904e\u3068\u3068\u3082\u306b\u30bd\u30fc\u30b9\u3068\u751f\u6210\u7269\u3001\u5951\u7d04\u3068\u5b9f\u88c5\u3001\u30b9\u30ad\u30fc\u30de\u3068\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u305a\u308c\u304c\u84c4\u7a4d\u3059\u308b\u3002CI \u306f\u3001\u305d\u306e\u6642\u9593\u65b9\u5411\u306e\u305a\u308c\u3092\u5909\u66f4\u3054\u3068\u306b\u518d\u691c\u67fb\u3059\u308b\u4ed5\u7d44\u307f\u3067\u3042\u308b\u3002<\/p>\n<p>\u3053\u306e\u610f\u5473\u3067 CI \u306f\u3001spa-reference \u304c\u300c\u73fe\u5728\u306e master \u306f\u3053\u306e\u69cb\u9020\u3092\u6e80\u305f\u3057\u3066\u3044\u308b\u300d\u3068\u4e3b\u5f35\u3059\u308b\u305f\u3081\u306e\u5b9f\u884c\u53ef\u80fd\u306a\u8a3c\u62e0\u306e\u4e00\u90e8\u306b\u306a\u3063\u3066\u3044\u308b\u3002\u6587\u66f8\u304c\u8981\u4ef6\u3068\u8a2d\u8a08\u5224\u65ad\u3092\u4fdd\u6301\u3057\u3001OpenAPI \u304c\u901a\u4fe1\u5951\u7d04\u3092\u4fdd\u6301\u3057\u3001\u30bd\u30fc\u30b9\u304c\u305d\u308c\u3089\u3092\u5b9f\u88c5\u3057\u3001CI \u304c\u6a5f\u68b0\u7684\u306b\u89b3\u6e2c\u3067\u304d\u308b\u5bfe\u5fdc\u95a2\u4fc2\u3092\u7d99\u7d9a\u3057\u3066\u691c\u67fb\u3059\u308b\u3002\u7570\u306a\u308b\u8868\u73fe\u3092\u76f8\u4e92\u306b\u7167\u5408\u3059\u308b\u3053\u3068\u3067\u3001\u53c2\u7167\u5b9f\u88c5\u3092\u4e00\u5ea6\u4f5c\u3063\u305f\u6210\u679c\u7269\u304b\u3089\u7d99\u7d9a\u7684\u306b\u691c\u8a3c\u3055\u308c\u308b\u57fa\u6e96\u70b9\u3078\u5909\u3048\u3066\u3044\u308b\u3002<\/p>\n<hr>\n<h2>10. reference \u306f\u6761\u4ef6\u4ed8\u304d\u306e\u57fa\u6e96\u70b9\u3067\u3042\u308b<\/h2>\n<p>spa-reference \u3092\u300cReact\u3001NestJS\u3001AWS \u3092\u4f7f\u3063\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u300d\u3068\u8981\u7d04\u3059\u308b\u3068\u3001\u5b9f\u88c5\u306b\u73fe\u308c\u305f\u88fd\u54c1\u540d\u3060\u3051\u304c\u6b8b\u308b\u3002\u3057\u304b\u3057\u3001\u3053\u3053\u307e\u3067\u898b\u3066\u304d\u305f\u69cb\u9020\u3092\u9006\u5411\u304d\u306b\u305f\u3069\u308b\u3068\u3001\u6280\u8853\u30b9\u30bf\u30c3\u30af\u3088\u308a\u4e0a\u4f4d\u306b\u3042\u308b\u5224\u65ad\u306e\u9023\u9396\u304c\u898b\u3048\u308b\u3002\u5bfe\u8c61\u3092\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u4e2d\u5fc3\u306e\u696d\u52d9 SPA \u306b\u9650\u5b9a\u3057\u3001\u73fe\u5728\u5fc5\u8981\u306a\u8cac\u52d9\u3060\u3051\u3092\u5b9f\u88c5\u3057\u3001\u5c06\u6765\u5206\u96e2\u53ef\u80fd\u306a\u5883\u754c\u3092\u5148\u306b\u4f5c\u308b\u3002\u30d6\u30e9\u30a6\u30b6\u5411\u3051 HTTP \u5951\u7d04\u3092 OpenAPI \u306b\u7f6e\u304d\u3001\u8a8d\u8a3c\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3068\u696d\u52d9\u4e0a\u306e\u8a8d\u53ef\u3092\u5206\u96e2\u3059\u308b\u3002PostgreSQL \u306e\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5185\u3067\u78ba\u5b9a\u3067\u304d\u308b\u4e8b\u5b9f\u3068\u3001SES \u3084 SNS \u306e\u3088\u3046\u306a\u5916\u90e8\u526f\u4f5c\u7528\u3092\u5206\u3051\u308b\u3002AWS \u56fa\u6709\u51e6\u7406\u3092\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u30a2\u30c0\u30d7\u30bf\u30fc\u3078\u9589\u3058\u8fbc\u3081\u3001\u540c\u3058\u696d\u52d9\u610f\u5473\u8ad6\u3092\u30ed\u30fc\u30ab\u30eb\u3067\u3082\u5b9f\u884c\u3059\u308b\u3002\u6700\u5f8c\u306b\u3001\u4ed5\u69d8\u3001\u751f\u6210\u7269\u3001\u5b9f\u88c5\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u30a4\u30f3\u30d5\u30e9\u30b9\u30c8\u30e9\u30af\u30c1\u30e3\u306e\u5bfe\u5fdc\u95a2\u4fc2\u3092 CI \u3067\u7d99\u7d9a\u7684\u306b\u691c\u67fb\u3059\u308b\u3002\u3053\u306e\u9023\u9396\u5168\u4f53\u304c spa-reference \u306e\u53c2\u7167\u5bfe\u8c61\u3067\u3042\u308b\u3002<\/p>\n<p>\u3053\u3053\u3067 reference \u3068\u3044\u3046\u8a9e\u304c\u91cd\u8981\u306b\u306a\u308b\u3002template \u3092\u4f7f\u3046\u4e3b\u76ee\u7684\u306f\u3001\u65e2\u77e5\u306e\u521d\u671f\u69cb\u9020\u3092\u8907\u88fd\u3057\u3066\u958b\u767a\u958b\u59cb\u307e\u3067\u306e\u6642\u9593\u3092\u77ed\u7e2e\u3059\u308b\u3053\u3068\u306b\u3042\u308b\u3002reference \u306f\u3001\u305d\u308c\u306b\u52a0\u3048\u3066\u300c\u306a\u305c\u3053\u306e\u69cb\u9020\u3092\u9078\u3093\u3060\u304b\u300d\u3092\u6bd4\u8f03\u5bfe\u8c61\u3068\u3057\u3066\u6b8b\u3059\u3002\u63a1\u7528\u5148\u3067\u306f\u3001\u5143\u306e\u9078\u629e\u3092\u6210\u7acb\u3055\u305b\u3066\u3044\u305f\u8981\u4ef6\u3068\u5236\u7d04\u3092\u8aad\u307f\u53d6\u308a\u3001\u81ea\u5206\u306e\u6761\u4ef6\u3068\u306e\u5dee\u5206\u304b\u3089\u3001\u7dad\u6301\u3059\u3079\u304d\u5224\u65ad\u3068\u5909\u66f4\u3059\u3079\u304d\u5224\u65ad\u3092\u8b58\u5225\u3059\u308b\u3002\u3053\u306e\u8aad\u307f\u66ff\u3048\u306b\u3088\u3063\u3066\u3001\u540c\u3058\u6280\u8853\u3092\u63a1\u7528\u3059\u308b\u5834\u5408\u306b\u3082\u5225\u306e\u6280\u8853\u3078\u7f6e\u304d\u63db\u3048\u308b\u5834\u5408\u306b\u3082\u57fa\u6e96\u70b9\u3068\u3057\u3066\u5229\u7528\u3067\u304d\u308b\u3002<\/p>\n<p>\u305d\u306e\u305f\u3081\u3001spa-reference \u306b\u542b\u307e\u308c\u308b\u9078\u629e\u306b\u306f\u56fa\u5b9a\u5ea6\u306e\u5dee\u304c\u3042\u308b\u3002\u305f\u3068\u3048\u3070\u3001\u5229\u7528\u8005\u306e role \u3092\u691c\u8a3c\u6e08\u307f identity \u304b\u3089\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u3067\u5c0e\u304f\u3053\u3068\u3001\u5916\u90e8\u914d\u9001\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5f8c\u306e\u526f\u4f5c\u7528\u3068\u3057\u3066\u5206\u3051\u308b\u3053\u3068\u3001\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u5951\u7d04\u3092\u5185\u90e8\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u578b\u304b\u3089\u5206\u96e2\u3059\u308b\u3053\u3068\u306f\u3001\u73fe\u5728\u306e\u8981\u4ef6\u3068\u5b89\u5168\u6027\u304b\u3089\u5f37\u304f\u5c0e\u304b\u308c\u308b\u3002\u4e00\u65b9\u3001React\u3001NestJS\u3001Prisma\u3001AWS CDK \u306f\u3001\u305d\u308c\u3089\u306e\u8cac\u52d9\u3092\u73fe\u5728\u306e\u53c2\u7167\u57fa\u6e96\u3067\u5177\u4f53\u5316\u3057\u305f\u6280\u8853\u3067\u3042\u308b\u3002\u524d\u8005\u3092\u5909\u66f4\u3059\u308b\u306a\u3089\u8981\u4ef6\u3084\u4fdd\u8a3c\u7bc4\u56f2\u305d\u306e\u3082\u306e\u3092\u518d\u691c\u8a0e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u3001\u5f8c\u8005\u3092\u5909\u66f4\u3059\u308b\u5834\u5408\u306f\u4e0a\u4f4d\u306e\u5951\u7d04\u3092\u7dad\u6301\u3067\u304d\u308b\u304b\u304c\u5224\u65ad\u57fa\u6e96\u306b\u306a\u308b\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u6761\u4ef6\u304c\u5909\u308f\u308b\u4f8b<\/th>\n<th>\u73fe\u5728\u306e\u57fa\u6e96\u70b9<\/th>\n<th>\u518d\u691c\u8a0e\u3055\u308c\u308b\u5224\u65ad<\/th>\n<th>\u7dad\u6301\u3059\u3079\u304d\u554f\u3044<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u691c\u7d22\u6d41\u5165\u3068\u521d\u671f\u8868\u793a\u304c\u4e3b\u8981\u8981\u4ef6\u306b\u306a\u308b<\/td>\n<td>React \u306e\u30d6\u30e9\u30a6\u30b6 SPA<\/td>\n<td>SSR\u3001SSG\u3001hybrid rendering \u3092\u542b\u3081\u305f\u30d5\u30ed\u30f3\u30c8\u30a8\u30f3\u30c9\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u3092\u518d\u691c\u8a0e\u3059\u308b\u3002<\/td>\n<td>\u4e3b\u8981\u5229\u7528\u8005\u304c\u3069\u306e\u7d4c\u8def\u3067\u5230\u9054\u3057\u3001\u3069\u306e\u6642\u70b9\u3067\u3069\u306e\u60c5\u5831\u3092\u8868\u793a\u3067\u304d\u308b\u5fc5\u8981\u304c\u3042\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u8907\u6570\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u5927\u304d\u304f\u7570\u306a\u308b\u8981\u6c42\u3092\u6301\u3064<\/td>\n<td>\u4e00\u3064\u306e Web SPA \u306b\u5bfe\u3059\u308b\u4e00\u3064\u306e BFF<\/td>\n<td>\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3054\u3068\u306e BFF \u5206\u5272\u3084 API \u96c6\u7d04\u306e\u5883\u754c\u3092\u518d\u691c\u8a0e\u3059\u308b\u3002<\/td>\n<td>\u3069\u306e\u5951\u7d04\u304c\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u56fa\u6709\u3067\u3001\u3069\u306e\u6a5f\u80fd\u304c\u5171\u901a\u306a\u306e\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u6a5f\u80fd\u3054\u3068\u306b\u72ec\u7acb\u30c1\u30fc\u30e0\u3068\u30ea\u30ea\u30fc\u30b9\u30b5\u30a4\u30af\u30eb\u304c\u6210\u7acb\u3059\u308b<\/td>\n<td>\u4e00\u3064\u306e\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u3068\u5185\u90e8\u6a5f\u80fd\u5883\u754c<\/td>\n<td>\u4e00\u90e8\u6a5f\u80fd\u306e\u30b5\u30fc\u30d3\u30b9\u5206\u5272\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5951\u7d04\u3001failure recovery \u3092\u518d\u691c\u8a0e\u3059\u308b\u3002<\/td>\n<td>\u5206\u6563\u306b\u3088\u3063\u3066\u5f97\u308b\u72ec\u7acb\u6027\u304c\u3001\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u3001\u518d\u8a66\u884c\u3001\u53ef\u89b3\u6e2c\u6027\u3001\u904b\u7528\u8cbb\u7528\u3092\u4e0a\u56de\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>AWS \u4ee5\u5916\u306e cloud \u304c\u73fe\u5728\u8981\u4ef6\u306b\u306a\u308b<\/td>\n<td>AWS \u30a2\u30c0\u30d7\u30bf\u30fc\u3068 AWS CDK<\/td>\n<td>\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u5b9f\u88c5\u3001IaC\u3001\u30c7\u30d7\u30ed\u30a4\u30c8\u30dd\u30ed\u30b8\u30fc\u3092\u518d\u691c\u8a0e\u3059\u308b\u3002<\/td>\n<td>\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5951\u7d04\u3068 domain \u610f\u5473\u8ad6\u306e\u3069\u3053\u307e\u3067\u3092\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u304b\u3089\u72ec\u7acb\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u5f37\u3044\u975e\u540c\u671f\u51e6\u7406\u3084\u5927\u91cf\u30a4\u30d9\u30f3\u30c8\u51e6\u7406\u304c\u4e2d\u5fc3\u306b\u306a\u308b<\/td>\n<td>\u540c\u671f HTTP \u3068\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u4e2d\u5fc3\u3068\u3059\u308b\u696d\u52d9 SPA<\/td>\n<td>message broker\u3001\u30a4\u30d9\u30f3\u30c8-driven processing\u3001\u30c7\u30fc\u30bf\u6240\u6709\u6a29\u3001\u4e00\u8cab\u6027\u30e2\u30c7\u30eb\u3092\u518d\u691c\u8a0e\u3059\u308b\u3002<\/td>\n<td>\u3069\u306e\u696d\u52d9\u4e8b\u5b9f\u3092\u540c\u671f\u7684\u306b\u78ba\u5b9a\u3057\u3001\u3069\u3053\u304b\u3089 eventual consistency \u3092\u8a31\u5bb9\u3059\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<tr>\n<td>\u65e2\u5b58\u7d44\u7e54\u6a19\u6e96\u304c React\u3001NestJS\u3001AWS \u4ee5\u5916\u306b\u3042\u308b<\/td>\n<td>\u73fe\u5728\u306e\u6280\u8853\u30b9\u30bf\u30c3\u30af<\/td>\n<td>\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3001\u5b9f\u884c\u6642\u3001cloud \u306e\u5177\u4f53\u7684\u5b9f\u88c5\u3092\u7f6e\u304d\u63db\u3048\u308b\u3002<\/td>\n<td>\u516c\u958b\u5951\u7d04\u3001\u8a8d\u53ef\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5883\u754c\u3001\u969c\u5bb3\u6642\u4fdd\u8a3c\u3092\u540c\u7b49\u306b\u7dad\u6301\u3067\u304d\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u6761\u4ef6\u5909\u66f4\u306f\u88fd\u54c1\u540d\u3060\u3051\u3067\u306a\u304f\u8cac\u52d9\u5883\u754c\u306b\u3082\u53ca\u3076\u3002\u516c\u958b\u30b3\u30f3\u30c6\u30f3\u30c4\u4e2d\u5fc3\u306e\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u3001\u30d6\u30e9\u30a6\u30b6\u30bb\u30c3\u30b7\u30e7\u30f3\u4e2d\u306e\u72b6\u614b\u64cd\u4f5c\u3088\u308a\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u3068\u30ad\u30e3\u30c3\u30b7\u30e5\u306e\u8a2d\u8a08\u304c\u524d\u9762\u306b\u51fa\u308b\u3002\u72ec\u7acb\u3057\u305f\u30c1\u30fc\u30e0\u304c\u6a5f\u80fd\u5883\u754c\u3054\u3068\u306b\u5b58\u5728\u3059\u308b\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u3001\u540c\u4e00\u30d7\u30ed\u30bb\u30b9\u306e\u5358\u7d14\u3055\u3088\u308a\u3001\u72ec\u7acb\u30c7\u30d7\u30ed\u30a4\u3068\u969c\u5bb3\u9694\u96e2\u306e\u4fa1\u5024\u304c\u9ad8\u304f\u306a\u308b\u3002\u5927\u91cf\u306e\u975e\u540c\u671f\u30a4\u30d9\u30f3\u30c8\u3092\u6271\u3046\u30b7\u30b9\u30c6\u30e0\u3067\u306f\u3001\u4e00\u3064\u306e\u95a2\u4fc2\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3078\u96c6\u7d04\u3059\u308b\u69cb\u6210\u3068 eventual consistency \u3092\u660e\u793a\u3059\u308b\u69cb\u6210\u3092\u3001\u696d\u52d9\u8981\u4ef6\u304b\u3089\u6bd4\u8f03\u3059\u308b\u3002reference \u3092\u4f7f\u3046\u3068\u306f\u3001\u3053\u306e\u6761\u4ef6\u5dee\u3092\u5224\u65ad\u3059\u308b\u3053\u3068\u3067\u3042\u308b\u3002<\/p>\n<p>\u518d\u5229\u7528\u3067\u304d\u308b\u306e\u306f\u3001\u6700\u521d\u306b\u5bfe\u8c61\u3092\u9650\u5b9a\u3057\u3001\u4f55\u3092\u540c\u6642\u306b\u6210\u7acb\u3055\u305b\u308b\u5fc5\u8981\u304c\u3042\u308b\u304b\u3092\u6c7a\u3081\u3001\u5229\u7528\u8005\u304b\u3089\u89b3\u6e2c\u3055\u308c\u308b\u5951\u7d04\u3092\u5b9a\u7fa9\u3057\u3001\u5916\u90e8\u4f9d\u5b58\u3068\u306e\u5883\u754c\u3092\u7f6e\u304d\u3001\u5fc5\u8981\u306a\u8907\u96d1\u6027\u3060\u3051\u3092\u5c0e\u5165\u3057\u3001\u305d\u306e\u5224\u65ad\u3092\u5b9f\u88c5\u3068\u691c\u8a3c\u3078\u5bfe\u5fdc\u4ed8\u3051\u308b\u3068\u3044\u3046\u9806\u5e8f\u3067\u3042\u308b\u3002React \u3084 AWS \u3092\u7f6e\u304d\u63db\u3048\u3066\u3082\u3001\u3053\u306e\u9806\u5e8f\u306f\u8a2d\u8a08\u5224\u65ad\u3092\u5c0e\u304f\u65b9\u6cd5\u3068\u3057\u3066\u6b8b\u308b\u3002<\/p>\n<p>spa-reference \u306e\u300cSimplicity is robustness.\u300d\u306f\u3001reference \u3092\u66f4\u65b0\u3059\u308b\u305f\u3081\u306e\u5224\u65ad\u898f\u5247\u3068\u3057\u3066\u50cd\u304f\u3002\u5c06\u6765\u8981\u4ef6\u304c\u5897\u3048\u305f\u3068\u304d\u306f\u3001\u65b0\u3057\u3044\u8981\u4ef6\u304c\u3069\u306e\u5883\u754c\u3092\u5b9f\u969b\u306b\u5909\u3048\u308b\u306e\u304b\u3092\u78ba\u8a8d\u3057\u3001\u65e2\u5b58\u306e\u69cb\u9020\u3067\u6e80\u305f\u305b\u308b\u90e8\u5206\u306f\u7dad\u6301\u3057\u3001\u8ffd\u52a0\u8981\u4ef6\u3092\u53d7\u3051\u6301\u3064\u90e8\u5206\u3078\u65b0\u3057\u3044\u72b6\u614b\u3001\u4f9d\u5b58\u95a2\u4fc2\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u5883\u754c\u3001\u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u3092\u914d\u7f6e\u3059\u308b\u3002\u5909\u66f4\u7bc4\u56f2\u3092\u8981\u4ef6\u5dee\u5206\u3078\u5bfe\u5fdc\u3055\u305b\u308b\u3053\u3068\u3067\u3001reference \u306e\u8907\u96d1\u6027\u3092\u5236\u5fa1\u3059\u308b\u3002<\/p>\n<p>reference \u304c\u6761\u4ef6\u4ed8\u304d\u3067\u3042\u308b\u3053\u3068\u3068\u3001\u73fe\u5728\u306e\u6761\u4ef6\u306b\u5bfe\u3059\u308b\u5177\u4f53\u6027\u306f\u4e21\u7acb\u3059\u308b\u3002spa-reference \u306f\u73fe\u5728\u306e\u6761\u4ef6\u306b\u5bfe\u3057\u3066\u3001\u30d0\u30c3\u30af\u30a8\u30f3\u30c9\u306f\u4e00\u3064\u306e NestJS \u30c7\u30d7\u30ed\u30a4\u53ef\u80fd\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306f PostgreSQL \u4e92\u63db\u306e\u6c38\u7d9a\u5316\u3001AWS \u30e2\u30fc\u30c9\u306e identity \u30d7\u30ed\u30d0\u30a4\u30c0\u30fc\u306f Cognito\u3001\u30d6\u30e9\u30a6\u30b6\u5411\u3051\u5951\u7d04\u306f OpenAPI 3.1\u3001\u5916\u90e8\u914d\u9001\u306b\u306f transactional outbox\u3001\u30ed\u30fc\u30ab\u30eb\u30c7\u30e2\u3067\u306f PostgreSQL 17 \u3092 Docker Compose \u3067\u8d77\u52d5\u3059\u308b\u3068\u3044\u3046\u5177\u4f53\u7684\u306a\u7b54\u3048\u3092\u6301\u3064\u3002\u305d\u306e\u9078\u629e\u3092\u6210\u7acb\u3055\u305b\u3066\u3044\u308b\u6761\u4ef6\u3082\u540c\u6642\u306b\u6b8b\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>reference \u306f\u3001\u62bd\u8c61\u7684\u306a\u8a2d\u8a08\u8ad6\u3068\u52d5\u304f\u30b3\u30fc\u30c9\u3092\u63a5\u7d9a\u3059\u308b\u4e2d\u9593\u5c64\u3068\u3057\u3066\u6a5f\u80fd\u3059\u308b\u3002transaction\u3001\u8a8d\u53ef\u3001outbox\u3001\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3001\u30c7\u30d7\u30ed\u30a4\u3068\u3044\u3063\u305f\u5177\u4f53\u7684\u306a\u554f\u984c\u3078\u62bd\u8c61\u539f\u5247\u3092\u9069\u7528\u3057\u3001\u305d\u306e\u7d50\u679c\u3092\u5b9f\u969b\u306b\u52d5\u304f\u30b3\u30fc\u30c9\u3078\u5199\u3059\u3002\u3055\u3089\u306b\u3001\u305d\u306e\u30b3\u30fc\u30c9\u304b\u3089\u8981\u4ef6\u3068\u8a2d\u8a08\u5224\u65ad\u3078\u623b\u308c\u308b\u3088\u3046\u306b\u3059\u308b\u3053\u3068\u3067\u3001\u5177\u4f53\u4f8b\u3068\u4e0a\u4f4d\u539f\u5247\u3092\u5f80\u5fa9\u3057\u3066\u8aad\u3081\u308b\u3002<\/p>\n<p>\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306f\u3001\u8981\u6c42\u306b\u5bfe\u3057\u3066\u3069\u306e\u8cac\u52d9\u3092\u4e00\u7dd2\u306b\u78ba\u5b9a\u3057\u3001\u3069\u306e\u8cac\u52d9\u3092\u5206\u96e2\u3057\u3001\u3069\u306e\u5931\u6557\u3092\u8a31\u5bb9\u3057\u3001\u3069\u306e\u5931\u6557\u3092\u5951\u7d04\u9055\u53cd\u3068\u3057\u3001\u3069\u3053\u307e\u3067\u3092\u81ea\u52d5\u56de\u5fa9\u3055\u305b\u308b\u304b\u3068\u3044\u3046\u5224\u65ad\u306e\u84c4\u7a4d\u3067\u3042\u308b\u3002PostgreSQL \u3092\u9078\u3076\u3053\u3068\u3088\u308a\u5148\u306b\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u5883\u754c\u304c\u3042\u308a\u3001Cognito \u3092\u9078\u3076\u3053\u3068\u3088\u308a\u5148\u306b\u8a8d\u8a3c\u3068\u8a8d\u53ef\u306e\u5206\u96e2\u304c\u3042\u308a\u3001Fargate \u3092\u9078\u3076\u3053\u3068\u3088\u308a\u5148\u306b\u73fe\u5728\u5fc5\u8981\u306a\u30c7\u30d7\u30ed\u30a4\u5358\u4f4d\u304c\u3042\u308b\u3002\u6280\u8853\u306f\u3001\u305d\u306e\u5224\u65ad\u3092\u73fe\u5728\u306e\u6761\u4ef6\u3067\u5b9f\u884c\u53ef\u80fd\u306b\u3057\u305f\u5177\u4f53\u7269\u3068\u3057\u3066\u4f4d\u7f6e\u4ed8\u3051\u3089\u308c\u308b\u3002<\/p>\n<p>spa-reference \u304c\u516c\u958b\u3057\u3066\u3044\u308b\u306e\u306f\u3001\u305d\u306e\u5177\u4f53\u7269\u3068\u5224\u65ad\u306e\u4e21\u65b9\u3067\u3042\u308b\u3002requirements \u304c\u5bfe\u8c61\u3068\u4fdd\u8a3c\u7bc4\u56f2\u3092\u5b9a\u3081\u3001design \u304c\u8cac\u52d9\u3068\u51e6\u7406\u610f\u5473\u3092\u5b9a\u3081\u3001policy \u304c\u5909\u66f4\u6642\u306e\u5224\u65ad\u898f\u5247\u3092\u5b9a\u3081\u3001OpenAPI \u304c\u5916\u90e8\u5951\u7d04\u3092\u5b9a\u3081\u3001\u30bd\u30fc\u30b9\u304c\u305d\u308c\u3089\u3092\u5b9f\u884c\u3057\u3001tests \u3068 CI \u304c\u6a5f\u68b0\u7684\u306b\u89b3\u6e2c\u3067\u304d\u308b\u5bfe\u5fdc\u95a2\u4fc2\u3092\u691c\u67fb\u3057\u3001infrastructure \u304c\u672c\u756a\u30c8\u30dd\u30ed\u30b8\u30fc\u3078\u5177\u4f53\u5316\u3059\u308b\u3002\u4e00\u3064\u306e\u5224\u65ad\u304c\u8907\u6570\u306e\u6210\u679c\u7269\u3078\u5199\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u8aad\u8005\u306f\u300c\u4f55\u3092\u4f5c\u3063\u305f\u304b\u300d\u3068\u300c\u306a\u305c\u305d\u3046\u306a\u3063\u3066\u3044\u308b\u304b\u300d\u306e\u4e21\u65b9\u3092\u8ffd\u8de1\u3067\u304d\u308b\u3002<\/p>\n<p>\u3053\u306e\u610f\u5473\u3067 reference \u306f\u3001\u73fe\u5728\u6761\u4ef6\u306b\u5bfe\u3059\u308b\u5177\u4f53\u7684\u306a\u7b54\u3048\u3068\u3001\u6761\u4ef6\u5909\u5316\u6642\u306e\u518d\u5224\u65ad\u70b9\u3092\u6301\u3064\u57fa\u6e96\u70b9\u3067\u3042\u308b\u3002spa-reference \u306e\u4e2d\u5fc3\u306b\u3042\u308b\u306e\u306f\u3001\u8981\u4ef6\u304b\u3089\u8cac\u52d9\u5883\u754c\u3092\u5c0e\u304d\u3001\u4fdd\u8a3c\u7bc4\u56f2\u3092\u660e\u793a\u3057\u3001\u5fc5\u8981\u306a\u8907\u96d1\u6027\u3060\u3051\u3092\u6280\u8853\u3078\u5909\u63db\u3057\u3001\u305d\u306e\u5224\u65ad\u3092\u5b9f\u88c5\u3068\u691c\u8a3c\u3078\u4e00\u8cab\u3057\u3066\u6b8b\u3059\u3068\u3044\u3046\u8a2d\u8a08\u65b9\u6cd5\u3067\u3042\u308b\u3002<\/p>\n<hr>\n<h2>\u53c2\u8003\u6587\u732e<\/h2>\n<ol>\n<li id=\"ref1\">id774, spa-reference README. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/README.md\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/README.md<\/a><\/li>\n<li id=\"ref2\">id774, Requirements: an SPA development reference application. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/REQUIREMENTS.md\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/REQUIREMENTS.md<\/a><\/li>\n<li id=\"ref3\">Martin Fowler, Sensible Default\uff082026-09-29\uff09. <a href=\"https:\/\/martinfowler.com\/bliki\/SensibleDefault.html\">https:\/\/martinfowler.com\/bliki\/SensibleDefault.html<\/a><\/li>\n<li id=\"ref4\">id774, Policy: implementation and maintenance rules. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/POLICY.md\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/POLICY.md<\/a><\/li>\n<li id=\"ref5\">id774, \u7406\u89e3\u30fb\u8a2d\u8a08\u30fb\u5236\u5ea6\u306f\u306a\u305c\u5358\u7d14\u5316\u3078\u53ce\u675f\u3059\u308b\u306e\u304b\uff082026-02-16\uff09. <a href=\"https:\/\/blog.id774.net\/entry\/2026\/02\/16\/3660\/\">https:\/\/blog.id774.net\/entry\/2026\/02\/16\/3660\/<\/a><\/li>\n<li id=\"ref6\">Herbert A. Simon, The Architecture of Complexity\uff081962-12-12\uff09. <a href=\"https:\/\/www.jstor.org\/stable\/985254\">https:\/\/www.jstor.org\/stable\/985254<\/a><\/li>\n<li id=\"ref7\">D. L. Parnas, On the Criteria To Be Used in Decomposing Systems into Modules\uff081972-12-01\uff09. <a href=\"https:\/\/doi.org\/10.1145\/361598.361623\">https:\/\/doi.org\/10.1145\/361598.361623<\/a><\/li>\n<li id=\"ref8\">id774, Basic design: an SPA development reference application. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/BASIC_DESIGN.md\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/BASIC_DESIGN.md<\/a><\/li>\n<li id=\"ref9\">Martin Fowler, Monolith First\uff082015-06-03\uff09. <a href=\"https:\/\/martinfowler.com\/bliki\/MonolithFirst.html\">https:\/\/martinfowler.com\/bliki\/MonolithFirst.html<\/a><\/li>\n<li id=\"ref10\">Microsoft, Backends for Frontends pattern. <a href=\"https:\/\/learn.microsoft.com\/azure\/architecture\/patterns\/backends-for-frontends\">https:\/\/learn.microsoft.com\/azure\/architecture\/patterns\/backends-for-frontends<\/a><\/li>\n<li id=\"ref11\">id774, Detailed design: an SPA development reference application. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/DETAILED_DESIGN.md\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/doc\/DETAILED_DESIGN.md<\/a><\/li>\n<li id=\"ref12\">PostgreSQL Global Development Group, Transaction Isolation. <a href=\"https:\/\/www.postgresql.org\/docs\/current\/transaction-iso.html\">https:\/\/www.postgresql.org\/docs\/current\/transaction-iso.html<\/a><\/li>\n<li id=\"ref13\">Prisma, Transactions and batch queries, Prisma ORM v7. <a href=\"https:\/\/docs.prisma.io\/docs\/orm\/v7\/prisma-client\/queries\/transactions\">https:\/\/docs.prisma.io\/docs\/orm\/v7\/prisma-client\/queries\/transactions<\/a><\/li>\n<li id=\"ref14\">Amazon Web Services, Transactional outbox pattern. <a href=\"https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/cloud-design-patterns\/transactional-outbox.html\">https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/cloud-design-patterns\/transactional-outbox.html<\/a><\/li>\n<li id=\"ref15\">OpenAPI Initiative, OpenAPI Specification v3.1.0\uff082021-02-15\uff09. <a href=\"https:\/\/spec.openapis.org\/oas\/v3.1.0.html\">https:\/\/spec.openapis.org\/oas\/v3.1.0.html<\/a><\/li>\n<li id=\"ref16\">N. Sakimura, J. Bradley, N. Agarwal, RFC 7636: Proof Key for Code Exchange by OAuth Public Clients\uff082015-09\uff09. <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc7636.html\">https:\/\/www.rfc-editor.org\/rfc\/rfc7636.html<\/a><\/li>\n<li id=\"ref17\">T. Lodderstedt, J. Bradley, A. Labunets, D. Fett, RFC 9700: Best Current Practice for OAuth 2.0 Security\uff082025-01\uff09. <a href=\"https:\/\/www.rfc-editor.org\/rfc\/rfc9700.html\">https:\/\/www.rfc-editor.org\/rfc\/rfc9700.html<\/a><\/li>\n<li id=\"ref18\">Amazon Web Services, Using PKCE in authorization code grants. <a href=\"https:\/\/docs.aws.amazon.com\/cognito\/latest\/developerguide\/using-pkce-in-authorization-code.html\">https:\/\/docs.aws.amazon.com\/cognito\/latest\/developerguide\/using-pkce-in-authorization-code.html<\/a><\/li>\n<li id=\"ref19\">Docker, Docker Compose. <a href=\"https:\/\/docs.docker.com\/compose\/\">https:\/\/docs.docker.com\/compose\/<\/a><\/li>\n<li id=\"ref20\">id774, spa-reference compose.yaml. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/compose.yaml\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/compose.yaml<\/a><\/li>\n<li id=\"ref21\">id774, spa-reference package.json. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/package.json\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/package.json<\/a><\/li>\n<li id=\"ref22\">id774, spa-reference frontend\/package.json. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/frontend\/package.json\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/frontend\/package.json<\/a><\/li>\n<li id=\"ref23\">id774, spa-reference backend\/package.json. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/backend\/package.json\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/backend\/package.json<\/a><\/li>\n<li id=\"ref24\">id774, spa-reference infra\/package.json. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/infra\/package.json\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/infra\/package.json<\/a><\/li>\n<li id=\"ref25\">id774, spa-reference AWS infrastructure stack. <a href=\"https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/infra\/lib\/reference-stack.ts\">https:\/\/github.com\/id774\/spa-reference\/blob\/28905244d51908a32a47cbefd3be4855df0cea13\/infra\/lib\/reference-stack.ts<\/a><\/li>\n<li id=\"ref26\">Amazon Web Services, What is Amazon Elastic Container Service?. <a href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/Welcome.html\">https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/Welcome.html<\/a><\/li>\n<li id=\"ref27\">Amazon Web Services, What is the AWS CDK?. <a href=\"https:\/\/docs.aws.amazon.com\/cdk\/v2\/guide\/home.html\">https:\/\/docs.aws.amazon.com\/cdk\/v2\/guide\/home.html<\/a><\/li>\n<li id=\"ref28\">GitHub, Understanding GitHub Actions. <a href=\"https:\/\/docs.github.com\/en\/actions\/get-started\/understanding-github-actions\">https:\/\/docs.github.com\/en\/actions\/get-started\/understanding-github-actions<\/a><\/li>\n<li id=\"ref29\">id774, AI \u304c\u30c6\u30b9\u30c8\u3092\u901a\u3057\u3066\u3082\u3001\u300c\u6b63\u3057\u3044\u300d\u3068\u306f\u9650\u3089\u306a\u3044\uff082026-09-01\uff09. <a href=\"https:\/\/blog.id774.net\/entry\/2026\/09\/01\/5534\/\">https:\/\/blog.id774.net\/entry\/2026\/09\/01\/5534\/<\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>SPA \u3092\u4e00\u3064\u52d5\u304b\u3059\u3068\u3053\u308d\u307e\u3067\u306a\u3089\u3001React \u3067\u753b\u9762\u3092\u4f5c\u308a\u3001HTTP API \u3092\u7528\u610f\u3057\u3001\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u63a5\u7d9a\u3059\u308c\u3070\u5f62\u306b\u306a\u308b\u3002\u3057\u304b\u3057\u3001\u696d\u52d9\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u3057\u3066\u7d99\u7d9a\u5229\u7528\u3067\u304d\u308b\u72b6\u614b\u307e\u3067\u9032\u3081\u308b\u3068\u3001\u753b\u9762\u3068 API \u306e\u5916\u5074\u306b\u5225\u306e\u8a2d &#8230; <a title=\"\u53c2\u7167\u5b9f\u88c5\u306f\u8a2d\u8a08\u5224\u65ad\u3092\u4fdd\u5b58\u3059\u308b\" class=\"read-more\" href=\"https:\/\/blog.id774.net\/entry\/2026\/10\/05\/5751\/\" aria-label=\"\u53c2\u7167\u5b9f\u88c5\u306f\u8a2d\u8a08\u5224\u65ad\u3092\u4fdd\u5b58\u3059\u308b \u306b\u3064\u3044\u3066\u3055\u3089\u306b\u8aad\u3080\">\u7d9a\u304d\u3092\u8aad\u3080<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-5751","post","type-post","status-publish","format-standard","hentry","category-tech"],"_links":{"self":[{"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/posts\/5751","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/comments?post=5751"}],"version-history":[{"count":1,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/posts\/5751\/revisions"}],"predecessor-version":[{"id":5752,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/posts\/5751\/revisions\/5752"}],"wp:attachment":[{"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/media?parent=5751"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/categories?post=5751"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.id774.net\/entry\/wp-json\/wp\/v2\/tags?post=5751"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}