Lesson 145 of 158 – Project Delete Student API
92%

Project Delete Student API

In this lesson, we will create the Delete Student API for our Student Management mobile application.

The React Native application will send a DELETE request using Axios. The PHP REST API will verify the JWT, validate the student ID, check whether the student exists, and delete the student record from MySQL using PDO.

Project Goal: Delete an existing student securely using the HTTP DELETE method, JWT authentication, PHP, MySQL, PDO, Axios, and TypeScript.

1. Delete Student API Flow

React Native Student List
        ↓
Delete Button
        ↓
Confirmation
        ↓
Axios DELETE
        ↓
students.php?id=5
        ↓
JWT Verification
        ↓
Validate Student ID
        ↓
Check Student
        ↓
PDO DELETE
        ↓
MySQL
        ↓
JSON Response

2. HTTP DELETE Method

The HTTP DELETE method is used when we want to remove an existing resource from the server.

DELETE /api/students.php?id=5

Here, 5 identifies the student that should be deleted.

3. Why Delete API Needs Authentication

Deleting a student is a sensitive operation. Therefore, the API should not allow anonymous users to delete records.

Authorization:
Bearer YOUR_JWT_TOKEN

The server should verify the JWT before executing the DELETE query.

4. API Content Type

header(
    "Content-Type: application/json"
);

The API uses JSON for its response.

5. Database Connection

require_once '../config/database.php';

The existing PDO database connection can be reused by the delete endpoint.

6. Check HTTP Method

if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Method not allowed"
    ]);

    exit;
}

This prevents GET, POST, or other methods from accidentally reaching the delete logic.

7. Read Authorization Header

$headers = getallheaders();

$authorization =
    $headers['Authorization']
    ?? '';

The Authorization header contains the Bearer JWT sent by the mobile application.

8. Extract Bearer Token

if (
    !preg_match(
        '/Bearer\s(\S+)/',
        $authorization,
        $matches
    )
) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Authentication required"
    ]);

    exit;
}

$token = $matches[1];

9. Verify JWT

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

try {

    $decoded = JWT::decode(
        $token,
        new Key(
            $secretKey,
            'HS256'
        )
    );

} catch (Exception $e) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Invalid or expired token"
    ]);

    exit;
}

The server should never trust a token simply because it exists. The signature and expiration must be verified.

10. Get Student ID

$id = filter_input(
    INPUT_GET,
    'id',
    FILTER_VALIDATE_INT
);

The student ID is received from the query parameter.

DELETE /api/students.php?id=5

11. Validate Student ID

if (!$id || $id <= 0) {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" =>
            "Valid student ID is required"
    ]);

    exit;
}

Always validate the ID before using it in the database query.

12. Check Whether Student Exists

$stmt = $pdo->prepare(
    "SELECT id
     FROM students
     WHERE id = ?"
);

$stmt->execute([$id]);

$student = $stmt->fetch(
    PDO::FETCH_ASSOC
);

if (!$student) {

    http_response_code(404);

    echo json_encode([
        "success" => false,
        "message" =>
            "Student not found"
    ]);

    exit;
}

Checking existence lets the API return a clear 404 response instead of reporting a successful deletion for a record that does not exist.

13. DELETE SQL Statement

DELETE FROM students
WHERE id = ?

The placeholder is replaced safely using a prepared statement.

14. Execute DELETE with PDO

$stmt = $pdo->prepare(
    "DELETE FROM students
     WHERE id = ?"
);

$stmt->execute([$id]);

Prepared statements help prevent SQL injection.

15. Check Deleted Rows

$deleted =
    $stmt->rowCount();

rowCount() can be used to determine how many rows were affected by the DELETE operation.

16. Successful Delete Response

http_response_code(200);

echo json_encode([
    "success" => true,
    "message" =>
        "Student deleted successfully"
]);

The mobile application can use this response to remove the student from the displayed list.

17. Complete PHP Delete API

<?php

header(
    "Content-Type: application/json"
);

require_once '../config/database.php';
require_once __DIR__ .
    '/vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secretKey =
    'CHANGE_THIS_TO_A_LONG_RANDOM_SECRET';

if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Method not allowed"
    ]);

    exit;
}

$headers = getallheaders();

$authorization =
    $headers['Authorization']
    ?? '';

if (
    !preg_match(
        '/Bearer\s(\S+)/',
        $authorization,
        $matches
    )
) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Authentication required"
    ]);

    exit;
}

$token = $matches[1];

try {

    JWT::decode(
        $token,
        new Key(
            $secretKey,
            'HS256'
        )
    );

    $id = filter_input(
        INPUT_GET,
        'id',
        FILTER_VALIDATE_INT
    );

    if (!$id || $id <= 0) {

        http_response_code(400);

        echo json_encode([
            "success" => false,
            "message" =>
                "Valid student ID is required"
        ]);

        exit;
    }

    $stmt = $pdo->prepare(
        "SELECT id
         FROM students
         WHERE id = ?"
    );

    $stmt->execute([$id]);

    if (!$stmt->fetch()) {

        http_response_code(404);

        echo json_encode([
            "success" => false,
            "message" =>
                "Student not found"
        ]);

        exit;
    }

    $stmt = $pdo->prepare(
        "DELETE FROM students
         WHERE id = ?"
    );

    $stmt->execute([$id]);

    http_response_code(200);

    echo json_encode([
        "success" => true,
        "message" =>
            "Student deleted successfully"
    ]);

} catch (Exception $e) {

    error_log($e->getMessage());

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" =>
            "Invalid or expired token"
    ]);
}

18. Axios DELETE Request

React Native can use Axios to send the DELETE request.

const response =
    await api.delete(
        `/students.php?id=${studentId}`
    );

The api Axios instance can automatically add the JWT Authorization header through the interceptor created earlier.

19. Delete Confirmation

A confirmation dialog is recommended before permanently deleting a student.

Alert.alert(
    "Delete Student",
    "Are you sure you want to delete this student?",
    [
        {
            text: "Cancel",
            style: "cancel"
        },
        {
            text: "Delete",
            onPress: () =>
                deleteStudent(studentId)
        }
    ]
);

20. Delete Student Function

const deleteStudent =
    async (studentId: number) => {

    try {

        const response =
            await api.delete(
                `/students.php?id=${studentId}`
            );

        if (response.data.success) {

            Alert.alert(
                "Success",
                response.data.message
            );

        }

    } catch (error) {

        Alert.alert(
            "Error",
            "Unable to delete student"
        );
    }
};

21. TypeScript Delete Response

interface DeleteStudentResponse {
    success: boolean;
    message: string;
}

This interface describes the JSON response returned by the PHP API.

22. Typed Axios DELETE

const response =
    await api.delete<DeleteStudentResponse>(
        `/students.php?id=${studentId}`
    );

TypeScript now knows the expected structure of response.data.

23. Remove Student from FlatList

After a successful delete, the application can remove the student from the local state.

setStudents(
    students.filter(
        student =>
            student.id !== studentId
    )
);

This immediately updates the displayed list without requiring the user to restart the application.

24. Handle API Errors

try {

    await api.delete(
        `/students.php?id=${studentId}`
    );

} catch (error) {

    if (
        axios.isAxiosError(error) &&
        error.response
    ) {

        const status =
            error.response.status;

        if (status === 401) {
            // Login again
        }

        else if (status === 404) {
            // Student not found
        }

        else if (status === 403) {
            // Permission denied
        }

        else {
            // Other API error
        }
    }
}

25. DELETE Status Codes

Status Meaning
200 Student deleted successfully
400 Invalid student ID
401 Authentication required or token invalid
403 User does not have permission
404 Student not found
405 HTTP method not allowed
500 Server/database error

26. Testing Delete API in Postman

Method: DELETE

URL:

https://example.com/api/students.php?id=5

Headers:

Authorization: Bearer YOUR_JWT_TOKEN

Send the request and check the JSON response.

{
    "success": true,
    "message": "Student deleted successfully"
}

27. Security Considerations

  • Always authenticate the delete request.
  • Verify the JWT on the server.
  • Check user permissions when required.
  • Validate the student ID.
  • Use PDO prepared statements.
  • Do not build DELETE SQL using string concatenation.
  • Do not expose database errors to the mobile application.
  • Use HTTPS in production.
  • Consider related records before deleting a student.

28. Important Database Consideration

A student may have related records in other tables such as payments, attendance, assignments, or results.

Before deleting a student permanently, the database design should decide whether related records should also be deleted, preserved, or disconnected.

students
   |
   +---- payments
   |
   +---- attendance
   |
   +---- assignments
   |
   +---- results
Best Practice: For important applications, consider soft deletion such as an is_deleted field when historical records must be preserved.

29. Complete Mobile Delete Flow

Student List
     ↓
Delete Button
     ↓
Confirmation Alert
     ↓
Axios DELETE
     ↓
JWT Authorization
     ↓
PHP REST API
     ↓
Verify JWT
     ↓
Validate ID
     ↓
Check Student
     ↓
PDO DELETE
     ↓
MySQL
     ↓
JSON Response
     ↓
Update React Native State
     ↓
Student Removed from List

30. Delete Student API Summary

The Delete Student API completes the DELETE operation of our student management backend.

  • DELETE is used to remove a student.
  • The student ID is passed using ?id=.
  • A valid JWT should be required.
  • The server verifies the token before deleting data.
  • The API validates the student ID.
  • The API checks whether the student exists.
  • PDO prepared statements are used for DELETE.
  • HTTP 200 indicates a successful deletion.
  • HTTP 404 indicates that the student does not exist.
  • React Native uses Axios to call the API.
  • TypeScript can type the delete response.
  • A confirmation dialog helps prevent accidental deletion.
  • The next lesson will implement student search.

📌 Key Points

  • The DELETE HTTP method removes an existing resource.
  • The student ID is supplied as a query parameter.
  • JWT authentication protects the delete endpoint.
  • The API should verify that the student exists.
  • PDO prepared statements should be used.
  • rowCount() can inspect affected rows.
  • HTTP 404 is used when the student is not found.
  • HTTP 401 is used for invalid or missing authentication.
  • React Native can use Axios for DELETE requests.
  • A confirmation dialog should be shown before deletion.
  • Related student records should be considered before permanent deletion.

🧠 Quick Quiz

Question: Which HTTP method is used to delete a student from the REST API?