I got a question from a colleague last week regarding the
context parameter in the WP REST API:
In which cases would the request be a GET request but the context be
edit? I was thinking that perhaps if an object is edited and a child is embedded, then maybe getting that child would be with
editcontext param, but probably that would be
embedinstead? Are there cases when context is
editbut it’s a GET request?
When I started learning and contributing to the REST API, I was also unclear about what the
context parameter was all about. I never saw a clear explanation for what
context was for. The REST API Handbook‘s Glossary entry on “Schema” mentions it briefly:
A “schema” is a representation of the format for WP-API’s response data. For instance, the Post schema communicates that a request to get a Post will return
author, and other fields. Our schemas also indicate the type each field is, provide a human-readable description, and show which contexts the field will be returned in.
Likewise, the Controller Classes handbook page notes that a controller’s
filter_response_by_context() method “filters the response shape based on the provided context parameter.” But what exactly is
context and how is it used?
When defining fields in the REST API, you may often throw into the schema that a field belongs to the contexts of
embed. On the surface, I can easily see why there would be confusion between a
view context being an alias for GET requests, and an
edit context being an alias for POST (and PUT) requests. Is including
context=edit in a GET request just another way to make a POST request to update a resource? Not quite.
There is actually a close relationship between POST/PUT requests and the
edit context. In fact, whenever you create or update a post, the posts controller will override whatever
context was supplied in the request to return the resource in the
edit context in the response. This leads to the purpose of the
context param: it defines a visibility scope for a given field. The
edit context is used to make the response include the fields which are needed in order to be able to edit the resource. So the
edit context is always used when doing GET requests when you want to obtain the data for editing. It’s not an alias for doing a POST/PUT request to edit a resource.
For example, the
content field includes two properties:
rendered field belongs to both the
edit contexts, whereas the
raw field only belongs to the
edit context. The
raw content will have unprocessed shortcodes, non-
wptexturize‘d text, and line breaks untouched by
wpautop. In contrast, the
rendered field is the content after all
the_content filters have been applied, just as it appears when viewed on the frontend. If you’re only showing posts in your app, all you need is the
rendered field. But when you edit a post, you need the
raw content to do so without losing data (like underlying shortcodes used). So when you request a post with the
edit context you get any fields that are defined in the schema with this context included. In the case of the
edit context, the ability to request a resource with this context is restricted to users who can actually edit the post in the first place (as there also may be sensitive information in unprocessed shortcodes).
So if the
rendered property of the
content field belongs to the
edit contexts, why doesn’t it belong to the
embed context? What is the
embed context? Note that it is not related in any way to oEmbed. The REST API allows you to define links from one resource to other resources. In the response, these links appear as the
_links object property. When you make a request to the REST API and you include
?_embed it will dispatch internal subrequests for all of the linked resources and include them in the response via an
_embedded object property. The internal subrequests will be made for the linked resources with a
context parameter of
embed. So the reason
content doesn’t belong to the
embed context is so that it is excluded from the
_embedded property, reducing the size of the overall response. You will note that
excerpt does belong to all three contexts, and so post excerpts will be included in
_embedded resources while
content is excluded from the
embed context, which makes sense if wanting to limit the overall size of the response when requesting with
I’ll share another situation though which
embed context really clicked for me. In preparing for a LoopConf 2.1 workshop, I was working on a Customize Featured Content Demo plugin. A featured item had a
related field in the REST API that contained a post ID. When requesting a given featured item with
_embed I wanted to get the featured item along with its related post in
_embedded so that I could eliminate doing a second request to obtain the related post and its properties, like
featured_media. Nevertheless, I was baffled when I looked at the post in
_embedded and it omitted
featured_media. It turns out that when the content endpoints where added, the
featured_media property was only defined as belonging to the
edit contexts. Because of this, the field was filtered out of the response. This was fixed in WordPress 4.8 via #39805, and this eliminated the need for an unsightly workaround to force a
view context on linked resources to get the field to be embedded.
All of this to say, the
context is a way to omit a predefined set of fields from being shown in a response, whether that be because they are unnecessary or unauthorized for a given application (showing posts to unauthenticated users), or they are assumed to be too verbose to warrant inclusion when a linked resource is embedded in a response.
The WordPress REST API doesn’t currently support a way to make a request that includes only individually requested fields in the response. For example to limit the response to only include the
content, you cannot make a request like:
There is a ticket open to add support for such a
fields parameter (see #38131). Nevertheless, the
context field can be used for this purpose in custom endpoints. In the REST API Handbook there is an Important Note about Changing Responses which includes an interesting paragraph:
Adding fields is not dangerous, so if you need to modify data, it’s much better to duplicate the field instead with your modified data. Removing fields is never encouraged; if you need to get back a smaller subset of data, work with contexts instead, and consider making your own context.
embed are not the only three possible contexts a field can belong to; you can make up your own. So as long as you can define a set of fields in your custom endpoints which you’ll need for a given application, you can create a new
context identifier to add to each of them; any fields that do not belong to this
context as included in the request will then be omitted in the response.
I hope this clears up what
context is in the WP REST API. I’ll probably try to incorporate some of this post into the REST API Handbook, either as a new page under Using the REST API, or perhaps as a section on the Global Parameters page.