REST API: Explore a dedicated notes endpoint - #13043
Draft
adamsilverstein wants to merge 4 commits into
Draft
Conversation
Serve editorial notes from wp/v2/notes instead of asking clients to filter wp/v2/comments by type. The collection returns threads with their replies nested and prepared in the same context, so pagination never orphans a reply and context=edit carries content.raw all the way down, which _embed cannot do. Opens up check_post_type_supports_notes() so the subclass can reuse it.
With wp/v2/notes serving notes, the comments controller no longer needs to branch on comment type. Note permissions, the empty-note-on-resolve allowance, duplicate and flood bypass, and the post type support check all move to WP_REST_Notes_Controller, reached through three protected seams: get_allowed_comment_types(), prepare_comment_for_content_check() and determine_comment_approval(). One branch stays: check_read_permission() keeps excluding notes from the approved-comment shortcut. Notes are stored approved, so without it the comments routes would hand them to anonymous readers by ID.
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
These two exercise the rest_insert_comment wiring through HTTP, so they have to follow notes to wp/v2/notes now that the comments route no longer accepts the note type.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Exploratory Core companion to Gutenberg #81599, which answers Mamaduka's suggestion that notes deserve their own REST endpoint instead of a filtered view of
wp/v2/comments.Two halves, one per commit, so the trade is easy to read:
WP_REST_Notes_Controller, servingwp/v2/notes.WP_REST_Comments_Controller.The second half is the interesting one.
wp/v2/commentscurrently carries note rules in nine places. After this, it carries one.The endpoint
WP_REST_Notes_Controller extends WP_REST_Comments_Controller, so notes stay comment rows: the same comment meta, the samerest_prepare_commentfilter, and anything registered throughregister_rest_field( 'comment', ... )all keep applying. The schema title stayscommenton purpose.What changes is the shape of the collection.
wp/v2/comments?type=notewp/v2/notestype=note&status=allevery timepostedit_post?repliesarray on their thread_embedprepares children inview, so nocontent.rawcontent.rawall the way downX-WP-Totalcounts threads_fields=id,post,reply_countCOUNTquery for thechildrenlinkchildrenlink, replies already travel insideReplies for a whole page are fetched in one
WP_Comment_Query, so the cost does not grow with the number of threads on the page.What comes out of the comments controller
WP_REST_Comments_Controller: +54 / -129. Its tests: -440.Removed:
$is_notebranch and the forbidden-params fallback inget_items_permissions_check()edit_postre-mapping of edit context, in bothget_items_permissions_check()andget_item_permissions_check()rest_cannot_create_note, theedit_poststatus cap, and the post type support check increate_item_permissions_check()&& ! $is_notecarve-outs that let notes past the draft andcomments_opengates'note'in the create-route type allowlistwp_allow_comment()bypass for notes_wp_note_statusinjection before the content check, and the empty-note allowance inside itchildrenlink rebuild that re-addedtypeandstatusfor notescheck_post_type_supports_notes()itselfThree protected seams take their place, each with a one-line default that restores the pre-notes behaviour:
The one branch that has to stay
check_read_permission()keeps excluding notes from the "approved comment on a readable post" shortcut:Every note is stored approved -
approvedmeans resolved, not public - so without this line an anonymous request towp/v2/comments/<id>returns any note on a public post. A new endpoint does not remove notes from the comments routes' ID space, so the guard belongs where the leak is. Removing it turnedtest_get_items_type_arg_unauthenticatedred, which is a good test.Testing
tests/phpunit/tests/rest-api/rest-notes-controller.php, 36 tests / 127 assertions, covering the nine behaviours that moved plus threading, context, pagination,_fields, and the role matrix thatdata_note_get_items_permissions_data_providerused to cover.tests/phpunit/tests/comment/wpNotifyNoteMentions.phphas two tests that post and update a note over HTTP to exercise therest_insert_commentwiring. They follow notes towp/v2/notes.Both remaining failures are local environment, not this branch:
Test_oEmbed_Controller::test_proxy_with_classic_embed_providerneeds outbound HTTP, andTests_Script_Modules_WpScriptModules::test_default_script_module_files_existwants built files this worktree has not generated.tests/qunit/fixtures/wp-api-generated.jsis regenerated for the two new routes, in its own commit.Open questions
wp/v2/comments?type=noteworks today and Gutenberg trunk still uses it. This branch removes the permission handling that makes it usable, which is a decision to make deliberately, not a side effect. Keeping both alive through one release is the conservative option.edit_commentfor the single-note route.get_item_permissions_check()here usesedit_comment, which maps toedit_poston the parent. That preserves what the comments controller did, but is worth a second look.block_editor_rest_api_preload_pathswould wantwp/v2/notesalongside or instead of the comments path.If this direction holds, the Gutenberg side needs no compat shim at all - the plugin can drop its copy of the controller and consume the Core route directly.
AI Use
Claude Code did the typing here, I did the asking. I will review and test.