Skip to content

Architecture: Separate API Layer from TUI for WebUI support #64

@yimsk

Description

@yimsk

Goal

Decouple TUI (Bubbletea) from business logic by introducing an API layer.
TUI and future WebUI will consume the same API.

Motivation

  • Enable WebUI without duplicating business logic
  • Unified execution path (TUI = API client)
  • Clean separation of concerns

Design Decisions

Decision Choice Rationale
API style Stateless Each request specifies profiles/regions. No server-side session state. Simpler, testable, multi-tab safe.
Target Local single-user No auth layer needed initially. SSO/login can directly invoke AWS CLI.
TUI migration Required TUI must use API, not direct DAO calls. Ensures parity.

Current Architecture (coupling points)

TUI (Bubbletea) → config.Global() → DAO → AWS SDK
                      ↑
            Profiles/Regions/ReadOnly stored globally

Key files with global state dependency:

  • internal/config/config.go - Global singleton for selections/regions/accountIDs
  • internal/view/resource_browser_fetch.go - Multi-profile/region parallel fetch
  • internal/aws/client.go - Context overrides (WithSelectionOverride/WithRegionOverride)
  • internal/view/profile_selector.go - SSO login (aws sso login)
  • internal/view/command_input.go - Console login (:login command)

Proposed Architecture

TUI ─┐                        
     ├─> API Layer ─> Registry/DAO/Actions ─> AWS SDK
Web ─┘        ↑
         Request-scoped context
         (no global state reads)

API Endpoints (minimum)

Resources

  • GET /api/services - List services
  • GET /api/{service}/{resource}?profiles=...&regions=... - List resources
  • GET /api/{service}/{resource}/{id} - Get resource detail
  • POST /api/{service}/{resource}/{id}/actions/{action} - Execute action

Configuration

  • GET /api/profiles - List available AWS profiles
  • GET /api/regions - List AWS regions

Authentication

  • POST /api/auth/sso/{profile} - Trigger SSO login
  • POST /api/auth/console/{profile} - Trigger console login

Query Parameters (all resource endpoints)

  • profiles - Comma-separated (e.g., ?profiles=dev,prod)
  • regions - Comma-separated (e.g., ?regions=us-east-1,ap-northeast-1)

Response Format

Results include profile/region metadata per resource. Partial errors reported separately.

Implementation Phases

Phase 1: API Layer

  • Define request-scoped execution context struct (profiles, regions, readOnly)
  • Create internal/api/ package with HTTP handlers
  • Refactor fetch logic to accept explicit context (eliminate config.Global() reads in hot path)
  • Implement resource list/get/action endpoints
  • Add claws serve command to start API server

Phase 2: TUI Migration

  • Create typed API client
  • Migrate ResourceBrowser to use API client
  • Migrate ProfileSelector/RegionSelector
  • Ensure action execution goes through API

Phase 3: WebUI (separate issue)

  • Web frontend consuming same API
  • SSO/console login UX (browser-native redirects)

Notes

  • Existing context override mechanism (WithSelectionOverride, WithRegionOverride) provides foundation
  • Read-only policy (internal/action/action.go) must be enforced at API layer
  • Multi-profile/region parallel fetch pattern (fetchParallel) can be reused

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions