Lesson 127 of 158 – React Native Registration API
80%

React Native Registration API

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.

Note: Registration should always be performed over HTTPS. The PHP server must validate all submitted data, check for duplicate accounts, and securely hash the password before storing it in the database.

1. What is a Registration API?

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.

2. Registration Flow

Registration Screen
       ↓
Name + Email + Password
       ↓
Axios POST
       ↓
PHP Registration API
       ↓
Validate Data
       ↓
Check Duplicate Email
       ↓
Hash Password
       ↓
Insert User
       ↓
Registration Response

3. Registration Request

The React Native application can send JSON data.

{
    "name": "Rahul Kumar",
    "email": "rahul@example.com",
    "password": "123456"
}

4. RegistrationRequest Interface

interface RegistrationRequest {
    name: string;
    email: string;
    password: string;
}

This interface defines the data sent from React Native to the PHP API.

5. Registration Response Interface

interface RegistrationResponse {
    success: boolean;
    message: string;
    user?: User;
}

The user property is optional because a failed registration may not return user information.

6. User Interface

interface User {
    id: number;
    name: string;
    email: string;
    role: "admin" | "teacher" | "student";
}

The interface describes the user returned by the registration API.

7. Creating an Axios Instance

import axios from "axios";

const api = axios.create({
    baseURL: "https://example.com/api",
    headers: {
        "Content-Type": "application/json"
    }
});

8. Registration Function

const registerUser = async (
    data: RegistrationRequest
): Promise<RegistrationResponse> => {

    const response =
        await api.post<RegistrationResponse>(
            "/register.php",
            data
        );

    return response.data;
};

9. Registration Form State

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

10. Creating Registration Data

const data: RegistrationRequest = {
    name,
    email,
    password
};

TypeScript checks that the object contains the required fields.

11. Calling the Registration API

const result =
    await registerUser(data);

console.log(result.message);

The response follows the RegistrationResponse interface.

12. Checking Registration Success

if (result.success) {

    console.log(
        "Registration successful"
    );

} else {

    console.log(
        result.message
    );
}

13. Registration Validation

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.

14. Password Length Validation

if (password.length < 6) {

    setError(
        "Password must contain at least 6 characters"
    );

    return;
}

The server should perform its own password policy validation as well.

15. Loading State

const handleRegister = async () => {

    try {

        setLoading(true);
        setError("");
        setMessage("");

        const result =
            await registerUser({
                name,
                email,
                password
            });

        console.log(result);

    } finally {

        setLoading(false);

    }
};

16. PHP Registration Request

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"] ?? "";

17. PHP Server-Side Validation

if (
    $name === "" ||
    $email === "" ||
    $password === ""
) {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "All fields are required"
    ]);

    exit;
}

18. Validating Email

if (!filter_var(
    $email,
    FILTER_VALIDATE_EMAIL
)) {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "Invalid email address"
    ]);

    exit;
}

19. Checking Duplicate Email

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

20. Hashing the Password

$passwordHash = password_hash(
    $password,
    PASSWORD_DEFAULT
);

Never store a user's plain-text password in the database.

21. Inserting the User

$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.

22. Registration Success Response

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

23. Handling Axios Registration Errors

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

24. Complete Registration Function

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

    }
};

25. Registration Screen

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

26. Showing Registration Messages

{error !== "" && (
    <Text>
        {error}
    </Text>
)}

{message !== "" && (
    <Text>
        {message}
    </Text>
)}

The application can display success and error messages returned by the API.

27. Registration Response with Generic API Type

interface ApiResponse<T> {
    success: boolean;
    message: string;
    data?: T;
}

type RegistrationResponse =
    ApiResponse<User>;

const response =
    await api.post<RegistrationResponse>(
        "/register.php",
        data
    );

28. Complete TypeScript Registration Service

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

29. Complete Registration Architecture

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

30. Complete Registration API Flow

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.

📌 Key Points

  • Registration APIs create new user accounts.
  • React Native can send registration data using Axios.
  • TypeScript interfaces define registration request and response structures.
  • Both client-side and server-side validation are useful.
  • The server should check for duplicate email addresses.
  • Passwords must be securely hashed before database storage.
  • Prepared statements should be used for database queries.
  • HTTP 201 can indicate successful resource creation.
  • HTTP 409 can indicate a duplicate account conflict.
  • HTTP 422 can be used for invalid submitted data.

🧠 Quick Quiz

Question: Which PHP function should be used to securely hash a user's password before storing it?