A registration API allows a React Native application to create a new user account on the server. In this lesson, we will connect a React Native registration form with a PHP REST API using Axios and TypeScript.
A registration API creates a new user account in the database.
POST /api/register.php
The React Native application sends user information to the API, and the PHP server validates and stores the account.
Registration Screen
↓
Name + Email + Password
↓
Axios POST
↓
PHP Registration API
↓
Validate Data
↓
Check Duplicate Email
↓
Hash Password
↓
Insert User
↓
Registration Response
The React Native application can send JSON data.
{
"name": "Rahul Kumar",
"email": "rahul@example.com",
"password": "123456"
}
interface RegistrationRequest {
name: string;
email: string;
password: string;
}
This interface defines the data sent from React Native to the PHP API.
interface RegistrationResponse {
success: boolean;
message: string;
user?: User;
}
The user property is optional because a failed registration may not return user information.
interface User {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
The interface describes the user returned by the registration API.
import axios from "axios";
const api = axios.create({
baseURL: "https://example.com/api",
headers: {
"Content-Type": "application/json"
}
});
const registerUser = async (
data: RegistrationRequest
): Promise<RegistrationResponse> => {
const response =
await api.post<RegistrationResponse>(
"/register.php",
data
);
return response.data;
};
const [name, setName] =
useState("");
const [email, setEmail] =
useState("");
const [password, setPassword] =
useState("");
const [loading, setLoading] =
useState(false);
const [error, setError] =
useState("");
const [message, setMessage] =
useState("");
const data: RegistrationRequest = {
name,
email,
password
};
TypeScript checks that the object contains the required fields.
const result =
await registerUser(data);
console.log(result.message);
The response follows the RegistrationResponse interface.
if (result.success) {
console.log(
"Registration successful"
);
} else {
console.log(
result.message
);
}
The mobile application can perform basic validation before making the API request.
if (!name || !email || !password) {
setError(
"All fields are required"
);
return;
}
Client-side validation improves the user experience, but server-side validation is still mandatory.
if (password.length < 6) {
setError(
"Password must contain at least 6 characters"
);
return;
}
The server should perform its own password policy validation as well.
const handleRegister = async () => {
try {
setLoading(true);
setError("");
setMessage("");
const result =
await registerUser({
name,
email,
password
});
console.log(result);
} finally {
setLoading(false);
}
};
PHP can read the JSON request body using php://input.
$input = json_decode(
file_get_contents("php://input"),
true
);
$name = trim($input["name"] ?? "");
$email = trim($input["email"] ?? "");
$password = $input["password"] ?? "";
if (
$name === "" ||
$email === "" ||
$password === ""
) {
http_response_code(422);
echo json_encode([
"success" => false,
"message" => "All fields are required"
]);
exit;
}
if (!filter_var(
$email,
FILTER_VALIDATE_EMAIL
)) {
http_response_code(422);
echo json_encode([
"success" => false,
"message" => "Invalid email address"
]);
exit;
}
$stmt = $pdo->prepare(
"SELECT id
FROM users
WHERE email = ?"
);
$stmt->execute([$email]);
if ($stmt->fetch()) {
http_response_code(409);
echo json_encode([
"success" => false,
"message" => "Email already registered"
]);
exit;
}
$passwordHash = password_hash(
$password,
PASSWORD_DEFAULT
);
Never store a user's plain-text password in the database.
$stmt = $pdo->prepare(
"INSERT INTO users
(name, email, password, role)
VALUES (?, ?, ?, ?)"
);
$stmt->execute([
$name,
$email,
$passwordHash,
"student"
]);
Prepared statements should be used when inserting user data.
$userId = $pdo->lastInsertId();
http_response_code(201);
echo json_encode([
"success" => true,
"message" => "Registration successful",
"user" => [
"id" => (int)$userId,
"name" => $name,
"email" => $email,
"role" => "student"
]
]);
try {
const result =
await registerUser(data);
if (result.success) {
setMessage(result.message);
}
} catch (error) {
if (axios.isAxiosError(error)) {
const message =
error.response?.data?.message;
setError(
message || "Registration failed"
);
} else {
setError(
"Something went wrong"
);
}
}
const handleRegister = async () => {
if (!name || !email || !password) {
setError("All fields are required");
return;
}
try {
setLoading(true);
setError("");
setMessage("");
const data: RegistrationRequest = {
name,
email,
password
};
const result =
await registerUser(data);
if (result.success) {
setMessage(
result.message
);
setName("");
setEmail("");
setPassword("");
} else {
setError(
result.message
);
}
} catch (error) {
setError(
"Unable to connect to server"
);
} finally {
setLoading(false);
}
};
<TextInput
placeholder="Name"
value={name}
onChangeText={setName}
/>
<TextInput
placeholder="Email"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
/>
<TextInput
placeholder="Password"
secureTextEntry
value={password}
onChangeText={setPassword}
/>
<Button
title="Register"
onPress={handleRegister}
/>
{error !== "" && (
<Text>
{error}
</Text>
)}
{message !== "" && (
<Text>
{message}
</Text>
)}
The application can display success and error messages returned by the API.
interface ApiResponse<T> {
success: boolean;
message: string;
data?: T;
}
type RegistrationResponse =
ApiResponse<User>;
const response =
await api.post<RegistrationResponse>(
"/register.php",
data
);
interface RegistrationRequest {
name: string;
email: string;
password: string;
}
interface User {
id: number;
name: string;
email: string;
role: "admin" | "teacher" | "student";
}
interface RegistrationResponse {
success: boolean;
message: string;
user?: User;
}
const registerUser = async (
data: RegistrationRequest
): Promise<RegistrationResponse> => {
const response =
await api.post<RegistrationResponse>(
"/register.php",
data
);
return response.data;
};
React Native
│
│ RegistrationRequest
↓
Axios
│
│ POST /register.php
↓
PHP REST API
│
├── Validate Name
├── Validate Email
├── Validate Password
├── Check Duplicate Email
├── Hash Password
└── Insert User
│
↓
RegistrationResponse
│
├── success
├── message
└── user
│
↓
React Native
│
↓
Show Success / Error
1. User opens registration screen
2. User enters name, email and password
3. React Native validates basic input
4. Axios sends POST request
5. PHP reads JSON data
6. PHP validates submitted data
7. PHP checks duplicate email
8. PHP hashes the password
9. PHP inserts the new user
10. PHP returns JSON response
11. React Native handles success or error
12. User can then proceed to login
A registration API connects the React Native user interface with the PHP/MySQL backend. TypeScript keeps the request and response structures predictable, while the PHP server remains responsible for validation, password hashing, database security, and account creation.
Question: Which PHP function should be used to securely hash a user's password before storing it?