Interacting with the WordPress REST API


In the Using the WordPress REST API tutorial you were introduced to the WordPress REST API, as well as the Backbone.js client to interact with it.

In this session, we will look at how you can interact with the WP REST API further, by adding, updating, and deleting data.

Learning outcomes

  1. Creating Posts using the WP REST API
  2. Updating Posts using the WP REST API
  3. Deleting Posts using the WP REST API
  4. Locating additional information about the using WP REST API

Comprehension questions

  1. Are all field names from the posts table mapped exactly to WP REST API schema fields for Posts?
  2. Can you use the same endpoint to create and update Posts?
  3. How could you create a post with the WP REST API that supports blocks?
View the video transcript

Hey there, and welcome to Learn WordPress.

In this tutorial, you’re going to learn about interacting with the WordPress REST API using the Backbone.js client that ships with WordPress. This video will cover the REST API schema and then you’ll learn how to create, update and delete WordPress data.

If this is your first time working with the WordPress REST API, I recommend watching the Using the WordPress REST API tutorial. This will introduce you to using the WordPress REST API with code examples. Alternatively, download the example code from that tutorial using this URL and use this to follow this tutorial.

When working with the WordPress REST API, it’s useful to keep the endpoint reference section of the WordPress REST API documentation handy. The endpoint reference lists all the endpoints that ship with WordPress. Clicking on an individual endpoint, say posts, shows you the schema for that endpoint. The schema defines all the fields that exist for a resource. When fetching or creating data of that specific type, you will notice that many of the endpoint fields match up with fields that are available in the WordPress database related to that data type. Some, however, are slightly different. For example, the title field for the post endpoint will match up to the post_title field in the posts table. It is important to remember that these differences exist and then to use the correct field name when interacting with the API. For example, when fetching the post via API using the built in Backbone.js client, you would filter by the title field and not post_title. Similarly, when looping through a list of posts returned from the WordPress REST API, you will use the post.title.rendered property as the title field on the post is an object and the rendered property of that object is the actual content of the post title.

Let’s use the WordPress REST API to create a new post. To do so we’ll need to pass the title and content fields to a new post model. You already have a plugin that allows you to list posts in an admin page. So you can use that as your starting point. First, you will need to update the page with a form that will allow you to enter the title and content of the posts you want to create. You could do so using the following HTML.

So under the main div, we’ll add a new div and close it out. And then we will add a header and we can add form element and inside the form we’ll add another container. Then we’ll start with a label and give it a for property. Say this is post title, close the label. And then let’s add an input field type of text. And let’s give it an id. And we’ll call this wp-learn-post-title. And we’ll copy this ID in the for attribute for the label. And then we can close the div. And then let’s copy this to create another form input. This time we’ll change it from post title it’s post content and then instead of input let’s use a textarea. And define the ID, as wp-learn-post-content, give it some columns so it takes up a decent amount of space as well as rows and then it textarea needs a closing tag. And then finally, we can copy the first input to create the button to submit this and we’ll say the input type is a button doesn’t need a label. the id can be submit post, And give it a value.

Here’s what the form looks like when it’s rendered on the admin page. With the form added, the next step would be to add the JavaScript that will handle things when the button is clicked. First we need to define a variable for the button.

So we can say const. submitPostButton, document.getElementById. And I can copy the ID from the form and put in there. And then we can do a check. And here we can just say if submitPostButton. This is the same as doing the type of an undefined check that I’m doing here. If the button exists, then we’re going to do add the event listener to the button. Okay to add the click event listener, and then we will do something once the button is clicked.

Now that you have the button click event list added, you can add the code that will handle the creation of the post. To do this, it’s a good idea to create a separate function to create the post and call that function on the click event.

So the first thing you’ll need to do is create a function called submitPost. So just above this, we can say function submitPost, and then update the click event listener to call that function. So we can change this to submitPost.

This will call the submitPost function when the Submit post button is clicked. Inside the Submit post function, you’ll need to get the title and content values from the form fields.

