In a TypeScript React Native application, API requests can also be strongly typed. This means we can define the structure of data that will be sent from the mobile application to the PHP REST API.
A typed API request means defining the structure of data that will be sent to the server using TypeScript.
interface LoginRequest {
email: string;
password: string;
}
This interface describes the data required by a login API.
Suppose we want to send student information to a PHP API.
interface StudentRequest {
name: string;
email: string;
mobile: string;
}
The request object should contain these properties.
const studentData: StudentRequest = {
name: "Rahul Kumar",
email: "rahul@example.com",
mobile: "9876543210"
};
TypeScript checks the structure of studentData.
Axios can send a typed request object to a PHP REST API.
const response =
await api.post(
"/students",
studentData
);
The request data is already checked by TypeScript because
studentData uses the StudentRequest interface.
interface LoginRequest {
email: string;
password: string;
}
This interface can be used by a React Native login screen.
const loginData: LoginRequest = {
email: "user@example.com",
password: "123456"
};
The object now follows the structure defined by
LoginRequest.
const response =
await api.post<LoginResponse>(
"/login",
loginData
);
Here, LoginRequest describes the request body and
LoginResponse describes the response.
interface RegisterRequest {
name: string;
email: string;
mobile: string;
password: string;
}
This can describe the data submitted from a registration form.
const registerData: RegisterRequest = {
name: "Amit Kumar",
email: "amit@example.com",
mobile: "9876543210",
password: "mypassword"
};
The request object can now be passed to the registration API.
const response =
await api.post<RegisterResponse>(
"/register",
registerData
);
The generic type specifies the expected API response.
Some request fields may not be required.
interface StudentRequest {
name: string;
email: string;
mobile?: string;
}
Here, mobile is optional.
Sometimes a request field can contain either a value or
null.
interface StudentRequest {
name: string;
email: string;
photo: string | null;
}
The application can send either a photo value or null.
IDs and numeric values should use the number type when
the API expects numbers.
interface CreateStudentRequest {
name: string;
courseId: number;
age: number;
}
const data: CreateStudentRequest = {
name: "Rahul",
courseId: 5,
age: 18
};
Boolean values can also be typed.
interface StudentStatusRequest {
studentId: number;
active: boolean;
}
const data: StudentStatusRequest = {
studentId: 10,
active: true
};
PUT requests can use a request interface to update existing records.
interface UpdateStudentRequest {
name: string;
email: string;
mobile: string;
}
const studentData: UpdateStudentRequest = {
name: "Rahul Kumar",
email: "rahul@example.com",
mobile: "9876543210"
};
await api.put(
"/students/10",
studentData
);
PATCH requests usually update only selected fields.
interface UpdateStudentEmailRequest {
email: string;
}
const data: UpdateStudentEmailRequest = {
email: "new@example.com"
};
await api.patch(
"/students/10",
data
);
Query parameters can also be represented with an interface.
interface StudentSearchParams {
search: string;
page: number;
limit: number;
}
const params: StudentSearchParams = {
search: "Rahul",
page: 1,
limit: 10
};
const params: StudentSearchParams = {
search: "Rahul",
page: 1,
limit: 10
};
const response =
await api.get(
"/students",
{
params: params
}
);
Axios converts the parameters into a query string.
Filters can also be defined using an interface.
interface StudentFilterParams {
courseId?: number;
status?: string;
page?: number;
limit?: number;
}
Optional properties allow the application to send only the filters selected by the user.
interface StudentSortParams {
sort: string;
order: "asc" | "desc";
}
The union type restricts order to either
asc or desc.
const params: StudentSortParams = {
sort: "name",
order: "asc"
};
React Native form state can use the same request interface.
const [form, setForm] =
useState<StudentRequest>({
name: "",
email: "",
mobile: ""
});
This keeps the form structure consistent with the API request.
const submitStudent = async () => {
try {
const response =
await api.post<CreateStudentResponse>(
"/students",
form
);
console.log(response.data);
} catch (error) {
console.log(error);
}
};
The React Native form sends JSON to the PHP REST API.
A complete API operation can have both a typed request and a typed response.
interface CreateStudentRequest {
name: string;
email: string;
mobile: string;
}
interface CreateStudentResponse {
success: boolean;
message: string;
data: Student;
}
const requestData: CreateStudentRequest = {
name: "Rahul",
email: "rahul@example.com",
mobile: "9876543210"
};
const response =
await api.post<CreateStudentResponse>(
"/students",
requestData
);
Avoid using any when the request structure is known.
// Avoid
const data: any = {
name: "Rahul",
email: "rahul@example.com"
};
Prefer:
interface StudentRequest {
name: string;
email: string;
}
const data: StudentRequest = {
name: "Rahul",
email: "rahul@example.com"
};
The React Native application sends JSON to the PHP REST API.
React Native
↓
TypeScript Request Interface
↓
Axios
↓
JSON Request
↓
PHP REST API
↓
Validation
↓
MySQL
The PHP server should still validate the received data. TypeScript improves the client-side development experience but does not replace server-side validation.
any unnecessarily.interface StudentRequest {
name: string;
email: string;
mobile: string;
courseId: number;
}
const studentData: StudentRequest = {
name: "Rahul Kumar",
email: "rahul@example.com",
mobile: "9876543210",
courseId: 5
};
const response =
await api.post<CreateStudentResponse>(
"/students",
studentData
);
interface LoginRequest {
email: string;
password: string;
}
interface LoginResponse {
success: boolean;
message: string;
token: string;
user: {
id: number;
name: string;
email: string;
};
}
const login = async () => {
const data: LoginRequest = {
email: "user@example.com",
password: "123456"
};
try {
const response =
await api.post<LoginResponse>(
"/login",
data
);
console.log(response.data.token);
} catch (error) {
console.log("Login failed");
}
};
React Native Form
↓
TypeScript Request Interface
↓
Request Object
↓
Axios
↓
JSON Request
↓
PHP REST API
↓
Server Validation
↓
MySQL
↓
JSON Response
↓
TypeScript Response Interface
↓
React Native UI
For example, a student registration screen can create a
RegisterRequest object and send it through Axios.
The PHP API validates the data, saves it in MySQL, and returns a
JSON response that can be represented by a TypeScript response interface.
This approach creates a clear contract between the React Native application and the REST API.
?.asc and desc.Question: Which TypeScript feature is commonly used to define the structure of data sent to an API?