The WordPress REST API is a core feature introduced in WordPress 4.7 allowing developers to make HTTP requests to access WordPress data as a JSON object. The REST API allows for many different solutions, whether you are looking to create a decoupled website or app with data from a WordPress backend, or to simply allow external websites to read a post feed. In this article is a look at common scenarios for customizing the REST API response for GET requests to posts.
Note: Most custom post type arguments will and should utilize more of the many post type options available than shown in this short example.
However, if the custom post type has been registered in a 3rd-party or contributed plugin or theme, it is a better practice to modify the arguments list in a function located in a custom theme or plugin and invoking the
In either case, setting
In an example case where the API client needs the post's author name presented at the same level as the post title and publish date, it is best to add a new field to the response. It is important to not modify the existing
Getting to know the capabilities of the WordPress REST API is a first step toward thinking outside the box with the WordPress CMS and creating new applications leveraging WordPress' standard structured data and backend.
Code
WordPress
A brief look at the core API
By default, a WordPress site’s post information can be found atyourwebsite.address/wp-json/v2/posts
. This endpoint displays the 10 most recent posts of any type. What is actually returned in the default response are the rows and fields in the database table wp_posts
of type “post”, plus the ID(s) of the featured image, categories, and tags, if any. Similarly, pages (posts of type "page" in the WordPress database) can be found at yourwebsite.address/wp-json/v2/pages
.
Adding custom post types
The REST API supports custom post types, but if the custom post type has been registered without setting theshow_in_rest
argument to true
, the response will return a 404 with the code rest_no_route
. Ideally, if the WordPress website is registering the custom post type through a custom theme or plugin, the modification can be made in the original argument array passed to register_post_type():
function pluginname_custom_post_type() { $args = array( 'label' => 'Custom Post Type', 'public' => true, 'show_in_rest' => true, 'rest_base' => 'custom' ); register_post_type( 'custom_post_type', $args ); } add_action( 'init', 'custom_post_type' );
register_post_type_args
hook:
function pluginname_modify_custom_post_type( $args, $post_type ) { if ( $post_type == 'custom_post_type' ) { $args['show_in_rest'] = true; $args['rest_base'] = 'custom'; } return $args; } add_action( 'register_post_type_args', 'modify_custom_post_type' );
show_in_true
to true
allows a new endpoint to be accessed using the rest_base
value. In this example: /wp-json/wp/v2/custom
.
Adding fields to the WordPress core response
There are cases where it is necessary or just convenient to modify the fields returned in the response. For example, while any data included in the_links
section of a post with "embeddable": true
can be included in its entirety without making another HTTP request by adding _embed=1
to the query, the embedded data might be too many layers deep to easily deal with from the API client's perspective:
"_embedded": { "author": { { "id": 1, "name": "Aten Design Group", "url": "https://www.aten.io", "description": "", "link": "https://www.aten.io", "slug": "atendesigngroup" } } }
author
field to ensure that API clients are able to continue working with the standard core response, regardless of any one client's needs.
register_rest_field() should be used in a custom function to add fields to the REST API response, and invoking that function with the rest_api_init
hook:
function pluginname_get_author_name( $post, $field_name, $request ) { return get_the_author_meta( 'display_name', (int) $post['author'] ); } function pluginname_add_author_name_to_api() { register_rest_field( 'post', 'author_name', array( 'get_callback' => 'pluginname_get_author_name' ) ); } add_action( 'rest_api_init', 'pluginname_add_author_name_to_api' );
Creating a custom endpoint
There are cases when the WordPress core REST API endpoints and fields are not suitable for a project:- A need to turn off the core endpoints,
- require authentication against a custom endpoint and not core endpoints or vice versa,
- limit or change fields returned,
- return a very specific set of fields, or
- some combination of these reasons.
function pluginname_get_post_items() { $args = array ( 'post_status' => 'publish' ); $items = array(); if ( $posts = get_posts( $args ) ) { foreach ( $posts as $post ) { $items[] = array( 'id' => $post->ID, 'title' => $post->post_title, 'author' => get_the_author_meta( 'display_name', $post->post_author ), 'content' => apply_filters( 'the_content', $post->post_content ), 'teaser' => $post->post_excerpt ); } } return $items; } function pluginname_get_page_items() { $items = array(); if ( $pages = get_pages( $args ) ) { foreach ( $pages as $page ) { $items[] = array( 'id' => $page->ID, 'title' => $page->post_title, 'author' => get_the_author_meta( 'display_name', $page->post_author ), 'content' => apply_filters( 'the_content', $page->post_content ), 'teaser' => $page->post_excerpt ); } } return $items; } function pluginname_register_api_endpoints() { register_rest_route( 'pluginname/v2', '/posts', array( 'methods' => 'GET', 'callback' => 'pluginname_get_post_items', ) ); register_rest_route( 'pluginname/v2', '/pages', array( 'methods' => 'GET', 'callback' => 'pluginname_get_page_items', ) ); } add_action( 'rest_api_init', 'pluginname_register_api_endpoints' );
Skip to footer
Comments