Integrate React native
React Native applications connect to Apso through the generated REST API. Use an end-user access token for mobile requests and keep service API keys in a server or BFF.
Store the user token securely
For an Expo application:
npx expo install expo-secure-storesrc/lib/session.ts
import * as SecureStore from 'expo-secure-store';
const TOKEN_KEY = 'apso_access_token';
export const session = {
getToken: () => SecureStore.getItemAsync(TOKEN_KEY),
setToken: (token: string) => SecureStore.setItemAsync(TOKEN_KEY, token),
clearToken: () => SecureStore.deleteItemAsync(TOKEN_KEY),
};Use platform-backed secure storage for tokens. Do not ship an Apso service API key in the application bundle.
Create an API client
src/lib/api.ts
import { session } from './session';
const API_URL = 'https://your-service.apso.cloud';
export async function apiRequest<T>(path: string, init?: RequestInit): Promise<T> {
const token = await session.getToken();
const response = await fetch(`${API_URL}${path}`, {
...init,
headers: {
'Content-Type': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
...init?.headers,
},
});
if (!response.ok) {
throw new Error(`Request failed with ${response.status}`);
}
return response.json() as Promise<T>;
}Load a paginated resource
Generated list endpoints return a paginated result when pagination is enabled:
src/screens/projects-screen.tsx
import { useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
import { apiRequest } from '../lib/api';
interface Project {
id: number;
name: string;
}
interface ProjectPage {
data: Project[];
count: number;
total: number;
page: number;
pageCount: number;
}
export function ProjectsScreen() {
const [result, setResult] = useState<ProjectPage | null>(null);
const [error, setError] = useState<string | null>(null);
const load = useCallback(async () => {
try {
setResult(await apiRequest<ProjectPage>('/Projects?limit=20&page=1'));
} catch (requestError) {
setError((requestError as Error).message);
}
}, []);
useEffect(() => { void load(); }, [load]);
if (error) return <Text accessibilityRole="alert">{error}</Text>;
if (!result) return <ActivityIndicator />;
return (
<FlatList
data={result.data}
keyExtractor={(item) => String(item.id)}
onRefresh={load}
refreshing={false}
renderItem={({ item }) => <View><Text>{item.name}</Text></View>}
/>
);
}Create a record
await apiRequest('/Projects', {
method: 'POST',
body: JSON.stringify({ name: 'Mobile launch', status: 'Active' }),
});Mobile checklist
- Store user credentials in platform-backed secure storage.
- Clear local credentials after a
401response or explicit logout. - Add request timeouts and retry only idempotent operations.
- Treat offline mode and interrupted writes as normal states.
- Validate tenant scope on the server.
- Use HTTPS for every non-local request.
Related
Last updated on