0

According to the JSON:API docs, you can implement the alterRoutes() method on a route subscriber to restrict access to collections. In a custom module, I have an entity type that should be POST only (no GET / PATCH / DELETE).

So I implemented a route subscriber as described:

  protected function alterRoutes(RouteCollection $collection): void {
    foreach ($collection as $name => $route) {
      $defaults = $route->getDefaults();
      /* @phpstan-ignore-next-line no empty */
      if (!empty($defaults['_is_jsonapi']) && !empty($defaults['resource_type'])) {
        $methods = $route->getMethods();

        if (str_starts_with($name, 'jsonapi.' . self::ENTITY_MACHINE_NAME) &&
          (
            in_array('GET', $methods, TRUE) ||
            in_array('PATCH', $methods, TRUE) ||
            in_array('DELETE', $methods, TRUE)
          )) {
          $collection->remove($name);
        }
      }
    }
  }

However, now when I visit www.example.com/jsonapi, I get an error:

"title": "Internal Server Error", "status": "500", "detail": "Route \u0022jsonapi.entity_type--bundle.collection\u0022 does not exist.",

Removing the in_array('GET', $methods, TRUE) check "fixes" the error, but I want to restrict access to GET.

How can I restrict access to GET for a specific entity type without breaking the /jsonapi route?

1 Answer 1

0

Thanks to bradjones1 for pointing me in the right direction on Slack.

PATCH and DELETE routes can be removed, but for GET, it is better to check access to avoid problems:

  protected function alterRoutes(RouteCollection $collection): void {
    foreach ($collection as $name => $route) {
      $defaults = $route->getDefaults();
      /* @phpstan-ignore-next-line no empty */
      if (!empty($defaults['_is_jsonapi']) && !empty($defaults['resource_type'])) {
        $methods = $route->getMethods();

        if (str_starts_with($name, 'jsonapi.' . self::ENTITY_MACHINE_NAME)) {
          if (
            in_array('PATCH', $methods, TRUE) ||
            in_array('DELETE', $methods, TRUE)
          ) {
            $collection->remove($name);
          }
          elseif (in_array('GET', $methods, TRUE)) {
            $route->setRequirement('_permission', 'administer my entity type');
          }
        }
      }
    }
  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.