Function breakdown: rest_ensure_response
Tags: wordpress, rest, api, javascript
Published: 2021-08-19 16:33:58

When making your own routes with the WordPress REST API, you have to return a valid REST object. WordPress provides a couple of ways to do this, including the rest_ensure_response function. When working with REST APIs in Javascript you will see this a lot:

```jsx
fetch('rest-endpoint')
.then(response => response.json())
.then(data => // ...do something with the data here)
```

The first method on the fetch function is passed the response object, which then returns the request's body. The second method is then passed that request body as JSON.

This pattern is possible because the data from the API is returned properly. Read on to see how the `rest_ensure_response` function works and how you can use it in your own routes.

## Function definition

The WordPress code reference [describes](https://developer.wordpress.org/reference/functions/rest_ensure_response/) `rest_ensure_response` as:

> [rest_ensure_response] implements WP_REST_Response, allowing usage of set_status/header/etc without needing to double-check the object. Will also allow WP_Error to indicate error responses, so users should immediately check for this value.

The documentation states that the function takes one parameter, which can be multiple types:

```php
// you normally return the result from a rest route
return rest_ensure_response(
	// return one of:
	// WP_REST_Response
	// WP_HTTP_Response
  // WP_Error
	// ?... (mixed content)
)
```

You can return a `WP_REST_Response` class, `WP_HTTP_Response` class, `WP_Error class`, or mixed content. Let's review the function definition, see how it works, and what it returns.

*Note: mixed content just refers to different types of data: arrays, object, strings, booleans, integers, etc.*

## Return value of the function

Here is the function definition:

```php
// location: wp-includes/rest-api.php
function rest_ensure_response( $response ) {
	if ( is_wp_error( $response ) ) {
		return $response;
	}
 
	if ( $response instanceof WP_REST_Response ) {
		return $response;
	}
 
  // While WP_HTTP_Response is the base class of WP_REST_Response, it doesn't provide
  // all the required methods used in WP_REST_Server::dispatch().
	if ( $response instanceof WP_HTTP_Response ) {
		return new WP_REST_Response(
			$response->get_data(),
			$response->get_status(),
			$response->get_headers()
		);
	}

	return new WP_REST_Response( $response );
}
```

First, the function checks if the passed in value `$response` is a `WP_Error` and if so, it returns it immediately.

Next, it checks if the passed-in value is a `WP_REST_Response` instance and if so, returns it directly. Otherwise, if the value is a `WP_HTTP_Response` instance, it returns it as a `WP_REST_Response` and passes the data, status, and headers to the class.

If all else fails, the function defaults to returning the value as a `WP_REST_Response` instance. All of this is to say, it's either going to return a `WP_Error` or `WP_Rest_Response` instance.

## What you'll normally pass to the function (aka: mixed content)

In your own code, you'll probably be passing in mixed content (your data) to `rest_ensure_response`. End users are usually returning `rest_ensure_response` from a custom `register_rest_route` and passing back either an error or valid data.

Here's a simple example of `rest_ensure_response` in a custom route:

```php
function callback_for_custom_rest_route($request) {
	$data = isset($request['name']) ? $request['name'] : new WP_Error('missing_name', 'please provide your name');
	
	// if name is set, return a 200 OK with the string value passed in for name
	// if name is not set, return a 500 Internal Server Error with error information defined above
	return rest_ensure_response($data);
}
```

And that's all you need to use `rest_ensure_response`!