In this lesson, we will create the main Student REST API for our Student Management mobile application.
This API will connect the React Native application with the MySQL students table through PHP and PDO. The API will support reading, creating, updating, and deleting student records.
The Student API will be the main communication layer between the React Native application and the students table.
React Native
↓
Axios
↓
students.php
↓
JWT Verification
↓
PDO
↓
MySQL
↓
JSON Response
We can create the main endpoint as:
/api/students.php
Different HTTP methods can perform different operations on the same endpoint.
| Method | Operation |
|---|---|
| GET | Read students |
| POST | Add student |
| PUT | Update student |
| DELETE | Delete student |
Our API works with the students table created earlier.
students
id
name
email
mobile
course
address
created_at
A simple project structure can be:
api/
│
├── register.php
├── login.php
├── students.php
├── profile.php
│
├── config/
│ └── database.php
│
└── auth/
└── jwt.php
The exact organization can be expanded as the project grows.
header(
"Content-Type: application/json"
);
Since our API returns JSON responses, the response content type should be set to JSON.
require_once '../config/database.php';
The API should use the existing PDO database connection rather than creating a new connection for every individual query.
Protected student APIs need access to the JWT library.
require_once __DIR__ .
'/vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
The exact path should match the location of Composer's
vendor directory in your project.
$headers = getallheaders();
$authorization =
$headers['Authorization']
?? '';
The API needs the Authorization header to obtain the JWT sent by the mobile application.
if (
!preg_match(
'/Bearer\s(\S+)/',
$authorization,
$matches
)
) {
http_response_code(401);
echo json_encode([
"success" => false,
"message" =>
"Authentication required"
]);
exit;
}
$token = $matches[1];
$secretKey =
'CHANGE_THIS_TO_A_LONG_RANDOM_SECRET';
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 secret key and algorithm must match those used when the token was created.
Our JWT contains the user's ID in the sub claim.
$userId = (int) $decoded->sub;
This identifies the authenticated user making the API request.
A GET request can retrieve student records.
GET /api/students.php
The API can return a list of students as JSON.
$stmt = $pdo->prepare(
"SELECT
id,
name,
email,
mobile,
course,
address,
created_at
FROM students
ORDER BY id DESC"
);
$stmt->execute();
$students =
$stmt->fetchAll(
PDO::FETCH_ASSOC
);
Only fields required by the mobile application are returned.
echo json_encode([
"success" => true,
"message" => "Students retrieved",
"data" => $students
]);
React Native can read the data array and display it using
FlatList.
A student ID can be supplied as a query parameter.
GET /api/students.php?id=5
PHP can read the ID:
$id = filter_input(
INPUT_GET,
'id',
FILTER_VALIDATE_INT
);
$stmt = $pdo->prepare(
"SELECT
id,
name,
email,
mobile,
course,
address,
created_at
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;
}
HTTP 404 is appropriate when the requested student does not exist.
A POST request will create a new student.
POST /api/students.php
Example JSON request:
{
"name": "Amit Kumar",
"email": "amit@example.com",
"mobile": "9876543210",
"course": "Python",
"address": "Patna"
}
$input = json_decode(
file_get_contents("php://input"),
true
);
$name =
trim($input['name'] ?? '');
$email =
trim($input['email'] ?? '');
$mobile =
trim($input['mobile'] ?? '');
$course =
trim($input['course'] ?? '');
$address =
trim($input['address'] ?? '');
if ($name === '') {
http_response_code(422);
echo json_encode([
"success" => false,
"message" =>
"Student name is required"
]);
exit;
}
Server-side validation should always be performed even if the React Native application validates the form.
$stmt = $pdo->prepare(
"INSERT INTO students
(name, email, mobile, course, address)
VALUES (?, ?, ?, ?, ?)"
);
$stmt->execute([
$name,
$email,
$mobile,
$course,
$address
]);
Prepared statements should be used for the INSERT operation.
$studentId =
$pdo->lastInsertId();
http_response_code(201);
echo json_encode([
"success" => true,
"message" =>
"Student added successfully",
"data" => [
"id" => $studentId,
"name" => $name,
"email" => $email,
"mobile" => $mobile,
"course" => $course,
"address" => $address
]
]);
The PUT method can update an existing student.
PUT /api/students.php?id=5
The request body can contain the updated student information.
{
"name": "Amit Kumar",
"email": "amit@example.com",
"mobile": "9999999999",
"course": "React Native",
"address": "Patna"
}
The DELETE method can remove a student.
DELETE /api/students.php?id=5
The API should first validate the ID and check whether the student exists before deleting the record.
$stmt = $pdo->prepare(
"DELETE FROM students
WHERE id = ?"
);
$stmt->execute([$id]);
The API can support search using a query parameter.
GET /api/students.php?search=rahul
PHP can safely search multiple fields using prepared statements.
SELECT *
FROM students
WHERE name LIKE ?
OR email LIKE ?
OR mobile LIKE ?
The Student API should eventually support pagination for large student lists.
GET /api/students.php?page=1&limit=10
The offset can be calculated as:
$offset = ($page - 1) * $limit;
React Native can use FlatList's onEndReached to load
additional pages.
import api from "./api";
export async function getStudents() {
const response =
await api.get("/students.php");
return response.data;
}
Keeping API calls inside service functions makes the mobile project easier to maintain.
interface Student {
id: number;
name: string;
email: string;
mobile: string;
course: string;
address: string;
created_at: string;
}
interface StudentResponse {
success: boolean;
message: string;
data: Student[];
}
The interface helps TypeScript understand the data returned by the Student API.
React Native
↓
Axios
↓
Authorization: Bearer JWT
↓
students.php
↓
JWT Verification
↓
Request Validation
↓
PDO Prepared Statement
↓
MySQL
↓
JSON Response
↓
React Native
↓
FlatList / Forms
The Student API is the core backend component of our mobile Student Management application.
In the next lesson, we will build the dedicated API endpoint for adding students.
students.php.Question: Which HTTP method is used to create a new student in the Student API?