So we can do something like const post_title, document.getElementById and then get the title field ID attributes. And we want to get the value of that input. You can do the same for the post content. wp-learn-post-content, get the value.

Next, you’ll need to create a new post model object using the Backbone js post model. You will then need to pass the values for the title and content to the model object.

So the way we do that is we go to post new wp.api models.Post. And then we pass in an object. And according to the documentation, the fields are title and content. So we can say title is the post title variable. added content is the post content that will be the contents of the fields.

Finally, you’ll need to send the request to the post route to save the data using the post model’s save method. You could also add a done callback to handle the response once the post is saved to show some kind of message.

So what we can do here is we can say post save done and then we can specify function to trigger once the response is returned. A response will be a post if it’s returned successfully. Do something with that post. Or we could just do something like say post has been saved.

If you refresh the admin page and enter a title and content, then click the Add button you should see an alert that says post saved.

So let’s try that new post new post content and let’s click and receive post saved.

If you use the plugin example from the previous tutorial, you might now want to click the Load post button to load the posts. Notice however that the post you just created doesn’t appear. This is because the default value for the status field in the post model is draft.

Let’s find the status field. And the options we have are publish future draft pending and private so probably defaults to draft.

You can change this by adding the status field to the post model object and passing in the published status.

So here, you can say status. And pass in publish.

Create the new post hit the load post button and you should see the new post in the list.

Let’s try that. So let’s refresh. Say another new post. Then you post content to add post has been saved Let’s load the posts. And there is another new post. While we’re here, let’s check posts list will see there’s a new post that was created in draft. And there’s another new post.

You can also update posts in the same way as creating them. The main difference is that you need to pass the post ID to the post model so that it knows which posts to update.

First, in the PHP file for the plugin, you’ll need to add a new form to manage handling updates. For this, you can simply copy the code that you used to create posts, but update the relevant form field IDs and add a field for the post id and finally change the button text update.

So let’s take this entire add posts section. And we will just copy and paste it below. And let’s start renaming so we’ll say update post. We’ll leave the post title but we’ll make the ID wp-learn-update-post. Content will stay the same but we’ll change the for attribute and the ID attribute to wp-learn-update-post. And change the button to wp-learn-update-post. Change the value update. And finally we’ll create a new form field just above the title for the ID. So the label will be wp-learn-update-post-id post may be wp-update-post id.

That’s all that’s needed on the PHP side. So you can switch over to the JavaScript file. The next step is to add a function to handle the post update. This will be very similar to the current submit post function. But we’ll need to be updated with the various element IDs and pass the post ID to the post model. You can also leave out the status in this example.

So let’s take submit post and pop down the bottom here. And let’s call this update post. And it’ll be wp-learn-update-post-title and wp-learn-update-post-content, and then we will need a field for the ID. So we can copy post title and create a new one called post id and get the correct ID attributes. And then in the object that’s passed to the post model, we need to specify the ID and we can remove the status because we’re not going to update that now. And let’s just change the message to post updated and there’s the function to handle the post.

Finally, you need to add the click event handler for the update button and call the update post function when it’s clicked.

So let’s take the Submit post one and changes update post. updatePostButton document.getElementById wp-learn-update-post, updatePostButton addEventListener. And let’s call the updatePost function.

The last thing we’ll need to do is update the load post functionality to include the ID in the list when you load posts.

So right at the top here, we will add in the old posts which we will add the ID to the list of fields to be fetched. And then then we will include the post ID to the output in the text area, and we will just separated with a comma.

Go ahead and test this out in your browser.

Refresh the admin page. Load the posts.

Then enter an ID updated post title and content in the update form and click update.

So let’s take it 175. And we’ll say updated post and updated post content. And let’s click Update. And the post has been updated.

Once the post has been updated, reload the list of posts to confirm the content has been updated.

There, clear it and load 175 has been updated.

You can also check the posts in the WordPress admin to confirm the changes.

So if we refresh the Post List, there is the update post. And there is the updated post content.

Notice how in the Block Editor the post content is displayed in a classic block. This is because in this simple example, you’re not passing block markup to the post model. You can pass block markup to the post model for example by wrapping the content in a wp-paragraph block tag. But this is beyond the scope of this tutorial.

Just to show you what this would look like. Let’s create a new block post and pass in some valid block markup. Using wp-paragraph tags, say new post content. And if we add that the post is saved. And if we look at the newest post, the content renders as a paragraph block.

Now that you know how to create and update a post, let’s take a look at how to delete a post. First, you’ll need to add another form to the admin page that will allow you to enter the ID of the post you want to delete as well as a button to trigger the Delete.

So in the PHP, we can just grab, update and use it for the Delete. And we just need the ID. We don’t need title and content. I’ll say wp-learn-post-id, wp-learn-post-id. And then we’ll say delete, post and delete, delete.

Then as before set up the click event listener for the button as well as the function to handle the deletion.

So again, here we can just grab for example the update post. Post ID and say delete post and it was the wp-learn-post-id field and do the same creating a button variables so delete post button, delete post and click event and call delete post.

Now that you have the button click event listener added, you can add the code that will handle the deletion. The first thing you’ll need to do is get the value from the form field which we have already. Then you’ll need to create a new post model object and pass in the post ID.

So it will be const post new wp.api.modelsPost and passing the object and that’s the ID and then post id.

Finally, you’ll need to delete the post from the database using the post models destroy method. As before you can also add the done callback to handle the response once the post is deleted.

So post destroy then back to handle a response Once the post has been deleted. And we’ll just alert a message to say post deleted.

Now refresh the page and load the posts.

Grab a post id pop that into the Delete form and hit Delete The system says the post has deleted so let’s load the posts and make sure that 178 is no longer there. 178 has been deleted, let’s verify this by looking at all the posts. And if we look in trash, there is the new blog post, which is ID 178.

For more information in using and interacting with the WordPress REST API, as well as how to extend it. Check out the WordPress REST API handbook developer.wordpress.org.

Happy coding

Introduction

Hey there, and welcome to Learn WordPress.

In this tutorial, you’re going to learn about interacting with the WordPress REST API, using the Backbone.js client that ships with WordPress.

This video will cover the WP REST API Schema, and then you’ll learn how to create, update, and delete WordPress data.

If this is your first time working with the WP REST API, I recommend watching the Using the WordPress REST API tutorial. This will introduce you to using the WP REST API, with code examples.

Alternatively, download the example code from that tutorial from this URL, and use it to follow this tutorial.

WP REST API Schema

When working with the REST API, it’s useful to keep the Endpoint Reference section of the WP REST API documentation handy. The Endpoint Reference lists all endpoints that ship with WordPress core.

Clicking on an individual endpoint, say Posts, will show you the schema for that endpoint. The schema defines all the fields that exist for a resource when fetching or creating data of that specific type.

You will notice that many of the endpoint fields match up with the fields that are available in the WordPress database table related to that data type. Some however, are slightly different. For example, the title field for the Post endpoint will match up to the post_title field in the posts table. It is important to remember that these differences exist, and to use the correct field name when interacting with the API.

For example, when fetching the posts via the API using the built-in Backbone.js client, you would filter by the title field, and not post_title:

allPosts.fetch(
    { data: { "_fields": "title" } }
)

Similarly, when looping through a list of posts returned from the WP REST PAI, you would use post.title.rendered, as the title field on the post is an object, and the rendered property of that object is the actual content of the post’s title.

done( function ( posts ) {
    const textarea = document.getElementById( 'wp-learn-posts' );
    posts.forEach( function ( post ) {
        textarea.value += post.title.rendered + '\n'
    } );
} );

Creating a Post

Let’s use the WP REST API it to create a new post. To do so, we’ll need to pass the title and content fields to a new post model.

You already have a plugin that allows you to list posts, so you can use that as a starting point.

