Hello! Welcome to the final lesson of our capstone module and the "PHP Mastery" course.
In our last session, you did an excellent job securing our application's views against Cross-Site Scripting (XSS) attacks. By creating a reusable e() helper function and consistently escaping all dynamic data on output, you've implemented a critical security defense.
Today, we're going to pivot from building a user-facing web application to creating a data-facing one. Our goal is to create a simple API endpoint for one of the application's resources. This will allow other applications (like a mobile app or a JavaScript-based frontend) to consume our data in a structured, predictable way. This is a fundamental skill for any modern web developer.
By the end of this lesson, you will have built a functional API endpoint that can serve a list of posts and individual posts in JSON format, directly from your existing application.
1. What is a REST API?
Before we start coding, let's establish what an API, specifically a REST API, is. API stands for Application Programming Interface. It's a set of rules and protocols that allows different software applications to communicate with each other.
A REST API (Representational State Transfer) is an architectural style for designing networked applications. It's the most common standard used for communication between web clients and servers.

To get a quick and clear overview of the core concepts, let's watch a short video.
What Is REST API? Examples And How To Use It: Crash Course System Design #3
This video from ByteByteGo, 'What Is REST API?', provides a concise explanation of REST principles.
Watch from the beginning to 03:38. Pay close attention to: Resources as Nouns: How endpoints are named after the data they represent (e.g., /products, not /getAllProducts). HTTP Verbs for Actions: The mapping of GET, POST, PUT, DELETE to CRUD (Create, Read, Update, Delete) operations. Response Structure: The use of JSON for data payloads and HTTP status codes to indicate the outcome of a request.
As the video explained, the key ideas are:
- Resources: The "things" your API provides data about. In our case, the primary resource is a
post. - Endpoints: The URLs that represent these resources, e.g.,
/api/posts. - HTTP Methods: The verbs that define the action you want to perform on the resource (
GETto read,POSTto create, etc.). - Representation: The format of the data returned, which is almost always JSON (JavaScript Object Notation).
2. Planning Our API Endpoints
For this lesson, we'll focus on the "Read" part of CRUD and create two GET endpoints for our posts resource:
GET /api/posts: This will return a list of all posts.GET /api/posts/{id}: This will return a single post identified by its ID.
The response for both will be in JSON format. We'll also ensure our API returns appropriate HTTP status codes:
200 OK: When a request is successful.404 Not Found: When a post with the requested ID does not exist.
3. Implementing the API Endpoints
Let's integrate this functionality into our existing MVC application. The process involves creating a new route, a dedicated API controller, and methods to handle the requests and return JSON.
Step 1: Create a Dedicated API Controller
It's good practice to separate API logic from your web-facing controllers.
- Create a new directory inside your controllers directory:
app/Controllers/Api. - Inside this new directory, create a file named
PostController.php. This will be ourApi\PostController.
The basic structure of this controller will be similar to your existing PostController, as it will also depend on your Post model/gateway to fetch data.
// app/Controllers/Api/PostController.php
namespace App\Controllers\Api;
use App\Models\Post; // Or your PostGateway/Model class
class PostController
{
private $postModel;
public function __construct()
{
// Assuming your model can be instantiated like this.
// Adjust if you use dependency injection.
$this->postModel = new Post();
}
// We will add methods here for index() and show().
}
Step 2: Add Routing for the API
Now, let's teach our router how to handle the new API endpoints. Open your router class (e.g., app/Router.php) and add the routes. We'll use regular expressions to capture the numeric ID for the single-post endpoint.
// In your Router class, where you register routes
// ... existing web routes ...
// API routes
$router->get('/api/posts', 'App\Controllers\Api\PostController@index');
$router->get('/api/posts/(\d+)', 'App\Controllers\Api\PostController@show');
// ...
This tells the router to direct requests for /api/posts to the index method of our new API controller, and requests for /api/posts/{id} to the show method.
Step 3: Implement the index() Method (Get All Posts)
The index() method will fetch all posts from the database and return them as a JSON array.
// In app/Controllers/Api/PostController.php
// ... inside the PostController class
public function index()
{
// Fetch all posts from the model
$posts = $this->postModel->findAll();
// Set the response header to indicate JSON content
header('Content-Type: application/json');
// Set the HTTP status code
http_response_code(200);
// Encode the data to JSON and output it
echo json_encode($posts);
}
This implementation is straightforward:
- It reuses our existing
findAll()method from the model. - It sets the
Content-Typeheader, which tells the client (e.g., a browser) to interpret the response body as JSON. - It uses
json_encode()to convert the PHP array of posts into a JSON string.

