0

I'm developing an Apigility driven application based on the Zend Framework 2.

I want my application to provide nested responses for both -- single items and lists:

/projects/1

{
    "id": "1",
    "title": "...",
    ...
    "_embedded": {
        "images": [
            {
                "id": "1",
                "project_id": "1",
                "title": "...",
                ...
            },
            {
                "id": "2",
                "project_id": "1",
                "title": "...",
                ...
            }
        ]
    },
    ...
}

/projects

{
    ...
    "_embedded": {
        "projects": [
            {
                "id": "1",
                "title": "...",
                ...
                "_embedded": {
                    "images": [
                        {
                            "id": "1",
                            "project_id": "1",
                            "title": "...",
                            ...
                        },
                        ...
                    ]
                },
                ...
            },
            ...
        ]
    },
    "total_items": 2
}

Since I've not found an apigility conform solution for implementing lists with nested lists (in this case projects with a list of images for every project list item, see here). I have to deal with the Paginator and DbAdapter and provide the page parameter manually:

class ProjectResource extends AbstractResourceListener {
    ...
    public function fetchAll($params = array()) {
        $pageNumber = $this->getEvent()->getRouteMatch()->getParam('page', 1); <-- that doesn't work
        $projectService = $this->getProjectService();
        $offset = $pageNumber > 0 ? $pageNumber - 1 : 0;
        $config = $this->getServiceManager()->get('Config');
        $itemCountPerPage = $config['zf-rest']['Portfolio\\V2\\Rest\\Project\\Controller']['page_size'];
        $projects = $projectService->getProjects($offset, $itemCountPerPage);
        return $projects;
    }
    ...
}

The problem is, that $this->getEvent()->getRouteMatch()->getParam('page', 1) doesn't work. Instead of the page parameter, $this->getEvent()->getRouteMatch()->getParams() returns

Array
(
    [controller] => Portfolio\V2\Rest\Project\Controller
    [version] => 2
)

How to access request parameters?

Community
  • 1
  • 1
automatix
  • 14,018
  • 26
  • 105
  • 230

1 Answers1

1

Request parameters have first to be added onto the whitelist. It can be done over the Apigility GUI or directly in the config:

module.config.php

return array(
    ...
    'zf-rest' => array(
        ...
        'Portfolio\\V2\\Rest\\Project\\Controller' => array(
            ...
            'collection_query_whitelist' => array('page'),
            ...
        ),
        ...
    ),
);

Then the parameter can be accessed over the arguments of the end point methods of the Resource class:

public function fetchAll($params = array()) {
    $projectService = $this->getProjectService();
    $config = $this->getServiceManager()->get('Config');
    $itemCountPerPage = $config['zf-rest']['Portfolio\\V2\\Rest\\Project\\Controller']['page_size'];
    $pageNumber = isset($params['page']) && intval($params['page']) > 0
        ? $params['page']
        : 1
    ;
    $offset = ($pageNumber - 1) * $itemCountPerPage;
    $projects = $projectService->getProjects($offset, $itemCountPerPage);
    return $projects;
}

See also the Apiglity documentation: ZF REST -> Configuration -> User Configuration -> collection_query_whitelist.

automatix
  • 14,018
  • 26
  • 105
  • 230