Updating Existing API Resources: REST API, PUT, and PATCH
Learn to update existing WordPress resources using REST API PUT and PATCH methods. Master ID-based routing and secure data modification for your plugins.
Previously in this course, we explored creating POST endpoints for data submission to add new entries to our Knowledge Base. Now, we expand our API's capabilities by implementing the logic required to modify existing resources.
In a RESTful architecture, the ability to update data is just as critical as the ability to create it. We achieve this by using the PUT and PATCH HTTP methods, which allow us to target specific resources via their unique identifiers.
Understanding PUT vs. PATCH
While both methods update resources, they serve different semantic purposes:
- PUT: Represents a complete replacement of the resource. If you send a
PUTrequest, you are expected to provide the full set of required data. If a field is missing, the API should ideally treat it as an empty value or an error. - PATCH: Represents a partial update. You only send the fields that need to be changed, and the server updates only those specific attributes.
When building WordPress plugins, we often use WP_REST_Request to handle these. While WordPress doesn't strictly enforce the structural difference between PUT and PATCH in the database layer, following these conventions makes your API predictable for other developers.
Implementing ID-based Routing
To update a resource, our endpoint must accept an ID parameter. We define this in our register_rest_route call by including a capture group in the route path.
PHPregister_rest_route( 'kb/v1', '/entry/(?P<id>\d+)', [ 'methods' => [ 'PUT', 'PATCH' ], 'callback' => 'kb_update_entry_handler', 'permission_callback' => 'kb_check_permissions', 'args' => [ 'id' => [ 'validate_callback' => 'is_numeric', ], ], ] );
By using (?P<id>\d+), we ensure the id is passed directly into our callback function as part of the $request object.
Worked Example: Updating an Entry
In our handler, we need to retrieve the post, verify it exists, and then perform the update using wp_update_post. We must also perform validating and sanitizing API arguments before committing changes to the database.
PHPfunction kb_update_entry_handler( WP_REST_Request $request ) { $id = $request->get_param( 'id' ); $post = get_post( $id ); if ( ! $post || $post->post_type !== 'knowledge_base' ) { return new WP_Error( 'not_found', 'Entry not found', [ 'status' => 404 ] ); } $args = [ 'ID' => $id, 'post_title' => sanitize_text_field( $request->get_param( 'title' ) ), 'post_content' => wp_kses_post( $request->get_param( 'content' ) ), ]; #6A9955">// Remove null values for partial updates(PATCH behavior) $args = array_filter( $args, function( $value ) { return ! is_null( $value ); } ); $result = wp_update_post( $args, true ); if ( is_wp_error( $result ) ) { return $result; } return new WP_REST_Response( [ 'success' => true, 'id' => $result ], 200 ); }
Hands-on Exercise
- Modify your existing
kb_update_entry_handlerto support bothPUTandPATCH. - Add a check to ensure that if a user attempts to update a post, they have the
edit_postcapability for that specific ID. - Test your endpoint using Postman or cURL by sending a
PATCHrequest to/wp-json/kb/v1/entry/{id}with only thetitlefield in the body. Ensure the content remains unchanged.
Common Pitfalls
- Ignoring Permission Callbacks: Never assume that because a user is logged in, they can edit every post. Always use
current_user_can( 'edit_post', $id )inside your handler, even if you have a global permission callback defined. - Overwriting Data: When implementing
PATCH, avoid updating fields that weren't provided in the request. Usingarray_filteror checking$request->has_param()is essential to avoid overwriting existing data withnullor empty strings. - Race Conditions: If two users edit the same resource simultaneously, the last one to save wins. For high-concurrency plugins, consider implementing ETag headers or "last modified" timestamps to prevent data loss.
Recap
Updating resources requires precise ID-based routing and careful handling of the request body. By distinguishing between the intent of PUT (full replacement) and PATCH (partial update), you create a robust API. Always sanitize your inputs and verify user permissions against specific post objects to keep your Knowledge Base secure.
Up next: We will begin managing the client-side experience by handling asynchronous state in React.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs โ the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard โ by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.