API Integration and Data Fetching
Table of Contents
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Introduction
This document explains the API integration and data fetching patterns used in the tenant console. It covers the centralized HTTP client, request/response/error interceptors, authentication token injection, environment-aware routing, and the state stores that orchestrate data loading. It also documents how the frontend integrates with the bi-common service layer, REST/gRPC patterns, and how to implement custom data loaders, handle concurrent requests, manage loading states, transform responses, implement error boundaries, and add retry mechanisms.
Project Structure
The tenant console’s API layer is primarily implemented in the ui-web package, with shared types and utilities in bi-common. The key areas are:
- Centralized HTTP client and interceptors
- Environment configuration and gateway routing
- API surface definitions
- Global stores for initialization and dictionary data
- Hooks for derived data and options
- Backend service layer utilities for standardized responses and errors
Diagram sources
- [request.ts]
- [requestInterceptor.ts]
- [RequestInterceptorProvider.tsx]
- [env.ts]
- [index.ts]
- [useBiStore.ts]
- [useCommonStore.ts]
- [useCollect.ts]
- [response.go]
- [error.go]
- [httpx.go]
Section sources
Core Components
- Central HTTP client: Provides unified request building, token injection, cookie handling, URL routing, timeouts, and response parsing.
- Interceptors: Request, response, and error interceptors enable cross-cutting concerns like logging, auth, and error normalization.
- Environment configuration: Manages gateway vs. rewrite modes, route mapping, and per-environment endpoints.
- API surface: Exposes typed functions for tenant, BI, and other domain APIs.
- Stores: Manage initialization, loading states, and cached dictionaries for UI components.
- Hooks: Derive UI-friendly options from global stores.
Section sources
- [request.ts]
- [requestInterceptor.ts]
- [env.ts]
- [index.ts]
- [useBiStore.ts]
- [useCommonStore.ts]
- [useCollect.ts]
Architecture Overview
The frontend composes a layered API integration strategy:
- Environment-aware routing: URLs starting with specific prefixes are mapped to gateway routes or rewritten via Next.js rewrites.
- Authentication: Bearer tokens are injected automatically; special handling for 401 business errors.
- Interceptors: Request headers, cookies, and optional logging are applied centrally.
- Stores orchestrate initialization sequences and concurrent dictionary loads.
- Backend services define standardized response and error semantics.
Diagram sources
Detailed Component Analysis
Centralized HTTP Client and Interceptors
- Request lifecycle:
- Merge defaults with caller config.
- Apply environment-specific routing (gateway vs rewrite).
- Inject Authorization header and optional cookies.
- Build URL with query params and dispatch via fetch with AbortController for timeouts.
- Parse response based on responseType; normalize business errors (e.g., 401).
- Run response interceptors; propagate errors through error interceptors.
- Interceptors:
- Request: Add token, headers, cookies.
- Response: Transform or enrich responses.
- Error: Normalize network/timeout/business errors; handle 401 by clearing tokens and redirecting.
- Logging interceptor:
- Optional fetch wrapper records requests/responses and posts logs to a local endpoint during development.
Diagram sources
Section sources
Environment Configuration and Routing
- Supports development/test/staging/production environments.
- Two routing modes:
- Gateway mode: Convert API prefixes to gateway routes and send to gatewayUrl.
- Rewrite mode: Use Next.js rewrites; URLs remain unchanged.
- API_ROUTE_MAP defines prefix-to-gateway-route mappings.
Diagram sources
Section sources
API Surface and CRUD Factory
- Provides typed functions for auth and domain APIs.
- Includes a generic CRUD factory to generate standard endpoints for resources.
Diagram sources
Section sources
Global Stores and Concurrent Data Loading
- useBiStore: Initializes BI data once, manages loading/error/initialized flags, and exposes quick-menu toggling.
- useCommonStore: Loads dictionary data concurrently via Promise.all for multiple endpoints, converts raw data into UI-friendly options, and caches structured data.
Diagram sources
Section sources
Hooks for Derived Options
- useCollect: Transforms stored collect data into selectable options and filters “own” collections.
Section sources
Backend Service Layer Integration (bi-common)
- Standard response model: unified code/message/data structure.
- Business error helpers: map business codes to HTTP statuses and carry metadata for downstream handling.
- Go HTTP client with retries: demonstrates a pattern for robust backend calls.
Diagram sources
Section sources
Dependency Analysis
- Frontend depends on:
- Environment configuration for routing decisions.
- Central request client for all HTTP calls.
- API surface for domain-specific endpoints.
- Stores for initialization and dictionary data.
- Backend services depend on:
- Standard response and error utilities for consistent messaging.
- Optional retry mechanisms for transient failures.
Diagram sources
- [env.ts]
- [request.ts]
- [index.ts]
- [useBiStore.ts]
- [useCommonStore.ts]
- [useCollect.ts]
- [response.go]
- [error.go]
- [httpx.go]
Section sources
- [env.ts]
- [request.ts]
- [index.ts]
- [useBiStore.ts]
- [useCommonStore.ts]
- [useCollect.ts]
- [response.go]
- [error.go]
- [httpx.go]
Performance Considerations
- Concurrency: Use Promise.all to load related dictionary endpoints in parallel.
- Caching: Initialize once and reuse in stores; avoid redundant fetches by checking loading/initialized flags.
- Timeouts: Centralized AbortController prevents hanging requests.
- Payloads: FormData and URLSearchParams are supported to reduce unnecessary JSON overhead.
- Network resilience: Consider adding exponential backoff and jitter for retries in high-stakes flows.
[No sources needed since this section provides general guidance]
Troubleshooting Guide
- 401/4100001 business errors: Automatically cleared and redirected to login; inspect error interceptors for customization.
- Network errors and timeouts: Normalized into RequestError with appropriate codes; surface via error interceptors.
- Request logging: Install fetch interceptor provider in development to capture request/response bodies and durations.
- Environment routing: Verify API_ROUTE_MAP and env.useGateway to ensure correct gateway vs rewrite behavior.
Section sources
Conclusion
The tenant console employs a robust, centralized API integration strategy with environment-aware routing, automatic authentication, and comprehensive interceptors. Stores orchestrate initialization and concurrent data loading, while hooks derive UI-ready options. The bi-common service layer provides standardized response and error semantics, and retry patterns are demonstrated for resilient backend communication.
[No sources needed since this section summarizes without analyzing specific files]
Appendices
Implementing Custom Data Loaders
- Use the central request client to implement loaders with:
- Request/response/error interceptors for cross-cutting concerns.
- Environment-aware routing for gateway or rewrite modes.
- Typed API surfaces for domain endpoints.
- Example patterns:
- Loader with concurrency: see dictionary loading via Promise.all.
- Loader with retries: adopt retry/backoff patterns similar to the Go HTTP client.
Section sources
Handling Concurrent Requests
- Use Promise.all to parallelize independent endpoints.
- Guard against duplicate or overlapping requests using store flags (loading/initialized).
Section sources
Managing Loading States
- Initialize stores with loading/error/initialized flags.
- Update UI based on store state; avoid re-fetching when initialized/loading.
Section sources
API Response Transformation
- Centralize response parsing and business error checks.
- Use response interceptors to normalize shapes and enrich payloads.
Section sources
Error Boundary Implementation
- Wrap critical data loaders with try/catch and set error state.
- Use error interceptors to unify error handling and reporting.
Section sources
Retry Mechanisms
- For backend services, leverage retry/backoff patterns similar to the Go HTTP client.
- For frontend loaders, consider retry-on-failure with capped attempts and exponential backoff.
Section sources