Frage Begrenzen Sie die Ergebnisse in Apigility


Ich habe eine Code-verbundene API mit Apigility erstellt. Für den Moment verwende ich die Standard-Create-Stubs. In meinem PostResource Es gibt eine Methode namens fetchAll($params = array()). Ich habe den Code für die Methode erstellt, sodass eine paginierbare Ergebnismenge zurückgegeben wird:

/** @var HydratorInterface $hydrator */
$hydrator = new \Zend\Stdlib\Hydrator\ClassMethods();

/** @var PostService $postService */
$postService = new PostService();

$posts = $postService->findAll(/* Limit, default 10 */);
$apiData = array();
foreach ($posts as $post) {
    $apiData[] = $hydrator->extract($post);
}
return new Paginator(new ArrayAdapter($apiData));

Das funktioniert soweit gut. Wenn ich zur API-URL navigiere, werde ich paginiert json Darstellung meiner DB-Daten. Wenn ich die Seitengröße für meine API auf 5 setze, bekomme ich 2 Seiten und 5 Ergebnisse. So weit, ist es gut. Das Problem ist, dass bei jedem Aufruf (Seite 1 oder Seite 2) alle 10 Ergebnisse aus der DB abgerufen werden. Es gibt nur 5 auf einer Seite, aber 10 sind hydratisiert usw.

Gibt es eine Möglichkeit, ein Limit zu verwenden, aber auch Apigility oder den Paginator wissen zu lassen, wie viele Ergebnisse es insgesamt gibt, so dass ich 5 Zeilen bekomme und immer noch die Seitennummerierung?


5
2018-05-16 15:03


Ursprung


Antworten:


Ich weiß nicht genau, wie Sie die Daten abrufen, aber der folgende Ansatz funktioniert wie gewünscht: Die Anrufkette sieht so aus AddressResource#fetchAll(...) -> AddressService#getBar(...) -> AddressMapper#findAll(...) und die Datenabrufmethode gibt a zurück Collection Objekt.

AddressResource.php

...

class AddressResource ... {

    ...

    public function fetchAll($params = array()) {
        $service = $this->getAddressService();
        $collection = $service->getAddresses($params->toArray());
        return $collection;
    }

    ...

}

AddressService.php

...

class AddressService ... {

    ...

    public function getAddresses($params = array()) {
        $collection = $this->getMapper()->findAll($params);
        return $collection;
    }

    ...

}

AddressMapper.php

...

class AddressMapper extends AbstractDbMapper {

    ...

    public function findAll($params = array()) {
        $select = $this->getSelect();
        $select->where(
            ...
        );
        $paginatorAdapter = $this->createPaginationAdapter($select);
        $collection = new AddressCollection($paginatorAdapter);
        return $collection;
    }

    ...

}

AddressCollection.php

...

use Zend\Paginator\Paginator;

class AddressCollection extends Paginator {
}

module.config.php

return array(
    ...
    'zf-rest' => array(
        ...
        'AddressBookAPI\\V1\\Rest\\Address\\Controller' => array(
            ...
            'page_size' => 5,
            ...
        ),
        ...
    ),
    ...
);

Jetzt ein Test: Ich rufe an /addresses und beobachten Sie das MySQL-Abfrageprotokoll:

$ tail -f /var/log/mysql_query.log

...

3 Connect   root@localhost on address-book-api
3 Query     SET NAMES 'UTF8'
3 Query     SELECT COUNT(1) AS `C` FROM (SELECT `addresses`.* FROM `addresses`) AS `original_select`
3 Query     SELECT `addresses`.* FROM `addresses` LIMIT 5 OFFSET 0
3 Quit

...

4
2018-05-18 21:29