diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 0b2da7f..1c9df71 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -140,36 +140,11 @@ function rest_api_loaded() {
 	 */
 	define( 'REST_REQUEST', true );
 
-	/** @var WP_REST_Server $wp_rest_server */
-	global $wp_rest_server;
-
-	/**
-	 * Filter the REST Server Class.
-	 *
-	 * This filter allows you to adjust the server class used by the API, using a
-	 * different class to handle requests.
-	 *
-	 * @since 4.4.0
-	 *
-	 * @param string $class_name The name of the server class. Default 'WP_REST_Server'.
-	 */
-	$wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' );
-	$wp_rest_server = new $wp_rest_server_class;
-
-	/**
-	 * Fires when preparing to serve an API request.
-	 *
-	 * Endpoint objects should be created and register their hooks on this action rather
-	 * than another action to ensure they're only loaded when needed.
-	 *
-	 * @since 4.4.0
-	 *
-	 * @param WP_REST_Server $wp_rest_server Server object.
-	 */
-	do_action( 'rest_api_init', $wp_rest_server );
+	// Initialize the server.
+	$server = rest_get_server();
 
 	// Fire off the request.
-	$wp_rest_server->serve_request( $GLOBALS['wp']->query_vars['rest_route'] );
+	$server->serve_request( $GLOBALS['wp']->query_vars['rest_route'] );
 
 	// We're done.
 	die();
@@ -273,9 +248,53 @@ function rest_url( $path = '', $scheme = 'json' ) {
  * @return WP_REST_Response REST response.
  */
 function rest_do_request( $request ) {
-	global $wp_rest_server;
 	$request = rest_ensure_request( $request );
-	return $wp_rest_server->dispatch( $request );
+	return rest_get_server()->dispatch( $request );
+}
+
+/**
+ * Get the current REST server instance.
+ *
+ * Instantiates a new instance if none exists already.
+ *
+ * @since 4.5.0
+ *
+ * @global WP_REST_Server $wp_rest_server REST server instance.
+ *
+ * @return  WP_REST_Server REST server instance.
+ */
+function rest_get_server() {
+	/* @var WP_REST_Server $wp_rest_server */
+	global $wp_rest_server;
+
+	if ( empty( $wp_rest_server ) ) {
+		/**
+		 * Filter the REST Server Class.
+		 *
+		 * This filter allows you to adjust the server class used by the API, using a
+		 * different class to handle requests.
+		 *
+		 * @since 4.5.0
+		 *
+		 * @param string $class_name The name of the server class. Default 'WP_REST_Server'.
+		 */
+		$wp_rest_server_class = apply_filters( 'wp_rest_server_class', 'WP_REST_Server' );
+		$wp_rest_server = new $wp_rest_server_class;
+
+		/**
+		 * Fires when preparing to serve an API request.
+		 *
+		 * Endpoint objects should be created and register their hooks on this action rather
+		 * than another action to ensure they're only loaded when needed.
+		 *
+		 * @since 4.5.0
+		 *
+		 * @param WP_REST_Server $wp_rest_server Server object.
+		 */
+		do_action( 'rest_api_init', $wp_rest_server );
+	}
+
+	return $wp_rest_server;
 }
 
 /**
diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php
index 33e3f24..0c148c2 100644
--- a/tests/phpunit/tests/rest-api/rest-server.php
+++ b/tests/phpunit/tests/rest-api/rest-server.php
@@ -15,9 +15,11 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
 
 		/** @var WP_REST_Server $wp_rest_server */
 		global $wp_rest_server;
-		$this->server = $wp_rest_server = new Spy_REST_Server();
 
-		do_action( 'rest_api_init', $this->server );
+		unset( $wp_rest_server );
+		add_filter( 'wp_rest_server_class', array( $this, 'filter_wp_rest_server_class' ) );
+		$this->server = rest_get_server();
+		remove_filter( 'wp_rest_server_class', array( $this, 'filter_wp_rest_server_class' ) );
 	}
 
 	public function test_envelope() {
@@ -645,4 +647,8 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
 			$this->assertFalse( isset( $headers[ $header ] ) && $headers[ $header ] === $value, sprintf( 'Header %s is set to nocache.', $header ) );
 		}
 	}
+
+	public function filter_wp_rest_server_class() {
+		return 'Spy_REST_Server';
+	}
 }
