What is a REST API?
REST (Representational State Transfer) APIs allow applications to communicate over HTTP by sending requests to access or manipulate data. A RESTful API typically includes HTTP methods like GET, POST, PUT, and DELETE, which correspond to CRUD (Create, Read, Update, Delete) operations.
Prerequisites
- PHP installed on your system.
- A basic understanding of PHP and HTTP methods.
- A simple database (we’ll use MySQL in this example).
Project Structure
For this example, our project will have the following structure:
project-folder/ ├── api/ │ ├── config.php │ ├── database.php │ ├── categories.php │ └── products.php ├── products/ │ └── index.php ├── categories/ │ └── index.php └── index.php
Note
For simplicity, this tutorial focuses on a single entity,
products
. However, you can apply similar logic to create additional APIs for other entities, such ascategories
,orders
, orcustomers
. Once you're comfortable with these basic steps, try expanding this API by adding endpoints for related data or new functionality.
Step 1: Setting Up the Database
Create a MySQL database and a table for the example. This example uses a products
table with some sample fields.
SQL to create the products
table:
CREATE DATABASE test_api; USE test_api; CREATE TABLE products ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, description TEXT, price DECIMAL(10, 2) NOT NULL );
Step 2: Database Configuration (config.php
)
In the api
folder, create a config.php
file to store the database connection details.
<?php // api/config.php define('DB_HOST', 'localhost'); define('DB_NAME', 'test_api'); define('DB_USER', 'root'); define('DB_PASS', ''); ?>
Step 3: Database Connection Class (database.php
)
Create a database.php
file in the api
folder to handle the database connection.
<?php // api/database.php class Database { private $host = DB_HOST; private $db_name = DB_NAME; private $username = DB_USER; private $password = DB_PASS; public $conn; public function getConnection() { $this->conn = null; try { $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password); $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $exception) { echo "Connection error: " . $exception->getMessage(); } return $this->conn; } } ?>
Step 4: Creating the API Endpoints (products.php
)
This file will handle the main API logic. It will listen for different HTTP methods and respond accordingly.
<?php // api/products.php include_once 'config.php'; include_once 'database.php'; header("Content-Type: application/json; charset=UTF-8"); $database = new Database(); $db = $database->getConnection(); $requestMethod = $_SERVER["REQUEST_METHOD"]; $request = explode("/", trim($_SERVER["REQUEST_URI"], "/")); $resource = $request[1] ?? null; if ($resource !== 'products') { echo json_encode(["message" => "Resource not found."]); exit(); } switch ($requestMethod) { case 'GET': if (isset($_GET['id']) && is_numeric($_GET['id'])) { getProduct($_GET['id']); } else { getProducts(); } break; case 'POST': createProduct(); break; case 'PUT': if (isset($_GET['id']) && is_numeric($_GET['id'])) { updateProduct($_GET['id']); } else { echo json_encode(["message" => "Provide id to updates"]); } break; case 'DELETE': if (isset($_GET['id']) && is_numeric($_GET['id'])) { deleteProduct($_GET['id']); } else { echo json_encode(["message" => "Provide id to updates"]); } break; default: echo json_encode(["message" => "Method not allowed"]); break; } function getProducts() { global $db; $query = "SELECT * FROM products"; $stmt = $db->prepare($query); $stmt->execute(); $products = $stmt->fetchAll(PDO::FETCH_ASSOC); echo json_encode($products); } function getProduct($id) { global $db; $query = "SELECT * FROM products WHERE id = ?"; $stmt = $db->prepare($query); $stmt->execute([$id]); $product = $stmt->fetch(PDO::FETCH_ASSOC); if ($product) { echo json_encode($product); } else { echo json_encode(["message" => "Product not found"]); } } function createProduct() { global $db; $data = json_decode(file_get_contents("php://input"), true); $query = "INSERT INTO products (name, description, price) VALUES (?, ?, ?)"; $stmt = $db->prepare($query); if ($stmt->execute([$data['name'], $data['description'], $data['price']])) { echo json_encode(["message" => "Product created"]); } else { echo json_encode(["message" => "Failed to create product"]); } } function updateProduct($id) { global $db; $data = json_decode(file_get_contents("php://input"), true); $query = "UPDATE products SET name = ?, description = ?, price = ? WHERE id = ?"; $stmt = $db->prepare($query); if ($stmt->execute([$data['name'], $data['description'], $data['price'], $id])) { echo json_encode(["message" => "Product updated"]); } else { echo json_encode(["message" => "Failed to update product"]); } } function deleteProduct($id) { global $db; $query = "DELETE FROM products WHERE id = ?"; $stmt = $db->prepare($query); if ($stmt->execute([$id])) { echo json_encode(["message" => "Product deleted"]); } else { echo json_encode(["message" => "Failed to delete product"]); } } ?>
Step 5: Routing Requests to products.php
In the products folder, create an index.php
file to handle incoming requests and redirect them to products.php
inside api folder.
<?php // index.php require '../api/products.php';
Step 6: Testing the API
With the API set up, you can test it using a tool like Postman or cURL.
Example Requests
- GET All Products:
GET https://domain-name.com/project-folder/products/
- GET Product by ID:
GET https://domain-name.com/project-folder/products?id=1
- POST Create Product:
POST
https://domain-name.com/project-folder/products/ with JSON body:
{ "name": "New Product", "description": "This is a test product", "price": 9.99 }
- PUT Update Product:
PUT
https://domain-name.com/project-folder/products?id=1 with JSON body
{ "name": "Updated Product", "description": "This is an updated description", "price": 19.99 }
- DELETE Product:
DELETE
https://domain-name.com/project-folder/products?id=1
Download the Postman Collection
To make testing even easier, you can download a Postman collection pre-configured with all the API endpoints used in this tutorial. Simply import the collection into Postman and start sending requests.
Download Postman Collection for Products APITo import the collection you can check this link on How to Import data into Postman.
Conclusion
In this article, we built a simple REST API using native PHP, which handles CRUD operations for a products
table in MySQL. This approach is ideal for small applications or for developers who want to learn the fundamentals of REST APIs in PHP. With this setup, you can expand the API by adding authentication, validation, and additional resources.
Creating a REST API using native PHP is a great way to understand the basics of web development and data handling. Once you have mastered this, you can enhance your API with other features, such as:
- Authentication and Authorization
- Error Handling and Validation
- Pagination and Sorting
Experiment with different objects to build a full-fledged backend API for a web or mobile application.