Extending the WordPress JSON API to include featured image urls

By default WordPress’ inbuilt JSON API doesn’t include the URL for a post’s featured image with the main request for the post. Instead, it requires you to use the featured_media field returned by the initial JSON response to make a separate request to a different endpoint to retrieve the featured image information.

We use a headless install of WordPress as the back-end of our website coupled with a Vue.js powered front-end. To reduce the number of API requests it takes to get all of the information needed to display the content on our site, we extend the API fields returned by the main request.

Adding our featured image information

Using the rest_api_init action hook, we wrote a couple of PHP functions to extend the dataset returned by the request.

The first of these functions registers a new field for the ‘post’ default post-type called nss_featured_images. The second is responsible for populating that field with the desired featured image information.

As we want to use featured images at different image sizes in our site design, the API feed needs to contain information for different image sizes. We therefore add more than one size to our field so we can then choose which image to display on the front-end.

Registering our custom field

We add the following small function attached to the ‘rest_api_init’ action hook to register our field:

/**
 * Add Featured Image srcs
 * 
 * By default WordPress only includes the id of the featured image with JSON data.
 * This function extends the defaut rest api data to return the src value for featured 
 * images.
 * 
 * @since 1.0.0
 */
function nss_add_featured_image_srcs() {
	register_rest_field( 'post', 'nss_featured_images', array(
		'get_callback'    => 'nss_get_featured_image_data',
		'update_callback' => null,
		'schema'          => null
	) );
}
add_action( 'rest_api_init', 'nss_add_featured_image_srcs' ) );

This function adds a second function to the 'get_callback' array item that populates the field with our images.

Retrieving the correct featured image information

/**
 * Get Featured Image Data
 * 
 * Retrieves extra featured image data to add to the JSON response.
 * 
 * @param  array $post_arr            An array of data relating to the post that has been requested via
 *                                    the rest api.
 * @return array $nss_featured_images An array of featured image sizes & srcs added to the JSON response under
 *                                    nss_featured_images parameter.
 * @since 1.0.0
 */
public function nss_get_featured_image_data( $post_arr ) {
	if ( isset( $post_arr[ 'featured_media' ] ) && !empty( $post_arr[ 'featured_media' ] ) ) {
		// Prepare our size array
		$sizes = array();

		// Get image size names
		$intermediate_image_sizes = get_intermediate_image_sizes();

		foreach( $intermediate_image_sizes as $size ) {
			$image     = wp_get_attachment_image_src( $post_arr[ 'featured_media' ], $size );
			$image_alt = get_post_meta( $post_arr[ 'featured_media' ], '_wp_attachment_image_alt', TRUE ); 

			if( $image ) {
				$sizes[ $size ]['src']    = $image[0];
				$sizes[ $size ]['width']  = $image[1];
				$sizes[ $size ]['height'] = $image[2];
				$sizes[ $size ]['crop']   = $image[3];
				$sizes[ $size ]['srcset'] = wp_get_attachment_image_srcset( $post_arr[ 'featured_media' ], $size );
				$sizes[ $size ]['alt']    = $image_alt;
			}
		}
		
		return $sizes;
	} else {
		return false;
	}
}

Let’s go through what the function above does:

  1. Firstly the function checks that the post has been assigned a featured image by checking the array of post information ($post_arr) passed to the function by the rest_api_init action hook. If it doesn’t find one, it gives the custom rest field a false value.
  2. Second, it uses the get_intermediate_image_sizes() WordPress function to retrieve an array of image size names (‘medium’, ‘large’ etc.) that have been registered in the current WordPress install.
  3. Third, it loops through the array of image size names returned in the previous step and retrieves the information we want for each image.
  4. Fourth, it adds the information for each image size to a $sizes array.
  5. Fifth, it passes back the constructed $sizes array to be used as the content of our custom rest field. We don’t need to json_encode() the array as WordPress will handle this when constructing the data for the API endpoint.

Result

Using the above we are able to add the additional image information to the standard WordPress JSON API endpoint for the ‘post’ post-type. This makes sure that we have all the information we want in a single request.

Visiting the /wp-json/wp/v2/posts endpoint of our WordPress install shows that our custom featured image information has been added to the data returned as part of the API request:

Extra featured image fields in WP-JSON API

Using this method we are able to extend the default WordPress JSON API endpoints and add all kinds of other information to the default feed!

Tags: php