API Integration
API integration guide for ZÈYA Mobile App.
API Configuration
Base URLs
The app uses environment-based API endpoints:
Production:
https://zeyaapp.com/api/v1/
Staging:
https://staging.zeyaapp.com/api/v1/
Environment Variables
Configured in eas.json and .env:
EXPO_PUBLIC_API_URL=zeyaapp.com/api/v1
EXPO_PUBLIC_FILE_URL=zeyaapp.com
EXPO_PUBLIC_HTTP_PROTOCOL=https
EXPO_PUBLIC_APP_ENV=production
EXPO_PUBLIC_LOCAL_API_URL=staging.zeyaapp.com/api/v1
EXPO_PUBLIC_LOCAL_FILE_URL=staging.zeyaapp.com
EXPO_PUBLIC_LOCAL_HTTP_PROTOCOL=https
API Provider
ApiProvider Context
The app uses a centralized API provider (src/context/ApiProvider.js):
import { ApiContext } from '../context/ApiProvider';
function MyComponent() {
const { apiCall, authToken, user } = useContext(ApiContext);
// Use API context
}
Features
- Automatic token management
- Request/response interceptors
- Error handling
- Unauthorized endpoint handling
- Token refresh
Making API Calls
Basic API Call
import { useContext } from 'react';
import { ApiContext } from '../context/ApiProvider';
function MyComponent() {
const { apiCall } = useContext(ApiContext);
const fetchData = async () => {
try {
const response = await apiCall('products', {
method: 'GET',
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
};
}
POST Request
const createProduct = async (productData) => {
try {
const response = await apiCall('add-product', {
method: 'POST',
data: productData,
});
return response.data;
} catch (error) {
throw error;
}
};
PUT/PATCH Request
const updateProduct = async (productId, updates) => {
try {
const response = await apiCall(`update-product/${productId}`, {
method: 'POST',
data: updates,
});
return response.data;
} catch (error) {
throw error;
}
};
DELETE Request
const deleteProduct = async (productId) => {
try {
const response = await apiCall(`product/${productId}`, {
method: 'DELETE',
});
return response.data;
} catch (error) {
throw error;
}
};
Authentication
Login
const login = async (email, password) => {
try {
const response = await apiCall('login', {
method: 'POST',
data: { email, password },
});
// Token is automatically stored by ApiProvider
return response.data;
} catch (error) {
throw error;
}
};
Register
const register = async (userData) => {
try {
const response = await apiCall('register', {
method: 'POST',
data: userData,
});
return response.data;
} catch (error) {
throw error;
}
};
Logout
const logout = async () => {
try {
await apiCall('logout', {
method: 'GET',
});
// Token is automatically cleared by ApiProvider
} catch (error) {
throw error;
}
};
Unauthorized Endpoints
The following endpoints don't require authentication:
loginregisterpassword-reset-otp-sentvalidate-otpsubmit-reset-passwordalternate-loginalternate-login-appleguest-productspreview-groupspreview-groups-dataget-dashboard-datasave-guest-device
Error Handling
API Error Structure
{
success: false,
error: "Error message",
code: "ERROR_CODE",
errors: { ... } // For validation errors
}
Handling Errors
try {
const response = await apiCall('endpoint');
} catch (error) {
if (error.response) {
// Server responded with error
const { error: errorMessage, code, errors } = error.response.data;
if (code === 'VALIDATION_ERROR') {
// Handle validation errors
console.log('Validation errors:', errors);
} else {
// Handle other errors
Alert.alert('Error', errorMessage);
}
} else if (error.request) {
// Request made but no response
Alert.alert('Network Error', 'Please check your internet connection');
} else {
// Something else happened
Alert.alert('Error', 'An unexpected error occurred');
}
}
Response Format
Success Response
{
"success": true,
"data": { ... },
"message": "Operation successful"
}
Paginated Response
{
"success": true,
"data": [ ... ],
"pagination": {
"current_page": 1,
"total_pages": 5,
"total_items": 100,
"per_page": 20,
"has_next": true,
"has_prev": false
}
}
Common API Endpoints
Products
// Get products
apiCall('products', { method: 'GET' });
// Create product
apiCall('add-product', {
method: 'POST',
data: productData,
});
// Update product
apiCall(`update-product/${id}`, {
method: 'POST',
data: updates,
});
// Delete product
apiCall(`product/${id}`, { method: 'DELETE' });
User Profile
// Get user profile
apiCall('user-profile', { method: 'GET' });
// Update profile
apiCall('user-update', {
method: 'POST',
data: profileData,
});
Chat
// Get chats
apiCall('user-chat', { method: 'GET' });
// Get messages
apiCall(`user-chat/${transactionId}/message`, {
method: 'GET',
});
// Send message
apiCall(`user-chat/${transactionId}/message`, {
method: 'POST',
data: { text: 'Hello' },
});
Groups
// Get groups
apiCall('groups', { method: 'GET' });
// Create group
apiCall('groups', {
method: 'POST',
data: groupData,
});
// Join group
apiCall('group-join', {
method: 'POST',
data: { group_uid: '...' },
});
File Uploads
Upload Product Images
import * as ImagePicker from 'expo-image-picker';
const uploadProductImages = async (productId, images) => {
const formData = new FormData();
images.forEach((image, index) => {
formData.append(`images[${index}]`, {
uri: image.uri,
type: 'image/jpeg',
name: `image_${index}.jpg`,
});
});
try {
const response = await apiCall(`update-product/${productId}`, {
method: 'POST',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
},
});
return response.data;
} catch (error) {
throw error;
}
};
API Utilities
Storage Utilities
import Storage from '../share/storage';
// Save token
await Storage().saveToken('auth_token', token);
// Get token
const token = await Storage().getToken('auth_token');
// Remove token
await Storage().removeToken('auth_token');
Constants
import Constants from '../share/constant';
// Use API constants
const AUTH_KEY = Constants().AUTH__TENANT_KEY;
Testing API Integration
Mock API Responses
// For development/testing
const mockResponse = {
success: true,
data: { ... },
};
// Use in tests or development
Network Debugging
- Use Flipper for network inspection
- Check Expo CLI logs
- Use React Native Debugger