.../config/optional/rest.resource.entity__node.yml | 1 + core/modules/rest/config/schema/rest.schema.yml | 16 ++++++++++--- core/modules/rest/rest.install | 4 +++- .../modules/rest/src/Entity/ConfigDependencies.php | 26 ++++++++++++++++++++++ core/modules/rest/src/Tests/RESTTestBase.php | 2 +- core/modules/rest/src/Tests/ResourceTest.php | 4 ++-- 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/core/modules/rest/config/optional/rest.resource.entity__node.yml b/core/modules/rest/config/optional/rest.resource.entity__node.yml index 4561a2f..8125fa3 100644 --- a/core/modules/rest/config/optional/rest.resource.entity__node.yml +++ b/core/modules/rest/config/optional/rest.resource.entity__node.yml @@ -1,6 +1,7 @@ id: entity__node plugin_id: 'entity:node' configuration: + granularity: method GET: supported_formats: - hal_json diff --git a/core/modules/rest/config/schema/rest.schema.yml b/core/modules/rest/config/schema/rest.schema.yml index 215f9b9..a7cf07d 100644 --- a/core/modules/rest/config/schema/rest.schema.yml +++ b/core/modules/rest/config/schema/rest.schema.yml @@ -7,8 +7,18 @@ rest.settings: type: string label: 'Domain of the relation' -rest_resource: - type: mapping +# The base type for REST resource configuration. +rest_resource_base: + type: mapping + mapping: + granularity: + type: string + label: 'Resource configuration granularity' + +# Method-level granularity of REST resource configuration. +# @todo Add resource-level granularity in https://www.drupal.org/node/2721595. +rest_resource.method: + type: rest_resource_base mapping: GET: type: rest_request @@ -50,5 +60,5 @@ rest.resource.*: type: string label: 'REST resource plugin id' configuration: - type: rest_resource + type: rest_resource.[granularity] label: 'REST resource configuration' diff --git a/core/modules/rest/rest.install b/core/modules/rest/rest.install index 4a153f9..e0597f9 100644 --- a/core/modules/rest/rest.install +++ b/core/modules/rest/rest.install @@ -26,13 +26,15 @@ function rest_requirements($phase) { /** * Install the REST config entity type and convert old settings-based config. + * + * @todo Automatically upgrade those REST resource config entities that have the same formats/auth mechanisms for all methods to "granular: resource" in https://www.drupal.org/node/2721595. */ function rest_update_8100() { \Drupal::entityDefinitionUpdateManager()->installEntityType(\Drupal::entityTypeManager()->getDefinition('rest_resource_config')); foreach (\Drupal::config('rest.settings')->get('resources') as $key => $resource) { $resource = RestResourceConfig::create([ 'id' => str_replace(':', '__', $key), - 'configuration' => $resource, + 'configuration' => ['granularity' => 'method'] + $resource, ]); $resource->save(); } diff --git a/core/modules/rest/src/Entity/ConfigDependencies.php b/core/modules/rest/src/Entity/ConfigDependencies.php index b277296..ee9a2e5 100644 --- a/core/modules/rest/src/Entity/ConfigDependencies.php +++ b/core/modules/rest/src/Entity/ConfigDependencies.php @@ -49,10 +49,36 @@ public function __construct(array $available_rest_formats, array $available_rest * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies() */ public function calculateDependencies(RestResourceConfigInterface $rest_config) { + $granularity = $rest_config->get('configuration')['granularity']; + if ($granularity === 'method') { + return $this->calculateDependenciesForMethodGranularity($rest_config); + } + else { + // @todo Add resource-level granularity support in https://www.drupal.org/node/2721595. + } + } + + /** + * Calculates dependencies of a specific rest resource configuration. + * + * @param \Drupal\rest\RestResourceConfigInterface $rest_config + * The rest configuration. + * + * @return string[][] + * Dependencies keyed by dependency type. + * + * @see \Drupal\Core\Config\Entity\ConfigEntityInterface::calculateDependencies() + */ + protected function calculateDependenciesForMethodGranularity(RestResourceConfigInterface $rest_config) { // The dependency lists for authentication providers and formats // generated on container build. $dependencies = []; foreach (array_keys($rest_config->get('configuration')) as $request_method) { + // 'granularity' is not a request method + if ($request_method === 'granularity') { + continue; + } + // Add dependencies based on the supported authentication providers. foreach ($rest_config->getSupportedAuthenticationProviders($request_method) as $auth) { if (isset($this->availableRestAuthentications[$auth])) { diff --git a/core/modules/rest/src/Tests/RESTTestBase.php b/core/modules/rest/src/Tests/RESTTestBase.php index 9306de2..8969a6a 100644 --- a/core/modules/rest/src/Tests/RESTTestBase.php +++ b/core/modules/rest/src/Tests/RESTTestBase.php @@ -272,7 +272,7 @@ protected function enableService($resource_type, $method = 'GET', $format = NULL // get entity by id /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */ $resource_config = $this->resourceConfigStorage->load($resource_config_id); - $resource_config = $resource_config ?: $this->resourceConfigStorage->create(['id' => $resource_config_id]); + $resource_config = $resource_config ?: $this->resourceConfigStorage->create(['id' => $resource_config_id, 'configuration' => ['granularity' => 'method']]); if (is_array($format)) { for ($i = 0; $i < count($format); $i++) { diff --git a/core/modules/rest/src/Tests/ResourceTest.php b/core/modules/rest/src/Tests/ResourceTest.php index a171d7f..1ab3970 100644 --- a/core/modules/rest/src/Tests/ResourceTest.php +++ b/core/modules/rest/src/Tests/ResourceTest.php @@ -45,7 +45,7 @@ protected function setUp() { */ public function testFormats() { /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */ - $resource_config = $this->resourceConfigStorage->create(['id' => 'entity__entity_test']); + $resource_config = $this->resourceConfigStorage->create(['id' => 'entity__entity_test', 'configuration' => ['granularity' => 'method']]); // Attempt to enable the resource. $resource_config ->addSupportedAuthenticationProvider('GET', 'basic_auth') @@ -68,7 +68,7 @@ public function testFormats() { */ public function testAuthentication() { /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */ - $resource_config = $this->resourceConfigStorage->create(['id' => 'entity__entity_test']); + $resource_config = $this->resourceConfigStorage->create(['id' => 'entity__entity_test', 'configuration' => ['granularity' => 'method']]); // Attempt to enable the resource. $resource_config ->addSupportedFormat('GET', 'hal_json')