First, you’ll need to update the page with a form that will allow you to enter the title and content of the post you want to create. You can use the following HTML to create the form, and add it to the admin page callback:

<div style="width:50%;">
    <h2>Add Post</h2>
    <form>
        <div>
            <label for="wp-learn-post-title">Post Title</label>
            <input type="text" id="wp-learn-post-title" placeholder="Title">
        </div>
        <div>
            <label for="wp-learn-post-content">Post Content</label>
            <textarea id="wp-learn-post-content" cols="100" rows="10"></textarea>
        </div>
        <div>
            <input type="button" id="wp-learn-submit-post" value="Add">
        </div>
    </form>
</div>

This html code adds a new form to the admin page, that:
– has a title of “Add Post”
– opens a new form element
– includes a text input for the title with the id attribute of wp-learn-post-title
– includes a textarea for the content with the id attribute of wp-learn-post-content
– has a button to submit the form with the id attribute of wp-learn-submit-post

Here is what the form looks like when it’s rendered in the admin page:

With the form added, the next step would be to add the JavaScript that will handle things when the button is clicked:

const submitPostButton = document.getElementById( 'wp-learn-submit-post' );
if ( submitPostButton ) {
    submitPostButton.addEventListener( 'click', function () {
        // create post code
    } );
}

Now that you have the button click event listener added, you can add the code that will handle the creation of the post. To do this, it’s a good idea to create a separate function to create the post, and call that function on the click event.

The first thing you’ll need to do is create the submitPost function:

function submitPost() {
    // create post code
}

Then update the click event listener to call that function:

submitPostButton.addEventListener( 'click', submitPost );

Inside the submitPost function, you’ll need to get the title and content values from the form fields:

const title = document.getElementById( 'wp-learn-post-title' ).value;
const content = document.getElementById( 'wp-learn-post-content' ).value;

Next, you’ll need to create a new post model object, using the Backbone.js Post model. You will then need to pass the values for the title and content to the model object:

const post = new wp.api.models.Post( {
    title: title,
    content: content,
} );

Finally, you’ll need to send the request to the Posts route to save the data, using the Posts model’s save method. You can also add a done callback to handle the response once the post is saved:

post.save().done( function ( post ) {
    alert( 'Post saved!' );
} );

If you refresh the admin page, and enter a title and content, and click the Add button, you should see an alert that says “Post saved!”.

If you used the plugin example from the previous tutorial, you might now want to click the loadPosts button to load the posts. Notice however that the post doesn’t appear. This is because the default value for the status field on the Post model is draft. You can change this by adding the status field to the post model object:

const post = new wp.api.models.Post( {
    title: title,
    content: content,
    status: 'publish',
} );

Create the new post, hit the loadPosts button, and you should see the new post in the list.

Updating Posts

You can also update Posts in the same way as creating posts. The main difference is that you also need to pass the post id to the Post model, so that it knows which post to update.

First, in the PHP file for the plugin, you’ll need to add a form to manage handling updates. For this, you can simply copy the code that’s used to create posts, but update the form field ids, add a field for the Post’s id, and change the button text to Update:

<div style="width:50%;">
    <h2>Update Post</h2>
    <form>
        <div>
            <label for="wp-learn-update-post-id">Post ID</label>
            <input type="text" id="wp-learn-update-post-id" placeholder="ID">
        </div>
        <div>
            <div>
                <label for="wp-learn-update-post-title">Post Title</label>
                <input type="text" id="wp-learn-update-post-title" placeholder="Title">
            </div>
            <div>
                <label for="wp-learn-update-post-content">Post Content</label>
                <textarea id="wp-learn-update-post-content" cols="100" rows="10"></textarea>
            </div>
            <div>
                <input type="button" id="wp-learn-update-post" value="Update">
            </div>
    </form>
</div>

That’s all that’s needed in the PHP side, so you can switch over to the JavaScript file. The next step is to add a function to handle the Post update. This will be very similar to the current submitPost function, but will need to update the various element ids, and pass the post id to the Post model. You can also leave out the status for this example.

