Wordpress - WP Rest API: details of latest post including featured media url in one request?

Ah I just had this problem myself! And while _embed is great, in my experience it is very slow, and the point of JSON is to be fast :D

I have the following code in a plugin (used for adding custom post types), but I imagine you could put it in your theme's function.php file.

php

add_action( 'rest_api_init', 'add_thumbnail_to_JSON' );
function add_thumbnail_to_JSON() {
//Add featured image
register_rest_field( 
    'post', // Where to add the field (Here, blog posts. Could be an array)
    'featured_image_src', // Name of new field (You can call this anything)
    array(
        'get_callback'    => 'get_image_src',
        'update_callback' => null,
        'schema'          => null,
         )
    );
}

function get_image_src( $object, $field_name, $request ) {
  $feat_img_array = wp_get_attachment_image_src(
    $object['featured_media'], // Image attachment ID
    'thumbnail',  // Size.  Ex. "thumbnail", "large", "full", etc..
    true // Whether the image should be treated as an icon.
  );
  return $feat_img_array[0];
}

Now in your JSON response you should see a new field called "featured_image_src": containing a url to the thumbnail.

Read more about modifying responses here:
http://v2.wp-api.org/extending/modifying/

And here's more information on theregister_rest_field and wp_get_attachment_image_src() functions:
1.) https://developer.wordpress.org/reference/functions/register_rest_field/
2.) https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/

**Note: Don't forget <?php ?> tags if this is a new php file!


Just add the _embed query argument to your URL asking for the posts, and every post object, will include the _embedded.[wp:featuredmedia] object, which includes all the images, just like the /media/$id resource. If you want an specific size, just access it by its property name, i.e.: _embedded[wp:featuredmedia][0].media_details.sizes.full.source_url or for its thumbnail: _embedded[wp:featuredmedia][0].media_details.sizes.thumbnail.source_url

That is, the wp:featuredmedia embedded object includes all the URLs and details for every size available for your post, but if you want just the original featured image, you can use the value in this key: post._embedded["wp:featuredmedia"][0].source_url

I use it in a site with something like this (use your own domain, of course):

$.get('https://example.com/wp-json/wp/v2/posts/?categories=3&_embed', 
    function(posts) { 
        var elems = '';
        posts.forEach(function(post){ 
            var link = post.link;
            var title = post.title.rendered;
            var pic = post._embedded["wp:featuredmedia"][0].source_url);
            elems += '<div class="this_week"><a href="' + link + '" target="_blank">';
            elems += '<img src="' + pic + '" title="' + title + '"/><span class="title">';
            elems += title + '</span></a></div>';
        });
        $('#blockbusters').html(elems);
    });
});

See? No need for two queries, just add _embed as a query argument, and then you have all the information you need to use the best size for your view.


Adding &_embed to your URL will add the wp:featuremedia to your JSON even if you have custom posts, Example

https://example.com/wp-json/wp/v2/posts?search=Sometitlepost&_embed&order=asc