Make WordPress Core


Ignore:
Timestamp:
06/17/2020 03:20:02 AM (5 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Only register one block renderer route.

Every block has a different set of attributes. These attributes are specified as a JSON Schema object. Previously, every block registered its own block renderer route using its attributes for the schema. This allowed for the attributes to be validated using the built in endpoint validation rules. It had the unfortunate side effect, however, of creating a large number of nearly identical REST API routes, one for each dynamic block. Each registered route has a performance impact. As the number of server side blocks goes up, this becomes more and more of an issue.

Now, we register a single block renderer route and dynamically validate the attributes based on the selected block.

Fixes #48079.
Props gziolo, TimothyBlynJacobs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php

    r47756 r48069  
    3535     */
    3636    public function register_routes() {
    37         $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered();
    38 
    39         foreach ( $block_types as $block_type ) {
    40             if ( ! $block_type->is_dynamic() ) {
    41                 continue;
    42             }
    43 
    44             register_rest_route(
    45                 $this->namespace,
    46                 '/' . $this->rest_base . '/(?P<name>' . $block_type->name . ')',
     37        register_rest_route(
     38            $this->namespace,
     39            '/' . $this->rest_base . '/(?P<name>[a-z0-9-]+/[a-z0-9-]+)',
     40            array(
     41                'args'   => array(
     42                    'name' => array(
     43                        'description' => __( 'Unique registered name for the block.' ),
     44                        'type'        => 'string',
     45                    ),
     46                ),
    4747                array(
    48                     'args'   => array(
    49                         'name' => array(
    50                             'description' => __( 'Unique registered name for the block.' ),
    51                             'type'        => 'string',
     48                    'methods'             => array( WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ),
     49                    'callback'            => array( $this, 'get_item' ),
     50                    'permission_callback' => array( $this, 'get_item_permissions_check' ),
     51                    'args'                => array(
     52                        'context'    => $this->get_context_param( array( 'default' => 'view' ) ),
     53                        'attributes' => array(
     54                            'description'       => __( 'Attributes for the block' ),
     55                            'type'              => 'object',
     56                            'default'           => array(),
     57                            'validate_callback' => static function ( $value, $request ) {
     58                                $block = WP_Block_Type_Registry::get_instance()->get_registered( $request['name'] );
     59
     60                                if ( ! $block ) {
     61                                    // This will get rejected in ::get_item().
     62                                    return true;
     63                                }
     64
     65                                $schema = array(
     66                                    'type'                 => 'object',
     67                                    'properties'           => $block->get_attributes(),
     68                                    'additionalProperties' => false,
     69                                );
     70
     71                                return rest_validate_value_from_schema( $value, $schema );
     72                            },
     73                        ),
     74                        'post_id'    => array(
     75                            'description' => __( 'ID of the post context.' ),
     76                            'type'        => 'integer',
    5277                        ),
    5378                    ),
    54                     array(
    55                         'methods'             => array( WP_REST_Server::READABLE, WP_REST_Server::CREATABLE ),
    56                         'callback'            => array( $this, 'get_item' ),
    57                         'permission_callback' => array( $this, 'get_item_permissions_check' ),
    58                         'args'                => array(
    59                             'context'    => $this->get_context_param( array( 'default' => 'view' ) ),
    60                             'attributes' => array(
    61                                 /* translators: %s: The name of the block. */
    62                                 'description'          => sprintf( __( 'Attributes for %s block' ), $block_type->name ),
    63                                 'type'                 => 'object',
    64                                 'additionalProperties' => false,
    65                                 'properties'           => $block_type->get_attributes(),
    66                                 'default'              => array(),
    67                             ),
    68                             'post_id'    => array(
    69                                 'description' => __( 'ID of the post context.' ),
    70                                 'type'        => 'integer',
    71                             ),
    72                         ),
    73                     ),
    74                     'schema' => array( $this, 'get_public_item_schema' ),
    75                 )
    76             );
    77         }
     79                ),
     80                'schema' => array( $this, 'get_public_item_schema' ),
     81            )
     82        );
    7883    }
    7984
     
    137142            setup_postdata( $post );
    138143        }
    139         $registry = WP_Block_Type_Registry::get_instance();
    140 
    141         if ( null === $registry->get_registered( $request['name'] ) ) {
     144
     145        $registry   = WP_Block_Type_Registry::get_instance();
     146        $registered = $registry->get_registered( $request['name'] );
     147
     148        if ( null === $registered || ! $registered->is_dynamic() ) {
    142149            return new WP_Error(
    143150                'block_invalid',
Note: See TracChangeset for help on using the changeset viewer.