function updatePost() {
    const id = document.getElementById( 'wp-learn-update-post-id' ).value;
    const title = document.getElementById( 'wp-learn-update-post-title' ).value;
    const content = document.getElementById( 'wp-learn-update-post-content' ).value;
    const post = new wp.api.models.Post( {
        id: id,
        title: title,
        content: content,
    } );
    post.save().done( function ( post ) {
        alert( 'Post Updated!' );
    } );
}

Finally, you need to add a click handler to the Update button, and call the updatePost function when it’s clicked:

const updatePostButton = document.getElementById( 'wp-learn-update-post' );
if ( updatePostButton ) {
    updatePostButton.addEventListener( 'click', updatePost );
}

The last thing you’ll need to do is update loadPosts functionality to include the id in the list:

allPosts.fetch(                                                                                       
    { data: { "_fields": "id, title" } }                                                              
).done( function ( posts ) {                                                                          
    const textarea = document.getElementById( 'wp-learn-posts' );                                     
    posts.forEach( function ( post ) {                                                                
        textarea.value += post.id  + ', ' +  post.title.rendered + '\n'                               
    } );                                                                                              
} );    

Go ahead and test this out in your browser, refresh the admin page and load the posts.

Then enter an id, updated post title and content, and click Update.

Once the post has been updated, reload the list of posts, to confirm the content has been updated. You can also check the Post in the WordPress admin to confirm the changes.

Notice how the post content is displayed as a Classic Block. This is because in this simple example we’re not passing block markup to the Post model. You can pass block markup to the Post model, for example by wrapping the content in a wp:paragraph block tags, but this is beyond the scope of this tutorial.

<!-- wp:paragraph -->
<p>Updated Post Content</p>
<!-- /wp:paragraph -->

Deleting a Post

Now that you know how to create and update a post, let’s take a look at how to delete a post.

First, you’ll need to add a form to the admin page callback that will allow you to enter the ID of the post you want to delete, as well as a button to trigger the delete:

<div style="width:50%;">
    <h2>Delete Post</h2>
    <form>
        <div>
            <label for="wp-learn-post-id">Post ID</label>
            <input type="text" id="wp-learn-post-id" placeholder="ID">
        </div>
        <div>
            <input type="button" id="wp-learn-delete-post" value="Delete">
        </div>
    </form>
</div>

Then, as before, set up the click event listener for the button, as well as the function to handle the deletion:

const deletePostButton = document.getElementById( 'wp-learn-delete-post' );
if ( typeof ( deletePostButton ) != 'undefined' && deletePostButton != null ) {
    deletePostButton.addEventListener( 'click', deletePost );
}
function deletePost() {
    // code to delete posts 
}

Now that you have the button click event listener added, you can add the code that will handle the deletion of the post. The first thing you’ll need to do is get the value from the form field:

const id = document.getElementById( 'wp-learn-post-id' ).value;

Next, you’ll need to create a new post model object, using the Backbone.js Post model:

const post = new wp.api.models.Post( { id: id } );

Finally, you’ll need to delete the post from the database, using the Posts model’s destroy method. You can also add the done callback to handle the response once the post is deleted:

post.destroy().done( function ( post ) {
    alert( 'Post deleted!' );
} );

Now, refresh the page, and load the posts

Then, grab one of the post ids, paste it in the ID field for the delete post form, and hit the delete button.

The post should be deleted, and you can use the load posts button to confirm the post has been deleted, or check the list of posts in the WordPress admin.

For more information on using and interacting with the WP REST API, as well as how to extend it, check out the WP REST API Handbook at developer.wordpress.org.

Happy coding

Workshop Details


Presenters

Jonathan Bossenger
@psykro

WordPress Code Instructor at Automattic, full-time sponsored member of the training team creating educational content for developers on Learn WordPress. Husband and father of two energetic boys.