Unlocking WordPress Apiw

cartography
Unlocking WordPress Apiw

In the ever-evolving landscape of web development, the ability to seamlessly connect applications and services is paramount.

Crafting Your Own API Endpoints

You are absolutely correct! My apologies for the previous generic example. Thank you for providing the link. That GitHub repository offers a fantastic, practical example of creating a tailored API endpoint for a custom post type.

Let's break down that specific code and present it as a detailed article. This approach is much more powerful as it deals with custom content types and formats the output exactly as needed.

Building a Custom "Projects" API Endpoint in WordPress: A Code-Driven Guide

When building a headless or decoupled application with a WordPress backend, the default API endpoints are a good start, but they often provide more—or less—data than you actually need. The real power of the WordPress REST API lies in creating custom endpoints that deliver precisely the data your front-end application requires.

This article provides a step-by-step breakdown of a real-world example from a GitHub repository by "neeryks", which builds a custom API endpoint to display "Projects."

The Goal: A Clean API for "Projects"

The objective of the code in the repository is to create a new API endpoint: /wp-json/neeryks/v1/projects. When accessed, this endpoint will return a clean, curated list of all published "Projects," including their title, content, featured image, and any associated "Project Types."

This is a common requirement for portfolio sites, case study pages, or any application that needs to fetch and display a specific type of content.

Step 1: Laying the Foundation with Custom Content Types

Before we can create an API for our projects, we need to tell WordPress what a "Project" is. The code accomplishes this by first registering a custom post type called projects and a custom taxonomy called project-type.

  • register_post_type('projects', ...): This function creates a new "Projects" section in the WordPress admin panel. It defines the labels (like "Add New Project"), sets it to be public, and, crucially, enables REST API support with 'show_in_rest' => true.
  • register_taxonomy('project-type', 'projects', ...): This function creates a way to categorize our projects, similar to standard post categories. It's linked directly to the projects post type.

This foundational step ensures our custom content is fully integrated into WordPress and accessible to the API.

Step 2: Registering the Custom API Route

This is the core of the API creation process. The code uses the rest_api_init action to register the new route.

add_action('rest_api_init', function () {
register_rest_route('neeryks/v1', 'projects', [
'methods' => 'GET',
'callback' => 'get_projects',
'permission_callback' => '__return_true',
]);
});

Let's dissect this:

  • 'neeryks/v1': This is the unique namespace. It prevents our endpoint from conflicting with other plugins or WordPress core endpoints.
  • 'projects': This is the route, defining the URL. The full path will be /wp-json/neeryks/v1/projects.
  • 'methods' => 'GET': This specifies that the endpoint responds to GET requests, as its purpose is to retrieve data.
  • 'callback' => 'get_projects': This is the most important part. It tells WordPress to execute the get_projects function when this endpoint is requested.
  • 'permission_callback' => '__return_true': This makes the endpoint public and accessible to anyone. For production sites where data should be protected, you would replace this with a function that checks for user authentication or specific permissions (e.g., current_user_can('read')).

Step 3: Crafting the Custom Callback Function (get_projects)

The get_projects function is where the magic happens. It queries the database, gathers all the necessary data, formats it perfectly, and sends it back.

Here's a breakdown of its logic:

  1. Query the Posts: It uses get_posts to fetch all published posts of the projects post type. PHP

$posts = get_posts([
'post_type' => 'projects',
'post_status' => 'publish',
'posts_per_page' => -1,
]);

  1. Check for Results: If no projects are found, it returns an error using WP_Error.
  2. Loop and Format: It iterates through each post object found. Inside the loop, it builds a custom array ($response_data) for each project. This is the key to creating a clean and efficient API response.
    • It gets basic data like ID, title, slug, content, and excerpt.
    • It gets the Featured Image: It uses get_the_post_thumbnail_url() to get a direct URL for the featured image, which is exactly what a front-end application needs.
    • It gets the Taxonomy Terms: It uses get_the_terms() to find all project-type terms associated with the post and adds them to the response.
  3. Return the Response: Finally, it wraps the carefully constructed array of projects in a WP_REST_Response object. This ensures the data is sent as a proper JSON response with a 200 OK status code.

The Complete Code (wp-api-post.php)

PHP

<?php
/* Plugin Name: WP API Post */

// Register Custom Post Type and Taxonomy
function register_project_cpt() {
register_post_type('projects', [
'label' => 'Projets',
'public' => true,
'menu_position' => 3,
'menu_icon' => 'dashicons-admin-customizer',
'supports' => ['title', 'editor', 'thumbnail', 'excerpt'],
'show_in_rest' => true,
'rewrite' => ['slug' => 'projects'],
]);

register_taxonomy('project-type', 'projects', [
'label' => 'Type de projet',
'rewrite' => ['slug' => 'project-type'],
'hierarchical' => true,
'show_in_rest' => true,
]);
}
add_action('init', 'register_project_cpt');

// Register API route
add_action('rest_api_init', function () {
register_rest_route('neeryks/v1', 'projects', [
'methods' => 'GET',
'callback' => 'get_projects',
'permission_callback' => '__return_true',
]);
});

// Callback function to get projects data
function get_projects($request) {
$posts = get_posts([
'post_type' => 'projects',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
]);

if (empty($posts)) {
return new WP_Error('empty_projects', 'No projects to display', ['status' => 404]);
}

$response_data = [];
foreach ($posts as $post) {
$post_id = $post->ID;
$project_types = get_the_terms($post_id, 'project-type');

$response_data[] = [
'id' => $post_id,
'title' => $post->post_title,
'slug' => $post->post_slug,
'content' => $post->post_content,
'excerpt' => $post->post_excerpt,
'thumbnail' => get_the_post_thumbnail_url($post_id, 'large'),
'project_types' => $project_types ? $project_types : [],
];
}

$response = new WP_REST_Response($response_data);
$response->set_status(200);

return $response;
}

By following this code's example, you can move beyond the generic and build powerful, efficient, and clean APIs for any type of content in WordPress.