8

With GET method we can do something like this

example.user
  path: 'example/{user}'
  defaults: 
    _controller: '\Drupal\example\Controller\ExampleController::content' 
  requirements: 
    _permission: 'access content' 
    user: ^[a-zA-Z0-9_]+

so it sets user param as required and also limits its format.

But I'd like to do something similar with POST method. Tried this, but not working:

example.user
  path: 'example'
  methods:  [POST]
  defaults: 
    _controller: '\Drupal\example\Controller\ExampleController::content' 
  requirements: 
    _permission: 'access content' 
    user: ^[a-zA-Z0-9_]+

EDIT:

Sure I can set some logic inside controller like this, but it doesn't feel right:

public function store(Request $request) {
   $params = json_decode($request->getContent(), TRUE);
   //I'm trying to avoid using these conditions inside controller methods
   if(empty($params['user'])){
      //return error response
   }else{
     if (!preg_match('/^[a-zA-Z0-9_]+/', $params['user'])) {
       //return error response
     }
   }
  //return success response
}

So what's drupal way to do it?

2
  • 1
    The Drupal way to do a restful interface (noticed "rest" tag in question) is to use RestResource (see EntityResource::post). In other words, use Serializer component to denormalize. If this isn't rest, then maybe we should remove the rest tag?
    – mradcliffe
    Aug 29, 2016 at 15:24
  • @mradcliffe Yeah thanks for heads up about the tag. Now when I read it few times again I think it doesn't fit.
    – Trupal
    Aug 29, 2016 at 15:51

3 Answers 3

1

Drupal routing system only validates parameters passed via URL (or GET) using route placeholder. Read more here

For a POST method, you can validate parameters on your controller function or if you don't want to pass the request to your controller prior to validating it, technically you can validate the parameters by defining a custom function under the requirement.

  example.user
  path: '/example/name'
  defaults:
    _controller: '\Drupal\example\Controller\ExampleController::content'
  requirements:
    _custom_access: '\Drupal\example\Controller\ExampleController::access'

Then

namespace Drupal\example\Controller;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

/**
 * Builds an example page.
 */
class ExampleController {

  /**
   * Checks access for a specific request.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(AccountInterface $account) {
    // parameters from the route and/or request as needed.   
   // **Here you can access and validate parameters.**
    return AccessResult::allowedIf($account->hasPermission('do example things') && $this->someOtherCustomCondition());
  }

}
0

I did something like this before ( take a look at helper link ),it not required to tell router about type

just post your data and in your controller get them with

$value = \Drupal::request()->request->get('your_posted_variable'); 

Also you can get all $_POST variables with

  \Drupal::request()->request->all(); // equal to $_POST
1
  • 1
    It's true what you are saying, thanks, but I know how to get params. I'm just trying to set them as required. Please see my update, I'm sorry I wasn't more clear.
    – Trupal
    Aug 29, 2016 at 12:49
0

You don't need to set anything on the route if you have a default parameter for POST you can add the value directly in the controller:

\Drupal\example\Controller\ExampleController::content

Then you check if you have receive some value in the POST method and if you have values replace the default value.

Your Answer

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

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