Index: wp-includes/rest-api/class-wp-rest-server.php
===================================================================
--- wp-includes/rest-api/class-wp-rest-server.php	(revision 47175)
+++ wp-includes/rest-api/class-wp-rest-server.php	(working copy)
@@ -561,6 +561,7 @@
 			return $data;
 		}
 
+		$requested_fields = $this->get_requested_embedded_fields();
 		$embedded = array();
 
 		foreach ( $data['_links'] as $rel => $links ) {
@@ -574,6 +575,20 @@
 					continue;
 				}
 
+				// Ignore relationships that weren't requested.
+				if ( $requested_fields && ! array_key_exists( $rel, $requested_fields ) ) {
+					continue;
+				}
+
+				// Add the requested fields to the soon-to-be-dispatched request.
+				if ( array_key_exists( $rel, $requested_fields ) ) {
+					$item['href'] = add_query_arg(
+						'_fields',
+						implode( ',', $requested_fields[ $rel ] ),
+						$item['href']
+					);
+				}
+
 				// Run through our internal routing and serve.
 				$request = WP_REST_Request::from_url( $item['href'] );
 				if ( ! $request ) {
@@ -610,6 +625,51 @@
 	}
 
 	/**
+	 * todo
+	 *
+	 * @return array
+	 */
+	protected function get_requested_embedded_fields() {
+		$raw_fields = isset( $_GET['_fields'] ) ? wp_parse_list( $_GET['_fields'] ) : '';
+		// todo sanitize
+
+		// handle back-compat?
+			// some people may already using _fields and _embed in order to limit the main response, but might expect full embedded results to stay
+
+		// add tests
+			// success
+			// nested
+				// _embedded.author.avatar_urls.24 doesn't work yet
+			// handle case where nothing was requested
+			// where something was requested but doesn't exist -probably nothing to do here, just test
+			// what else?
+
+		if ( empty( $raw_fields ) ) {
+			return array();
+		}
+
+		foreach ( $raw_fields as $raw_field ) {
+			if ( '_embedded.' !== substr( $raw_field, 0, 10 ) ) {
+				continue;
+			}
+
+			$rel_with_nested    = str_replace( '_embedded.', '', $raw_field );
+			$delimiter_position = strpos( $rel_with_nested, '.' );
+			$rel                = substr( $rel_with_nested, 0, $delimiter_position );
+
+			if ( false !== $delimiter_position ) {
+				$nested_field = substr( $rel_with_nested, $delimiter_position + 1 );
+
+				$requested_fields[ $rel ][] = $nested_field;
+			} else {
+				$requested_fields[ $rel ] = array();
+			}
+		}
+
+		return $requested_fields;
+	}
+
+	/**
 	 * Wraps the response in an envelope.
 	 *
 	 * The enveloping technique is used to work around browser/client
