Zend Framework 2 REST API:想要调用get()而不是getList()

Zend Framework 2 REST API:想要调用get()而不是getList()

问题描述:

I am building RESTful API in Zend Framework 2. My route is article/person. I know that if id is not passed in url then it will call getList() method, not get().

In my case, I don't pass id as a get or post parameter but I pass it in HTTP header. As I use id to perform database operations, I want it to call get() method, not getList(). How can I tweak the code to do that?

Is it possible to specify exact method name to call in routing?

我在Zend Framework 2中构建RESTful API。我的路由是 article / person code>。 我知道如果 id code>没有在url中传递,那么它将调用 getList() code>方法,而不是 get() code>。 p> \ n

就我而言,我没有将 id code>作为get或post参数传递,但我在HTTP头中传递它。 当我使用 id code>来执行数据库操作时,我希望它调用 get() code>方法,而不是 getList() code>。 我如何调整代码来做到这一点? p>

是否可以指定在路由中调用的确切方法名称? p> div>

I don't pass id as a get or post parameter but I pass it in HTTP header

This does make your REST invalid, so it isn't actually REST anymore. You therefor cannot use the RestfulAbstractController without customization.

You can either write your own abstract controller or you override the getIdentifier method:

protected function getIdentifier($routeMatch, $request)
{
    $identifier = $this->getIdentifierName();
    $headers    = $request->getHeaders();

    $id = $headers->get($identifier)->getFieldValue();
    if ($id !== false) {
        return $id;
    }

    return false;
}

Make sure you set the correct identifier name in each controller. In this case, the identifier name should match the name of the header you are using.

Note this will be used for GET, PUT, PATCH, DELETE and HEAD requests, not only for GET!

/edit:

The getIdentifier method is called in the flow a controller determines which method to run. Normally, it's this:

  1. The controller is constructed
  2. The controller's dispatch is called (the controller is Dispatchable)
  3. The dispatch triggers an event "dispatch"
  4. The method onDispatch listens to this event
  5. In the AbstractRestfulController the method tries to determine which method to call

For #5, it checks for example if the request is a GET request. If so, it checks if there is an identifier given. If so, the get() is used. If not, the getList() is used. The "if there is an identifier given" check is done with the getIdentifier() method.

If you extend the AbstractRestfulController with your own abstract controller and override the getIdentifier(), you can determine your own identifier. This way, you can check for the header instead of the route parameter or query parameter.

I think the easiest approach is to call get method from getList method

public function getList(){
   // get id from header
   $id = $this->getRequest()->getHeaders()->get("id-header-field");
   if ($id){
       return $this->get($id);
   }
   else{ /* return list */}
}

public function get($id){
  return JsonModel($data);
}

Override AbstractRestfulController to be able to tweak all the functionality related to the id.

class YourController extends AbstractRestfulController {

    //in the constructor, ensure that your id name is set to the header variable you are using
    public function __construct() {
        $this->identifierName = 'id'; // Override $identifierName value specified in AbstractRestfulController, if you need it
    }

    protected function getIdentifier($routeMatch, $request)
    {

        //first of all, check if the id is set in the $routeMatch params, this is, in the normal way
        $id= parent::getIdentifier($routeMatch, $request);     
        if ($id !== false) {
            return $id;
        }

        //if the id its not set, check out the headers 
        $id =  $request->getHeaders()->get($this->getIdentifierName())->getFieldValue();
        if ($id !== false) {
            return $id;
        }

        return false;
    }

}