A User Interface API is an API endpoint that returns information about the currently authenticated user. In a React Native application, this information can be used to display the user's name, email, role, profile information, and other account details.
A User API provides information about a user through an HTTP endpoint.
For example:
GET /api/profile.php
The server can identify the logged-in user using the authentication token and return the user's profile.
React Native
↓
Authorization Header
↓
PHP User API
↓
Verify JWT
↓
Find User
↓
Return JSON
↓
React Native
{
"success": true,
"message": "User profile",
"user": {
"id": 101,
"name": "Rahul Kumar",
"email": "rahul@example.com",
"role": "student"
}
}
TypeScript can describe the structure of the user returned by the API.
interface User {
id: number;
name: string;
email: string;
}
interface User {
id: number;
name: string;
email: string;
role: string;
}
The role can identify whether the user is an admin, teacher, or student.
TypeScript can restrict the role to specific values.
interface User {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
interface UserProfileResponse {
success: boolean;
message: string;
user: User;
}
This interface describes the complete API response.
const response =
await axios.get<UserProfileResponse>(
"/profile"
);
console.log(response.data.user.name);
The Axios generic tells TypeScript the expected response type.
const response =
await axios.get<UserProfileResponse>(
"/profile",
{
headers: {
Authorization:
`Bearer ${token}`
}
}
);
The token allows the server to identify the authenticated user.
A user profile may contain properties such as:
interface User {
id: number;
name: string;
email: string;
mobile: string;
role: string;
}
Some properties may not be available for every user.
interface User {
id: number;
name: string;
email: string;
mobile?: string;
profileImage?: string;
}
The ? means the property is optional.
interface User {
id: number;
name: string;
email: string;
profileImage?: string;
}
React Native can use the profile image URL returned by the API.
<Image
source={{ uri: user.profileImage }}
/>
const api = axios.create({
baseURL: "https://example.com/api"
});
const response =
await api.get<UserProfileResponse>(
"/profile"
);
An Axios instance keeps API configuration in one place.
const getUserProfile =
async (): Promise<UserProfileResponse> => {
const response =
await api.get<UserProfileResponse>(
"/profile"
);
return response.data;
};
const [user, setUser] =
useState<User | null>(null);
const loadProfile = async () => {
const result =
await getUserProfile();
setUser(result.user);
};
The user state can initially be null until the API response arrives.
{user && (
<View>
<Text>{user.name}</Text>
<Text>{user.email}</Text>
<Text>{user.role}</Text>
</View>
)}
const [loading, setLoading] =
useState(false);
const loadProfile = async () => {
try {
setLoading(true);
const result =
await getUserProfile();
setUser(result.user);
} finally {
setLoading(false);
}
};
interface UserApiError {
success: false;
message: string;
code?: string;
}
This can describe a structured error returned by the API.
If the JWT is missing, invalid, or expired, the API may return
HTTP status 401.
if (error.response?.status === 401) {
console.log("Please login again");
}
The application can then clear authentication state and navigate to the login screen.
Authentication identifies the user, while authorization determines whether the user can access a particular resource.
Authorization: Bearer JWT_TOKEN
The PHP API should verify the token and enforce any required permissions.
Some APIs use a standard data property.
{
"success": true,
"message": "Profile loaded",
"data": {
"id": 101,
"name": "Rahul",
"email": "rahul@example.com",
"role": "student"
}
}
interface UserResponse {
success: boolean;
message: string;
data: User;
}
Then Axios can use:
const response =
await api.get<UserResponse>(
"/profile"
);
interface User {
id: number;
name: string;
email: string;
mobile: string;
role: "admin" | "teacher" | "student";
profileImage?: string;
createdAt: string;
}
The interface should match the actual JSON structure returned by the API.
interface ApiResponse<T> {
success: boolean;
message: string;
data: T;
}
type UserResponse =
ApiResponse<User>;
This generic structure can also be reused for other API resources.
export const getUser =
async (): Promise<UserResponse> => {
const response =
await api.get<UserResponse>(
"/profile"
);
return response.data;
};
Keeping API functions in a service file makes React Native components cleaner.
useEffect(() => {
const loadProfile = async () => {
try {
const result =
await getUser();
setUser(result.data);
} catch (error) {
console.log(
"Unable to load profile"
);
}
};
loadProfile();
}, []);
interface User {
id: number;
name: string;
email: string;
mobile?: string;
role: "admin" | "teacher" | "student";
profileImage?: string;
createdAt?: string;
}
interface UserResponse {
success: boolean;
message: string;
data: User;
}
import axios from "axios";
interface User {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
interface UserResponse {
success: boolean;
message: string;
data: User;
}
const api = axios.create({
baseURL: "https://example.com/api"
});
const getUser =
async (
token: string
): Promise<UserResponse> => {
const response =
await api.get<UserResponse>(
"/profile",
{
headers: {
Authorization:
`Bearer ${token}`
}
}
);
return response.data;
};
const [user, setUser] =
useState<User | null>(null);
const loadProfile = async () => {
try {
const result =
await getUser(token);
if (result.success) {
setUser(result.data);
}
} catch (error) {
console.log(
"Profile loading failed"
);
}
};
useEffect(() => {
loadProfile();
}, []);
return (
<View>
{user && (
<>
<Text>
Name: {user.name}
</Text>
<Text>
Email: {user.email}
</Text>
<Text>
Role: {user.role}
</Text>
</>
)}
</View>
);
Login
↓
Receive JWT
↓
Store Authentication State
↓
GET /profile
↓
Authorization: Bearer JWT
↓
PHP Verifies JWT
↓
Find User
↓
Return UserResponse
↓
TypeScript Validates Structure
↓
Update React Native State
↓
Display User Profile
TypeScript interfaces make user API communication predictable and easier to maintain. The same User interface can be reused in profile screens, authentication state, navigation, and other protected screens.
User | null.Question: Which TypeScript type is suitable when the user may not have been loaded yet?