Step 4: Implement the show($id) Method (Get a Single Post)
The show($id) method will handle fetching a single post. It must also gracefully handle cases where the post doesn't exist.
// In app/Controllers/Api/PostController.php
// ... inside the PostController class
public function show($id)
{
// Fetch the post from the model
$post = $this->postModel->find($id);
header('Content-Type: application/json');
if (!$post) {
// If the post is not found, return a 404 error
http_response_code(404);
echo json_encode(['error' => 'Post not found']);
return; // Stop execution
}
// If the post is found, return it with a 200 status code
http_response_code(200);
echo json_encode($post);
}
This method introduces error handling: if the model returns false or null, we set a 404 Not Found status code and return a clear JSON error message.
For a detailed walkthrough of building a very similar API structure from scratch, the following video is an excellent resource. You don't need to code along with it, but watch the selected parts to see these same concepts applied in a complete project.
Create a PHP REST API : Write a RESTful API from Scratch using Plain, Object-Oriented PHP and MySQL
The video 'Create a PHP REST API' by Dave Hollingworth demonstrates building a complete API with a structure very similar to our capstone project. Let's watch the key segments related to what we just built.
Watch the following two segments: Handling a GET request for a collection (16:45 - 18:30): Notice how he calls a getAll() method on his gateway, gets an array of data, and then echoes the json_encode() result. This is exactly what we did in our index() method. Handling a GET request for a single resource (33:33 - 36:40): Observe how he first fetches the record by its ID. He then checks if the result is valid and, if not, sends a 404 response with an error message. This mirrors our show() method's logic.
4. Testing Your API
Your API endpoints are now ready to be tested!
- Make sure your local development server is running.
- Test the collection endpoint: Open your web browser and navigate to
http://localhost:8000/api/posts(adjust the URL and port if yours is different). You should see a JSON array of all the posts from your database. - Test the single resource endpoint: Navigate to
http://localhost:8000/api/posts/1. You should see the JSON object for the post with an ID of 1. - Test the not found case: Navigate to an ID that doesn't exist, like
http://localhost:8000/api/posts/999. You should see your JSON error message:{"error":"Post not found"}.
Your browser might have a plugin to format the JSON, making it more readable. If it just shows a wall of text, that's also correct!
Conclusion and Your Journey Forward
Congratulations! You have successfully created a simple, functional API for your application and completed the final learning outcome of the capstone project. This is a huge milestone. You've now experienced the full spectrum of building a modern PHP application, from fundamental syntax to MVC architecture, security, and now, API development.
Today's Key Takeaways:
- REST APIs are a standard way for applications to communicate over the web, using resources (nouns) and HTTP methods (verbs).
- JSON is the standard data format for modern APIs due to its simplicity and readability.
- Creating an API endpoint in an MVC application involves routing, a dedicated controller, and model interaction.
- It is crucial to set the
Content-Type: application/jsonheader and use appropriate HTTP status codes (200,404, etc.) to communicate the outcome of a request.
This lesson marks the end of the "PHP Mastery" course. You have built a complete, secure, and modern PHP application from the ground up. You should be incredibly proud of what you've accomplished.
What's Next for You?
Your journey to PHP mastery doesn't end here. Here are some excellent next steps to consider:
- Expand Your API: Challenge yourself to implement the other CRUD operations (
POST,PATCH,DELETE) for your posts resource. The video and textual resources from this lesson cover how to do this. - Explore Frameworks: Now that you understand the core principles, dive into a major PHP framework like Laravel or Symfony. They provide powerful tools that make building complex applications and APIs much faster and more structured.
- Deepen Your Security Knowledge: Your interest in cybersecurity is a valuable asset. Explore API authentication standards like OAuth 2.0 or token-based methods (e.g., API keys, JWT) to secure your endpoints.
- Contribute to Open Source: Find a PHP project on GitHub that interests you and start contributing. It's one of the best ways to learn from experienced developers.
Thank you for your hard work and dedication throughout this course. You now have a solid foundation to build a successful career as a PHP developer. Good luck