API Integration Standards
Guidelines for integrating external APIs.
DSE API
Production integrations should use DSEApiService from @worker/services/market-data. Wrap calls in try/catch and map DSEApiError into domain errors before surfacing them to tRPC or the UI.
import { DSEApiService, DSEApiError } from "@worker/services/market-data";
import { createBusinessLogicError } from "@worker/services/shared/domain-errors";
const dseApi = new DSEApiService();
try {
const prices = await dseApi.getLastTradedPrices(["GP", "BRACBANK"]);
logger.info("Fetched prices", { count: prices.length });
} catch (error) {
if (error instanceof DSEApiError) {
throw createBusinessLogicError(`DSE API unavailable: ${error.message}`);
}
throw error;
}
Patterns
- Convert third-party failures into domain-level
Resulterrors orBusinessLogicErrors - Implement timeouts and retries at the client level when needed
- Cache aggressively when the upstream provider has strict rate limits
- Mock external APIs in tests; never hit the real service from automated suites
- Use structured logging with request context (endpoint, payload, correlation IDs)
Testing
When unit or integration tests rely on API data, provide deterministic fixtures via dependency injection:
const mockDseApi = vi.mocked(new DSEApiService(mockClient));
mockDseApi.getLastTradedPrices.mockResolvedValue([
{ symbol: "GP", price: 123_45, date: "2025-11-08" },
]);
Ensure mocks cover error pathways so Result-based callers exercise both success and failure branches.