Opened 4 years ago
Last modified 3 months ago
#54484 assigned defect (bug)
REST API returns (empty) array for Meta but Schema has type object
Reported by: |
|
Owned by: |
|
---|---|---|---|
Milestone: | 6.9 | Priority: | normal |
Severity: | normal | Version: | 4.7 |
Component: | REST API | Keywords: | has-patch |
Focuses: | Cc: |
Description
When checking http://localhost/wp-json/wp/v2/posts (fresh setup) the meta field is an empty array:
[{"id":1,...,"meta":[],...}]
But the schema (localhost/wp-json/wp/v2/posts?_method=OPTIONS) has type definition object:
{ ..., "schema":{ "$schema":"http:\/\/json-schema.org\/draft-04\/schema#", "title":"post", "type":"object", "properties":{ ..., "meta":{ "description":"Metafelder.", "type":"object", "context":[ "view", "edit" ], "properties":[ ] }, ... }, ... }, ... }
Either the schema is wrong and should be array or REST API should not return an empty array
I'm downloading the schema from my local WordPress instance in order to create POJOs and using those with Springs WebClient which results in the following error:
Error: JSON decoding error: Cannot deserialize value of type `com.acme.api.wp.Meta` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.acme.api.wp.Meta` from Array value (token `JsonToken.START_ARRAY`) at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.acme.api.wp.Posts["meta"])
Manually changing type from object to array fixes it. But I'm not sure if the schema is wrong or the REST API is returning invalid data.
Change History (4)
#2
@
4 years ago
- Summary changed from REST API returns (empty) array for Post Meta but Schema has type object to REST API returns (empty) array for Meta but Schema has type object
#3
@
3 months ago
- Milestone changed from Awaiting Review to 6.9
- Owner set to flixos90
- Status changed from new to assigned
- Version changed from 5.8.2 to 4.7
I realize I am finding this ticket very late, but thank you for raising this @dtrunk90!
The type of meta
is object
, so that's all correct. But the problem is that an empty array in PHP becomes []
when JSON-encoded, it doesn't make a difference whether it's supposed to be a regular (indexed) array ([]
in JS/JSON) or an associative array ({}
in JS/JSON). So this is certainly a bug.
The workaround is to either use JSON_FORCE_OBJECT
when JSON-encoding the data, or transform the empty array to an empty object (e.g. via new stdClass()
).
I think the latter fix is what's needed here, since it has to be determined for each specific possibly empty array individually, based on the JSON schema of the data. I'm going to take a closer look at this.
This has been a bug ever since the REST API was introduced, therefore setting the version to 4.7
.
This ticket was mentioned in PR #8712 on WordPress/wordpress-develop by @sukhendu2002.
3 months ago
#4
- Keywords has-patch added
This PR addresses an inconsistency in the WordPress REST API where an empty meta field was returned as []
(empty array), while the API schema specifies it should be {}
(empty object). This primarily affects clients consuming the API in the default 'view'
context.
The WP_REST_Posts_Controller::prepare_item_for_response()
method now checks the request context. It only converts an empty meta array ([]
) to an empty object ({}
) if $request['context'] === 'view'
. For the 'edit'
context, it remains []
.
The WP_REST_Blocks_Controller::filter_response_by_context()
method has been updated to safely access the wp_pattern_sync_status
key/property regardless of whether $data['meta']
is an array or an object.
Trac ticket:
Still the case for current dev version (5.9)
And it's the same for menu, menu-items and I guess many others which contains a meta "object".