フルスタックアーキテクチャのブループリント —— 著者:王教成#
Kotlin クロスプラットフォームフルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL + 多プラットフォーム実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター
+読み書き分離
+自動フェイルオーバー
)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース
/注文データベース
/在庫データベース
)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3
)および列レベルデータ暗号化(AES-256
)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql
)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ
/主外キー
/インデックス戦略
)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算
)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;
)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY)
)
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY
)
L11 原子操作層:制約条件を設定する(UNIQUE(email)
, NOT NULL(username)
)
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true
)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entity
にはUser
/Profile
エンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class)
)
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce")
)
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity
/.embeddable
/.enums
)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User
)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt
)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException()
)
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
)
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY)
)
L11 原子操作層:equals()
/hashCode()
メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析
/ページング設定
)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repository
にはOrder
/LineItem
が含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')")
)
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories
)
L5 パッケージ構造層:リポジトリの層を整理する(.repository
/.custom
/.projection
)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>
)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable)
)
L8 コードブロック層:@Query
注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status")
)
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end)
)
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true")
)
L11 原子操作層:flush
操作を実行する(saveAndFlush(entity)
)
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード
+ロールバックログ
)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService
/InventoryService
)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id")
)
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement
)
L5 パッケージ構造層:サービスの層を整理する(.api
/.impl
/.event
)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl
)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart)
在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class)
)
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this))
)
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%)
)
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException()
)
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition
)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-service
を注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails
)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters
)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user
/.controller.order
)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders")
)
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder()
)
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result
)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order))
)
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity)
)
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest())
)
6. クライアント データソース (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:Ktor Client の多プラットフォームネットワークスタックを設定する(HttpClient
+ 30sタイムアウト
+ GraphQLサポート
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:統一認証メカニズムを実施する(JWT自動更新
+ プラットフォーム特有のセキュリティストレージ
)
L4 モジュール層:network
モジュールを構築しクロスプラットフォームネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(.graphql
/.api
/.interceptor
)
L6 クラスとインターフェース層:汎用データソースインターフェースを定義する(interface ApiService { suspend fun query<T>(query: String): T }
)
L7 メソッド層:反応的データストリームを宣言する(fun getProducts(): Flow<ProductDTO>
)
L8 コードブロック層:指数バックオフ再試行ロジックを構築する(retryWhen { e, attempt -> if (e is TimeoutCancellationException && attempt < 3) }
)
L9 ステートメント層:クロスプラットフォームネットワーク呼び出しを実行する(withContext(Dispatchers.Default) { apiService.fetchData() }
)
L10 式層:kotlinx.serialization を使用して解析する(Json.decodeFromString<T>(response)
)
L11 原子操作層:プラットフォーム識別ヘッダーを追加する(headers.append("Platform", Platform.platformName)
)
7. クライアント ストレージ層 (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:統一キャッシュ戦略を設計する(メモリキャッシュ
+ SqlDelight永続化
+ 自動同期
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:ローカルデータ暗号化を実施する(プラットフォーム特有のセキュリティストレージ
)
L4 モジュール層:storage
モジュールを作成しデータ調整を実現する
L5 パッケージ構造層:ストレージ実装を整理する(.cache
/.database
/.preference
)
L6 クラスとインターフェース層:スマートキャッシュリポジトリを実装する(class SmartCacheRepository<T>(...)
)
L7 メソッド層:混合データ取得を作成する(ローカルキャッシュを先に読み取り、なければネットワークリクエストを行いキャッシュを更新する)
L8 コードブロック層:キャッシュの有効期限制御を構築する(if (lastUpdated.isBefore(now - 5.minutes)) refreshRemote()
)
L9 ステートメント層:クロスプラットフォームデータベースクエリを実行する(db.userQueries.getById(id).executeAsOneOrNull()
)
L10 式層:拡張関数を使用して変換する(networkDTO.toDomainEntity()
)
L11 原子操作層:StateFlow にデータを発信する(_dataState.emit(Result.success(data))
)
8. クライアント ビジネスロジック (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:クロスプラットフォームユースケース仕様を策定する(純Kotlin実装
+ 単一責任原則
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:統一権限チェックを実施する(if (!sessionManager.hasPermission(required)) throw PermissionDenied()
)
L4 モジュール層:domain
モジュールを定義しビジネスルールを含める
L5 パッケージ構造層:ユースケースパッケージを整理する(.usecase.user
/.usecase.order
)
L6 クラスとインターフェース層:プラットフォームに依存しないユースケースクラスを作成する(class CheckoutUseCase @Inject constructor(val repo: CartRepo)
)
L7 メソッド層:コアビジネスロジックを実装する(suspend operator fun invoke()
:在庫を検証→合計を計算→注文を提出)
L8 コードブロック層:エラー変換ブロックを構築する(catch { e -> when(e) { is NetworkException -> ... } }
)
L9 ステートメント層:リポジトリメソッドを呼び出す(val cart = cartRepo.getCart().first()
)
L10 式層:require を使用してパラメータを検証する(require(cart.items.isNotEmpty())
)
L11 原子操作層:ドメインオブジェクトを構築する(Order.createFromCart(cart, userId)
)
9. クライアント 状態管理 (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:統一状態管理を設定する(StateFlow
+ MVIモデル
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(catch (e: UnauthorizedException) { _state.value = SessionExpired }
)
L4 モジュール層:presentation
モジュールを作成し状態コンテナを定義する
L5 パッケージ構造層:ViewModel パッケージを整理する(.viewmodel.user
/.viewmodel.product
)
L6 クラスとインターフェース層:汎用状態コンテナを定義する(class UserViewModel : KoinComponent { ... }
)
L7 メソッド層:状態更新メソッドを作成する(fun loadData() { viewModelScope.launch { ... } }
)
L8 コードブロック層:状態変換ブロックを構築する(private fun mapToUiState(data: T): UiState
)
L9 ステートメント層:UI 状態を更新する(_state.update { it.copy(data = data, loading = false) }
)
L10 式層:密封クラスを使用して状態を変換する(when(result) { is Success -> UiState.Data(...) }
)
L11 原子操作層:UseCase メソッドを呼び出す(val result = getUserUseCase(userId)
)
10. クライアント UI 層 (プラットフォーム特定の実装)#
L0 ビジネスエコシステム層:統一ユーザージャーニーパスを設計する(登録→ログイン→ホーム→詳細→支払い
)
L1 システム層:プラットフォーム UI フレームワークを採用する(Android: Jetpack Compose
/iOS: SwiftUI
/Web: Compose for Web
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(Android: onPauseでぼかし
/iOS: willResignActiveでぼかし
/Web: blurイベント処理
)
L4 モジュール層:ui
メインモジュールを構築しテーマ設定を含める
L5 パッケージ構造層:UI コンポーネントパッケージを整理する(.screen.login
/.screen.cart
/.component
)
L6 クラスとインターフェース層:プラットフォーム UI コンポーネントを定義する(Android: @Composable fun
/iOS: struct View: View
/Web: fun Render()
)
L7 メソッド層:イベント処理関数を作成する(val onLogin = { viewModel.login(credentials) }
)
L8 コードブロック層:状態応答レンダリングブロックを構築する(when(state) { Loading -> ローディングインジケーターを表示 }
)
L9 ステートメント層:UI 要素を組み合わせる(Android: Column { }
/iOS: VStack { }
/Web: Div { }
)
L10 式層:アニメーション式を使用する(Android: AnimatedVisibility
/iOS: withAnimation
/Web: animate {}
)
L11 原子操作層:テキスト属性を設定する(Android: Text(...)
/iOS: Text(...)
/Web: Span { Text(...) }
)
Kotlin フルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL+Android 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター
+読み書き分離
+自動フェイルオーバー
)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース
/注文データベース
/在庫データベース
)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3
)および列レベルデータ暗号化(AES-256
)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql
)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ
/主外キー
/インデックス戦略
)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算
)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;
)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY)
)
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY
)
L11 原子操作層:制約条件を設定する(UNIQUE(email)
, NOT NULL(username)
)
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true
)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entity
にはUser
/Profile
エンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class)
)
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce")
)
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity
/.embeddable
/.enums
)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User
)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt
)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException()
)
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
)
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY)
)
L11 原子操作層:equals()
/hashCode()
メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析
/ページング設定
)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repository
にはOrder
/LineItem
が含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')")
)
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories
)
L5 パッケージ構造層:リポジトリの層を整理する(.repository
/.custom
/.projection
)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>
)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable)
)
L8 コードブロック層:@Query
注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status")
)
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end)
)
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true")
)
L11 原子操作層:flush
操作を実行する(saveAndFlush(entity)
)
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード
+ロールバックログ
)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService
/InventoryService
)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id")
)
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement
)
L5 パッケージ構造層:サービスの層を整理する(.api
/.impl
/.event
)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl
)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart)
在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class)
)
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this))
)
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%)
)
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException()
)
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition
)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-service
を注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails
)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters
)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user
/.controller.order
)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders")
)
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder()
)
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result
)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order))
)
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity)
)
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest())
)
6. クライアント データソース(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:Retrofit を設定する(GsonConverterFactory
+ 30sタイムアウト
+ キャッシュ制御
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:証明書ピンニングを実施する(CertificatePinner.Builder()
)
L4 モジュール層:data-source
モジュールを構築しネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(.api
/.retrofit
/.local
)
L6 クラスとインターフェース層:Retrofit インターフェースを定義する(@GET("users/{id}") suspend fun getUser(@Path("id") id: Long): UserDTO
)
L7 メソッド層:ストリーミングデータ取得を宣言する(fun getProducts(): Flow<ProductDTO>
)
L8 コードブロック層:再試行ロジックブロックを構築する(retryWhen { e, attempt -> if (e is SocketTimeoutException && attempt < 3) }
)
L9 ステートメント層:ネットワークリクエストを実行する(withContext(Dispatchers.IO) { apiService.fetchData() }
)
L10 式層:kotlinx.serialization を使用して解析する(Json.decodeFromString<UserDTO>(response)
)
L11 原子操作層:認証ヘッダーを追加する(request.addHeader("Authorization", "Bearer ${tokenStorage.accessToken}")
)
7. クライアント Repository(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:スマートキャッシュ戦略を設計する(メモリキャッシュ
+Room永続化
+自動更新
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:ローカルデータ暗号化を実施する(SQLCipher統合
)
L4 モジュール層:リポジトリモジュールを作成しデータ調整を実現する
L5 パッケージ構造層:リポジトリ実装を整理する(.repo_impl.user
/.repo_impl.product
)
L6 クラスとインターフェース層:リポジトリクラスを実装する(class UserDataRepository @Inject constructor(...)
)
L7 メソッド層:キャッシュ優先戦略を作成する(CoreData をチェック→ネットワークリクエスト→キャッシュを更新)
L8 コードブロック層:キャッシュ更新制御を構築する(if (lastUpdated.isBefore(now - 5.minutes)) refreshRemote()
)
L9 ステートメント層:Room クエリを実行する(roomDb.userDao().getById(id).flowOn(Dispatchers.IO)
)
L10 式層:拡張関数を使用して変換する(networkDTO.toDomainEntity()
)
L11 原子操作層:StateFlow にデータを発信する(_userState.emit(Result.success(user))
)
8. クライアント UseCase(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:ユースケース仕様を策定する(純Kotlin実装
+単一責任原則
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:権限チェックを実施する(if (!sessionManager.isAdmin()) throw PermissionDeniedException()
)
L4 モジュール層:ドメインモジュールを定義しビジネスルールを含める
L5 パッケージ構造層:ユースケースパッケージを整理する(.usecase.user
/.usecase.product
)
L6 クラスとインターフェース層:ユースケースの迅速な応答を作成する(class CheckoutUseCase @Inject constructor(val repo: CartRepo)
)
L7 メソッド層:コアロジックを実装する(func execute(cart: Cart) async throws
:在庫検証→合計計算→注文)
L8 コードブロック層:エラー変換を構築する(catch { throw DomainErrorMapper.transform($0) }
)
L9 ステートメント層:リポジトリメソッドを呼び出す(let stock = try await stockRepo.checkAvailability(productId)
)
L10 式層:guard を使用してパラメータを検証する(guard cart.items.count > 0 else { throw CartError.empty }
)
L11 原子操作層:ドメインモデルを構築する(Order.create(from: cart, user: user)
)
9. クライアント ViewModel(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:Hilt 依存性注入 ViewModel を設定する(@HiltViewModel
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(catch (e: UnauthorizedException) { _state.value = SessionExpired }
)
L4 モジュール層:presentation モジュールを作成し状態コンテナを定義する
L5 パッケージ構造層:ViewModel パッケージを整理する(.viewmodel.home
/.viewmodel.cart
)
L6 クラスとインターフェース層:ViewModel を継承する(class UserViewModel @Inject constructor(val useCase: GetUserUseCase): ViewModel()
)
L7 メソッド層:非同期ロードメソッドを作成する(@MainActor func loadProfile() async { ... }
)
L8 コードブロック層:状態変換器を構築する(private func mapResult(_ result: Result<User, Error>)
)
L9 ステートメント層:UI 状態を更新する(state = .loaded(user)
)
L10 式層:列挙型の関連値を使用する(enum ViewState { case idle, loading, loaded(User), failed(Error) }
)
L11 原子操作層:UseCase を呼び出す(self.user = try await useCase.fetchUser(id)
)
10. クライアント UI 層(Android)#
L0 ビジネスエコシステム層:ユーザージャーニーパスを設計する(登録ログインホーム詳細支払い
)
L1 システム層:Jetpack Compose フレームワークを採用しテーマシステムを設定する(MaterialTheme
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(onPause時にぼかし効果を適用
)
L4 モジュール層:app メインモジュールを構築しテーマ設定を含める
L5 パッケージ構造層:UI コンポーネントパッケージを整理する(.screen.login
/.screen.cart
/.component.button
)
L6 クラスとインターフェース層:可組み合わせ関数を定義する(@Composable fun HomeScreen(viewModel: HomeViewModel)
)
L7 メソッド層:イベント処理関数を作成する(private func handlePurchase() { Task { await viewModel.purchase() } }
)
L8 コードブロック層:状態応答ブロックを構築する(switch viewModel.state { case .loading: ProgressView() }
)
L9 ステートメント層:UI 要素を組み合わせる(Column(modifier = Modifier.fillMaxSize()) { Header() }
)
L10 式層:暗黙のアニメーションを使用する(.animation(.spring, value: viewModel.state)
)
L11 原子操作層:テキスト表示を設定する(Text(text = stringResource(id = R.string.welcome))
)
Kotlin+Swift フルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL+iOS 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター
+読み書き分離
+自動フェイルオーバー
)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース
/注文データベース
/在庫データベース
)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3
)および列レベルデータ暗号化(AES-256
)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql
)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ
/主外キー
/インデックス戦略
)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算
)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;
)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY)
)
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY
)
L11 原子操作層:制約条件を設定する(UNIQUE(email)
, NOT NULL(username)
)
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true
)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entity
にはUser
/Profile
エンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class)
)
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce")
)
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity
/.embeddable
/.enums
)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User
)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt
)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException()
)
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
)
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY)
)
L11 原子操作層:equals()
/hashCode()
メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析
/ページング設定
)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repository
にはOrder
/LineItem
が含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')")
)
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories
)
L5 パッケージ構造層:リポジトリの層を整理する(.repository
/.custom
/.projection
)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>
)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable)
)
L8 コードブロック層:@Query
注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status")
)
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end)
)
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true")
)
L11 原子操作層:flush
操作を実行する(saveAndFlush(entity)
)
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード
+ロールバックログ
)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService
/InventoryService
)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id")
)
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement
)
L5 パッケージ構造層:サービスの層を整理する(.api
/.impl
/.event
)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl
)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart)
在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class)
)
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this))
)
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%)
)
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException()
)
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition
)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-service
を注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails
)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters
)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user
/.controller.order
)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders")
)
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder()
)
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result
)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order))
)
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity)
)
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest())
)
6. クライアント データソース(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:URLSession ネットワークスタックを設定する(URLSessionConfiguration.ephemeral
+30sタイムアウト
+URLCache
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:SSL 証明書ピンニングを実施する(SecTrust
証明書チェーン検証)
L4 モジュール層:NetworkService
モジュールを構築しネットワーク層をカプセル化する
L5 パッケージ構造層:データソースの層を整理する(Networking/API
/Networking/Models
/Networking/Interceptors
)
L6 クラスとインターフェース層:API プロトコルを定義する(protocol UserAPIService { func fetchUser(id: Int) async throws -> UserDTO }
)
L7 メソッド層:Combine データストリームを宣言する(func productStream() -> AnyPublisher<[ProductDTO], Error>
)
L8 コードブロック層:再試行ロジックを構築する(.retry(3) { $0 is URLError }
)
L9 ステートメント層:ネットワークリクエストを発起する(let (data, _) = try await URLSession.shared.data(for: request)
)
L10 式層:Codable を使用して解析する(JSONDecoder().decode(UserDTO.self, from: data)
)
L11 原子操作層:認証ヘッダーを追加する(request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
)
7. クライアント Repository(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:混合キャッシュ戦略を設計する(NSCache
+CoreData
+自動同期
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:データ暗号化を実施する(NSFileProtectionComplete
ファイル保護)
L4 モジュール層:Persistence
データ調整モジュールを作成する
L5 パッケージ構造層:リポジトリ実装を整理する(Repositories/UserRepository
/Repositories/ProductRepository
)
L6 クラスとインターフェース層:リポジトリクラスを実装する(struct CoreDataUserRepository: UserRepositoryProtocol
)
L7 メソッド層:キャッシュ優先戦略を作成する(CoreData をチェック→ネットワークリクエスト→キャッシュを更新)
L8 コードブロック層:キャッシュ更新制御を構築する(if cacheEntry.lastUpdated.timeIntervalSinceNow < -300 { fetchRemote() }
)
L9 ステートメント層:CoreData クエリを実行する(try container.viewContext.fetch(NSFetchRequest<UserEntity>(entityName: "User"))
)
L10 式層:マッピング拡張を使用してモデルを変換する(extension UserDTO { func toManagedObject() }
)
L11 原子操作層:CoreData コンテキストを保存する(container.viewContext.save()
)
8. クライアント UseCase(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:ユースケース仕様を策定する(純Swift実装
+単一責任
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:権限チェックを実施する(guard context.authService.isAdmin else { throw AuthError.unauthorized }
)
L4 モジュール層:DomainLogic
ビジネスルールモジュールを定義する
L5 パッケージ構造層:ユースケースパッケージを整理する(UseCases/CheckoutUseCase
/UseCases/UserManagement
)
L6 クラスとインターフェース層:ユースケース構造体を作成する(struct PurchaseUseCase { let repository: OrderRepository }
)
L7 メソッド層:コアロジックを実装する(func execute(cart: Cart) async throws
:在庫検証→合計計算→注文)
L8 コードブロック層:エラー変換を構築する(catch { throw DomainErrorMapper.transform($0) }
)
L9 ステートメント層:リポジトリメソッドを呼び出す(let stock = try await stockRepo.checkAvailability(productId)
)
L10 式層:guard を使用してパラメータを検証する(guard cart.items.count > 0 else { throw CartError.empty }
)
L11 原子操作層:ドメインモデルを構築する(Order.create(from: cart, user: user)
)
9. クライアント ViewModel(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:依存性注入を設定する(Swinject
コンテナ登録)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(.onReceive(authService.$sessionState) { if $0 == .expired { handleLogout() } }
)
L4 モジュール層:PresentationLogic
反応型モジュールを作成する
L5 パッケージ構造層:ViewModel を整理する(ViewModels/ProfileViewModel
/ViewModels/CartViewModel
)
L6 クラスとインターフェース層:ObservableObject を定義する(class UserProfileViewModel: ObservableObject { @Published private(set) var state = ViewState.idle }
)
L7 メソッド層:非同期ロードメソッドを作成する(@MainActor func loadProfile() async { ... }
)
L8 コードブロック層:状態変換器を構築する(private func mapResult(_ result: Result<User, Error>)
)
L9 ステートメント層:UI 状態を更新する(state = .loaded(user)
)
L10 式層:列挙型の関連値を使用する(enum ViewState { case idle, loading, loaded(User), failed(Error) }
)
L11 原子操作層:UseCase を呼び出す(self.user = try await useCase.fetchUser(id)
)
10. クライアント UI 層(iOS)#
L0 ビジネスエコシステム層:ユーザージャーニーパスを設計する(登録ログインホーム詳細支払い
)
L1 システム層:SwiftUI フレームワークを採用しテーマを設定する(ViewModifier
+Environment
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(.onReceive(UIApplication.willResignActiveNotification) { blurScreen() }
)
L4 モジュール層:UserInterface
ビューコンポーネントライブラリを構築する
L5 パッケージ構造層:ビューを層別に整理する(Modules/Login/Views
/Modules/Checkout/Components
)
L6 クラスとインターフェース層:View 構造体を定義する(struct ProductDetailView:View { @StateObject var viewModel: DetailViewModel }
)
L7 メソッド層:イベント処理を作成する(private func handlePurchase() { Task { await viewModel.purchase() } }
)
L8 コードブロック層:状態応答ブロックを構築する(switch viewModel.state { case .loading: ProgressView() }
)
L9 ステートメント層:ビュー要素を組み合わせる(VStack { HeaderView(); ProductGallery() }
)
L10 式層:暗黙のアニメーションを使用する(.animation(.spring, value: viewModel.state)
)
L11 原子操作層:テキスト表示を設定する(Text(user.name).font(.system(size: 16, weight: .semibold))
)
Kotlin+TypeScript フルスタックアーキテクチャのブループリント:縦 11 層級 × 横 10 モジュールの SpringBoot+MySQL+Web 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター
+読み書き分離
+自動フェイルオーバー
)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース
/注文データベース
/在庫データベース
)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3
)および列レベルデータ暗号化(AES-256
)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql
)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ
/主外キー
/インデックス戦略
)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算
)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;
)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY)
)
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY
)
L11 原子操作層:制約条件を設定する(UNIQUE(email)
, NOT NULL(username)
)
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true
)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entity
にはUser
/Profile
エンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class)
)
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce")
)
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity
/.embeddable
/.enums
)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User
)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt
)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException()
)
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
)
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY)
)
L11 原子操作層:equals()
/hashCode()
メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析
/ページング設定
)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repository
にはOrder
/LineItem
が含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')")
)
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories
)
L5 パッケージ構造層:リポジトリの層を整理する(.repository
/.custom
/.projection
)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>
)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable)
)
L8 コードブロック層:@Query
注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status")
)
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end)
)
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true")
)
L11 原子操作層:flush
操作を実行する(saveAndFlush(entity)
)
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード
+ロールバックログ
)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService
/InventoryService
)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id")
)
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement
)
L5 パッケージ構造層:サービスの層を整理する(.api
/.impl
/.event
)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl
)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart)
在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class)
)
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this))
)
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%)
)
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException()
)
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition
)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-service
を注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails
)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters
)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user
/.controller.order
)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders")
)
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder()
)
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result
)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order))
)
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity)
)
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest())
)
6. クライアント データソース(Web)#
L0 ビジネスエコシステム層:なし
L1 システム層:Axios インスタンスを設定する(baseURL
+ interceptor
+ 30sタイムアウト
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:CSRF 保護を実施する(anti-CSRF token
)および JWT 自動更新
L4 モジュール層:api-service
モジュールを構築しネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(/services/api/authService.ts
,/services/api/productService.ts
)
L6 クラスとインターフェース層:API サービスクラスを定義する(class AuthService { async login(credentials: LoginDTO): Promise<AuthResponse> }
)
L7 メソッド層:反応的データストリームを宣言する(const productObservable = new BehaviorSubject<Product[]>([])
)
L8 コードブロック層:指数バックオフ再試行ロジックを構築する(retryWithBackoff(axiosCall, maxRetries = 3)
)
L9 ステートメント層:API リクエストを実行する(return axios.post<AuthResponse>('/auth/login', credentials)
)
L10 式層:zod を使用して応答検証を行う(AuthResponseSchema.parse(response.data)
)
L11 原子操作層:認証ヘッダーを注入する(config.headers.Authorization = 'Bearer ${token}'
)
7. クライアント 状態管理(Web)#
L0 ビジネスエコシステム層:なし
L1 システム層:Redux 状態アーキテクチャを設計する(redux-toolkit
+ redux-persist
)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:敏感データのクリアを実施する(localStorage.clear()
)
L4 モジュール層:store
モジュールを作成しアプリケーション状態を管理する
L5 パッケージ構造層:状態スライスを整理する(/store/slices/authSlice.ts
,/store/slices/cartSlice.ts
)
L6 クラスとインターフェース層:非同期 Thunk を定義する(export const fetchUser = createAsyncThunk('user/fetch')
)
L7 メソッド層:状態更新ロジックを作成する(reducers: { addToCart: (state, action) => { ... } }
)
L8 コードブロック層:データの正規化ブロックを構築する(createEntityAdapter<Product>()
)
L9 ステートメント層:状態変化を購読する(store.subscribe(() => { ... })
)
L10 式層:selector を使用して効率的にデータを選択する(const user = useSelector(selectCurrentUser)
)
L11 原子操作層:Immer ドラフトを生成する(`produce (state, draft => { draft.cart.items.push (item