Lesson 118 of 158 – Typed API Requests
75%

Typed API Requests

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.

Note: Typed API requests are useful for login forms, registration, student creation, updating records, searching, filtering, and other REST API operations.

1. What is a Typed API Request?

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.

2. Why Type API Requests?

  • Prevents incorrect property names.
  • Improves code completion.
  • Helps catch incorrect data types.
  • Makes API code easier to understand.
  • Improves maintainability.
  • Provides better integration with PHP REST APIs.

3. Basic Request Interface

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.

4. Creating a Request Object

const studentData: StudentRequest = {
    name: "Rahul Kumar",
    email: "rahul@example.com",
    mobile: "9876543210"
};

TypeScript checks the structure of studentData.

5. Typed POST Request

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.

6. Login Request Interface

interface LoginRequest {
    email: string;
    password: string;
}

This interface can be used by a React Native login screen.

7. Login Request Object

const loginData: LoginRequest = {
    email: "user@example.com",
    password: "123456"
};

The object now follows the structure defined by LoginRequest.

8. Sending a Typed Login Request

const response =
    await api.post<LoginResponse>(
        "/login",
        loginData
    );

Here, LoginRequest describes the request body and LoginResponse describes the response.

9. Registration Request Interface

interface RegisterRequest {
    name: string;
    email: string;
    mobile: string;
    password: string;
}

This can describe the data submitted from a registration form.

10. Registration Request Object

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.

11. Typed Registration API Call

const response =
    await api.post<RegisterResponse>(
        "/register",
        registerData
    );

The generic type specifies the expected API response.

12. Optional Request Properties

Some request fields may not be required.

interface StudentRequest {
    name: string;
    email: string;
    mobile?: string;
}

Here, mobile is optional.

13. Nullable Request Properties

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.

14. Number Values in Requests

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
};

15. Boolean Values in Requests

Boolean values can also be typed.

interface StudentStatusRequest {
    studentId: number;
    active: boolean;
}
const data: StudentStatusRequest = {
    studentId: 10,
    active: true
};

16. Typed PUT Request

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
);

17. Typed PATCH Request

PATCH requests usually update only selected fields.

interface UpdateStudentEmailRequest {
    email: string;
}
const data: UpdateStudentEmailRequest = {
    email: "new@example.com"
};

await api.patch(
    "/students/10",
    data
);

18. Typed Search Parameters

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
};

19. Sending Typed Query Parameters

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.

20. Typed Filter Parameters

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.

21. Typed Sorting Parameters

interface StudentSortParams {
    sort: string;
    order: "asc" | "desc";
}

The union type restricts order to either asc or desc.

const params: StudentSortParams = {
    sort: "name",
    order: "asc"
};

22. Typed Request with Form State

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.

23. Sending Form Data to PHP API

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.

24. Typed Request and Typed Response Together

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
    );

25. Avoiding any in API Requests

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"
};

26. PHP REST API and Typed Requests

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.

27. Common Typed Request Mistakes

  • Using the wrong property name.
  • Using a string when the API expects a number.
  • Forgetting required fields.
  • Sending unexpected fields without checking the API contract.
  • Using any unnecessarily.
  • Assuming TypeScript validation protects the PHP server.
Important: Always validate request data again on the server.

28. Complete Typed Student Request

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
    );

29. Complete Login Request Example

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");

    }
};

30. Complete Typed API Request Flow

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.

📌 Key Points

  • TypeScript interfaces can describe data sent to REST APIs.
  • Typed requests reduce property and data-type mistakes.
  • Login and registration requests can be strongly typed.
  • POST, PUT, and PATCH request bodies can use interfaces.
  • Query parameters can also be represented with interfaces.
  • Optional properties can be marked with ?.
  • Union types can restrict values such as asc and desc.
  • Axios can combine typed request data with typed API responses.
  • TypeScript does not replace server-side PHP validation.
  • A clear request interface creates a better contract between React Native and the REST API.

🧠 Quick Quiz

Question: Which TypeScript feature is commonly used to define the structure of data sent to an API?