API and Integrations - utourismboard/explore-uganda-application-documentation GitHub Wiki

API and Integrations Documentation

Overview

This document details the APIs and third-party integrations used in the Explore Uganda App, including authentication, endpoints, and implementation guidelines.

API Architecture

Base URLs

Production: https://api.exploreuganda.app/v1
Staging: https://staging-api.exploreuganda.app/v1
Development: https://dev-api.exploreuganda.app/v1

Authentication

// Example Authentication Header
final headers = {
  'Authorization': 'Bearer ${userToken}',
  'Content-Type': 'application/json',
  'Accept': 'application/json',
  'Api-Version': 'v1'
};

Core APIs

User Management

// User Endpoints
class UserEndpoints {
  static const String base = '/users';
  static const String profile = '$base/profile';
  static const String preferences = '$base/preferences';
  static const String notifications = '$base/notifications';
}

// Example User API Call
Future<User> getUserProfile() async {
  final response = await dio.get(
    UserEndpoints.profile,
    options: Options(headers: headers),
  );
  return User.fromJson(response.data);
}

Content Management

// Content Endpoints
class ContentEndpoints {
  static const String attractions = '/attractions';
  static const String events = '/events';
  static const String services = '/services';
  static const String investments = '/investments';
}

// Example Content API Call
Future<List<Attraction>> getAttractions({
  required int page,
  required int limit,
  String? category,
  String? location,
}) async {
  final response = await dio.get(
    ContentEndpoints.attractions,
    queryParameters: {
      'page': page,
      'limit': limit,
      if (category != null) 'category': category,
      if (location != null) 'location': location,
    },
  );
  return (response.data['data'] as List)
      .map((json) => Attraction.fromJson(json))
      .toList();
}

Third-Party Integrations

Google Maps Integration

// Google Maps Configuration
class MapsConfig {
  static const String apiKey = 'YOUR_GOOGLE_MAPS_API_KEY';
  static const String baseUrl = 'https://maps.googleapis.com/maps/api';
  
  static const Map<String, String> endpoints = {
    'geocoding': '/geocode/json',
    'directions': '/directions/json',
    'places': '/place/nearbysearch/json',
  };
}

// Example Maps Integration
Future<List<Place>> getNearbyPlaces({
  required double latitude,
  required double longitude,
  required String type,
  int radius = 5000,
}) async {
  final response = await dio.get(
    '${MapsConfig.baseUrl}${MapsConfig.endpoints['places']}',
    queryParameters: {
      'location': '$latitude,$longitude',
      'radius': radius,
      'type': type,
      'key': MapsConfig.apiKey,
    },
  );
  return Place.listFromJson(response.data['results']);
}

Payment Integrations

Mobile Money

// Mobile Money Configuration
class MobileMoneyConfig {
  static const String baseUrl = 'https://mm-gateway.exploreuganda.app/v1';
  static const supportedProviders = ['MTN', 'Airtel'];
  
  static Future<bool> initiatePayment({
    required String phoneNumber,
    required double amount,
    required String provider,
  }) async {
    // Implementation
  }
}

International Payments

// Stripe Integration
class StripeService {
  static const String publishableKey = 'YOUR_STRIPE_PUBLISHABLE_KEY';
  
  static Future<PaymentIntent> createPaymentIntent({
    required String currency,
    required int amount,
  }) async {
    // Implementation
  }
}

// PayPal Integration
class PayPalService {
  static const String clientId = 'YOUR_PAYPAL_CLIENT_ID';
  
  static Future<bool> processPayment({
    required double amount,
    required String currency,
  }) async {
    // Implementation
  }
}

Firebase Integration

Firebase Configuration

// Firebase Setup
final firebaseOptions = FirebaseOptions(
  apiKey: 'YOUR_API_KEY',
  appId: 'YOUR_APP_ID',
  messagingSenderId: 'YOUR_SENDER_ID',
  projectId: 'YOUR_PROJECT_ID',
);

// Initialize Firebase
await Firebase.initializeApp(options: firebaseOptions);

Cloud Functions

// Cloud Functions Integration
class CloudFunctions {
  static final functions = FirebaseFunctions.instance;
  
  static Future<void> processBooking(BookingData data) async {
    try {
      await functions
          .httpsCallable('processBooking')
          .call(data.toJson());
    } catch (e) {
      // Error handling
    }
  }
}

Push Notifications

Firebase Cloud Messaging

// FCM Configuration
class FCMConfig {
  static final messaging = FirebaseMessaging.instance;
  
  static Future<void> initialize() async {
    final settings = await messaging.requestPermission();
    final token = await messaging.getToken();
    
    // Save token to backend
    await updateFCMToken(token);
  }
  
  static Future<void> handleBackgroundMessage(
    RemoteMessage message,
  ) async {
    // Handle background message
  }
}

Error Handling

API Error Structure

class APIError {
  final int code;
  final String message;
  final String? details;
  
  APIError({
    required this.code,
    required this.message,
    this.details,
  });
  
  factory APIError.fromJson(Map<String, dynamic> json) {
    return APIError(
      code: json['code'],
      message: json['message'],
      details: json['details'],
    );
  }
}

Error Handling Implementation

Future<T> handleApiCall<T>(Future<T> Function() apiCall) async {
  try {
    return await apiCall();
  } on DioError catch (e) {
    throw APIError(
      code: e.response?.statusCode ?? 500,
      message: e.response?.data['message'] ?? 'Unknown error occurred',
      details: e.response?.data['details'],
    );
  } catch (e) {
    throw APIError(
      code: 500,
      message: 'Internal error occurred',
    );
  }
}

Rate Limiting

API Rate Limits

class RateLimits {
  static const Map<String, int> limits = {
    'attractions': 100,  // requests per minute
    'events': 100,
    'services': 100,
    'search': 60,
    'bookings': 30,
  };
}

API Versioning

Version Control

class APIVersion {
  static const String current = 'v1';
  static const List<String> supported = ['v1'];
  
  static bool isSupported(String version) {
    return supported.contains(version);
  }
}

Testing

API Testing

void main() {
  group('API Integration Tests', () {
    test('Get Attractions', () async {
      final attractions = await getAttractions(
        page: 1,
        limit: 10,
      );
      expect(attractions, isNotEmpty);
    });
    
    test('User Profile', () async {
      final profile = await getUserProfile();
      expect(profile, isNotNull);
    });
  });
}

Documentation Generation

API Documentation

/// Generates Swagger/OpenAPI documentation
void generateApiDocs() {
  // Implementation
}
⚠️ **GitHub.com Fallback** ⚠️