Make WordPress Core

Opened 5 years ago

Closed 4 years ago

#47834 closed enhancement (maybelater)

Allow un-encoded output / other content types

Reported by: lkf_tanzt's profile lkf_tanzt Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.2.2
Component: REST API Keywords: has-patch reporter-feedback
Focuses: rest-api Cc:


The issue

I want to use the REST-API to provide other content types than JSON. It’s possible to set the HTTP header Content-Type to other values but the data in the the response are always json encoded so they are wrapped in "" in the result echoed. The content type is ignored here.

I followed the program flow to this line:

The $result is always json encoded, regardless of how the Content-type header was set.

So what would be a possible solution?

1. Check for content-type header

One solution would be to query the header flied Content-Type from $result (the headers are already sent in line 361) and encode the content only if the header is set to application/json or a subtype of this.

So the data are not encoded, if the content-type header is manually set for a response to something else, and those other content-types would work well. By default the content-type is set to application/json and the data is encoded, so everything would work as before.

2. Introduce filterable encode switch

We could introduce a flag $do_json_encode which would allow to skip the encoding part by adding a filter on this and returning false.

A similar thing is done in Line 380 with $served. So this could look like the following:

$do_json_encode = apply_filters( 'rest_do_json_encode', true, $result, $request, $this );
if ( $do_json_encode ){
    // the currently existing line
    $result = wp_json_encode( $result );

Since the value defaults to true the default behaviour would not change but we would introduce the option to alter this with a filter and since we provide $result and $request the user/developer can decide on his own if he want’s to encode the data or not.

Attachments (1)

47834.diff (1.7 KB) - added by lkf_tanzt 5 years ago.
I’ve prepared a diff-file for the second suggestion.

Download all attachments as: .zip

Change History (7)

#1 @kadamwhite
5 years ago

@lkf_tanzt Welcome, and thank you for the ticket! The REST API started out predominately to provide a JSON API, and we use wp-json as our base, so I'm not surprised this ended up tripping you up. :)

May I ask for an example of an alternative content type you'd like to use?

#2 @lkf_tanzt
5 years ago

Yeah, I know JSON is the standard format and I like and use it a lot. But – in theory – REST is only an architectural design and Fielding did not define a content format for the representations provided.

My use case is a quite simple event plugin. I want to provide alternative representations for the events. To do this I want to provide a route where the client can define the needed format. Examples:

  • application/json to use the event data in a JS application
  • text/calendar (the thing which caused the issue) this is used to provide iCalendar / ics files according to RFC 5545
  • application/pdf (another possible format) to allow the user to download a specially formatted PDF file of a events list

So I want to use the REST API to provide the format the client requires. I might use the Accept-Header and content negotiation to process the requested format and return it with the corresponding Content-Type-Header.

#3 @lkf_tanzt
5 years ago

Another use case would be to generate vCard output for users using content type text/vcard.

5 years ago

I’ve prepared a diff-file for the second suggestion.

#4 @lkf_tanzt
5 years ago

  • Focuses rest-api added
  • Keywords has-patch added

#5 @TimothyBlynJacobs
5 years ago

  • Keywords reporter-feedback added

@lkf_tanzt have you considered using the rest_pre_serve_request filter to provide your own serving mechanism?

#6 @TimothyBlynJacobs
4 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from new to closed

Closing as I think this is well served by the existing rest_pre_serve_request filter.

Note: See TracTickets for help on using tickets.