2015-05-16 15 views
5

Stworzyłem kod połączony API z Apigility. Na razie używam standardowych kodów pośredniczących. W moim PostResource znajduje się metoda o nazwie fetchAll($params = array()). Stworzyłem kod metody tak, że zwraca paginatable zestaw wyników:Ogranicz wyniki w Apilility

/** @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)); 

to działa prawidłowo tak daleko. Jeśli przejdę do adresu API interfejsu API, otrzymam podzieloną na paginację json reprezentację moich danych DB. Jeśli ustawię rozmiar strony dla mojego API na 5. Da mi to 2 strony i 5 wyników. Jak na razie dobrze. Problem polega na tym, że przy każdym wywołaniu (strona 1 lub strona 2) wszystkie 10 wyników zostanie pobranych z DB. Zwraca tylko 5 na jednej stronie, ale 10 jest nawodnionych itd.

Czy istnieje sposób na wykorzystanie limitu, ale również powiadomienie Apigility lub paginatora, ile wyników jest w sumie tak, że otrzymam 5 wierszy i nadal paginacja?

+1

Może spojrzeć Pod 'Adapter paginatora' DbSelect'? -> http://framework.zend.com/manual/current/en/modules/zend.paginator.usage.html#the-dbselect-adapter – Crisp

+0

Domyślnie kolekcje rozszerzają 'Zend \ Paginator \ Paginator', więc jeśli Używasz standardowych skrótów, zachowanie, które opisujesz, nie powinno się wyświetlać. Jak wygląda twój łańcuch połączeń? W ten sposób: 'FooResource # fetchAll (...) -> FooService # getBar (...) -> FooMapper # findAll (...)'? Czy 'FooMapper # findAll (...)' zwraca 'FooCollection'? 'findAll ($ params = array()) { \t $ select = $ this-> getSelect(); \t $ select-> where (...); \t $ paginatorAdapter = $ this-> createPaginationAdapter ($ select); \t $ collection = new FooCollection ($ paginatorAdapter); \t return $ kolekcja; } ' – automatix

Odpowiedz

4

Nie wiem dokładnie, w jaki sposób pobiera się dane, ale jednak następujące podejście działa zgodnie z oczekiwaniami: Łańcuch wywołań wygląda na AddressResource#fetchAll(...) -> AddressService#getBar(...) -> AddressMapper#findAll(...), a metoda odzyskiwania danych zwraca obiekt Collection.

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, 
      ... 
     ), 
     ... 
    ), 
    ... 
); 

Teraz test: Dzwonię /addresses i obserwując dziennik zapytań MySQL:

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

... 

3 Connect [email protected] 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 

...