DEV Community

Vedika Intelligence
Vedika Intelligence

Posted on

Building Robust Astrology Apps with TypeScript and the Vedika API [2026-01]

In today's fast-paced development world, type safety isn't just a nice-to-have—it's essential for building reliable applications. When integrating with external APIs like the Vedika astrology service, TypeScript's strong typing can save you from countless runtime errors and debugging headaches. Let's explore how to create a type-safe integration with the Vedika API that will make your astrology app shine.

The Problem: API Integration Without Type Safety

When working with third-party APIs, developers often face challenges like:

  • Uncertain response structures
  • Missing required fields
  • Incorrect data types
  • Time-consuming debugging of API-related issues

These problems become even more pronounced when dealing with complex data like birth details and astrology interpretations. Without proper type definitions, you're essentially flying blind, praying that the API returns exactly what you expect.

Solution: Type-Safe Vedika API Integration

Let's build a robust TypeScript wrapper for the Vedika API that provides compile-time safety and autocompletion.

Step 1: Install Dependencies

First, make sure you have the necessary packages:

npm install axios typescript @types/node
Enter fullscreen mode Exit fullscreen mode

Step 2: Define Type Interfaces

Create a types.ts file to define the interfaces for our API:

// types.ts
export interface BirthDetails {
  datetime: string; // ISO 8601 format
  latitude: number;
  longitude: number;
}

export interface VedikaQuery {
  question: string;
  birthDetails: BirthDetails;
}

export interface VedikaResponse {
  id: string;
  question: string;
  answer: string;
  confidence: number;
  timestamp: string;
  relatedTopics?: string[];
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the API Client

Now, let's build a client that handles communication with the Vedika API:

// vedikaClient.ts
import axios, { AxiosInstance } from 'axios';
import { VedikaQuery, VedikaResponse } from './types';

class VedikaClient {
  private client: AxiosInstance;

  constructor(apiKey: string) {
    this.client = axios.create({
      baseURL: 'https://api.vedika.io/v1',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      }
    });
  }

  async getAstrologyInsight(query: VedikaQuery): Promise<VedikaResponse> {
    try {
      const response = await this.client.post< VedikaResponse>('/astrology/query', query);
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error)) {
        console.error('Vedika API Error:', error.response?.data);
        throw new Error(`Vedika API error: ${error.response?.statusText}`);
      }
      throw error;
    }
  }
}

export default VedikaClient;
Enter fullscreen mode Exit fullscreen mode

Step 4: Implement with Error Handling

Let's create a service that uses our client with additional error handling:

// astrologyService.ts
import VedikaClient from './vedikaClient';
import { VedikaQuery, VedikaResponse } from './types';

export class AstrologyService {
  private client: VedikaClient;

  constructor(apiKey: string) {
    this.client = new VedikaClient(apiKey);
  }

  async getInsight(question: string, birthDetails: VedikaQuery['birthDetails']): Promise<VedikaResponse> {
    if (!question.trim()) {
      throw new Error('Question cannot be empty');
    }

    if (!this.validateBirthDetails(birthDetails)) {
      throw new Error('Invalid birth details');
    }

    const query: VedikaQuery = { question, birthDetails };

    try {
      const response = await this.client.getAstrologyInsight(query);
      return response;
    } catch (error) {
      console.error('Failed to get astrology insight:', error);
      throw new Error('Unable to retrieve astrology insight at this time');
    }
  }

  private validateBirthDetails(details: VedikaQuery['birthDetails']): boolean {
    return (
      details.datetime &&
      !isNaN(Date.parse(details.datetime)) &&
      details.latitude >= -90 && details.latitude <= 90 &&
      details.longitude >= -180 && details.longitude <= 180
    );
  }
}

// Usage example
const astrologyService = new AstrologyService('your-api-key');

try {
  const insight = await astrologyService.getInsight(
    "What does my future hold?",
    {
      datetime: "1990-05-15T14:30:00Z",
      latitude: 40.7128,
      longitude: -74.0060
    }
  );
  console.log(insight.answer);
} catch (error) {
  console.error('Error:', error.message);
}
Enter fullscreen mode Exit fullscreen mode

Practical Tips and Gotchas

  1. Date Handling: The Vedika API expects datetime in ISO 8601 format. Use toISOString() method when working with Date objects:
const birthDate = new Date(1990, 4, 15, 14, 30); // May 15, 1990, 2:30 PM
const isoDate = birthDate.toISOString(); // "1990-05-15T18:30:00.000Z"
Enter fullscreen mode Exit fullscreen mode
  1. Environment Variables: Never hardcode your API key. Use environment variables:
// .env file
VEDIKA_API_KEY=your_api_key_here

// In your code
const apiKey = process.env.VEDIKA_API_KEY;
Enter fullscreen mode Exit fullscreen mode
  1. Rate Limiting: The Vedika API has rate limits. Implement exponential backoff for retries:
async function withRetry<T>(
  fn: () => Promise<T>,
  maxRetries = 3,
  delay = 1000
): Promise<T> {
  try {
    return await fn();
  } catch (error) {
    if (maxRetries <= 0) throw error;

    await new Promise(resolve => setTimeout(resolve, delay));
    return withRetry(fn, maxRetries - 1, delay * 2);
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Response Validation: Consider using a library like Zod for runtime validation of API responses:
import { z } from 'zod';

const vedikaResponseSchema = z.object({
  id: z.string(),
  question: z.string(),
  answer: z.string(),
  confidence: z.number().min(0).max(1),
  timestamp: z.string(),
});

const validatedResponse = vedikaResponseSchema.parse(apiResponse);
Enter fullscreen mode Exit fullscreen mode

Conclusion and Next Steps

We've built a type-safe wrapper for the Vedika astrology API that provides compile-time checking, better error handling, and improved developer experience. By leveraging TypeScript's capabilities, we've created a more robust and maintainable integration.

Next Steps to Enhance This Integration:

  1. Add Request Caching: Implement caching to avoid redundant API calls for the same birth details and questions.

  2. Create Mock Service: Build a mock implementation for development and testing purposes.

  3. Add Request/Response Interceptors: Implement logging and analytics.

  4. Develop Type Guards: Create runtime type checking for complex astrology data structures.

  5. Explore GraphQL: Consider wrapping the Vedika API with a GraphQL layer for more flexible queries.

By following these patterns, you'll be well on your way to building a reliable, type-safe astrology application that leverages the power of the Vedika API while minimizing the risk of runtime errors. Happy coding!

Top comments (0)