2015-05-16 6 views
5

Ho creato un'API connessa al codice con Apigility. Per ora sto usando gli stub di creazione standard. Nel mio PostResource c'è un metodo chiamato fetchAll($params = array()). ho creato il codice per il metodo in modo che restituisca un insieme paginatable di risultati:Limitare i risultati in Apigility

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

Questo funziona bene finora. Se si accede all'URL dell'API, otterrò una rappresentazione impaginata json dei miei dati DB. Se imposto la dimensione della pagina per la mia API su 5. Mi darà 2 pagine e 5 risultati. Fin qui tutto bene. Il problema è che su ogni chiamata (pagina 1 o pagina 2) tutti i 10 risultati saranno recuperati dal DB. Restituisce solo 5 in una pagina ma 10 sono idratati ecc.

C'è un modo per usare un limite ma anche lasciare che Apigility o l'impaginatore sappiano, quanti risultati ci sono in totale in modo che io ottenga 5 righe e ancora l'impaginazione?

+1

Forse dare un'occhiata alla Adattatore paginatore 'DbSelect'? -> http://framework.zend.com/manual/current/en/modules/zend.paginator.usage.html#the-dbselect-adapter – Crisp

+0

Per default le collezioni estendono 'Zend \ Paginator \ Paginator', quindi se Stai usando gli stub standard, il comportamento che stai descrivendo non dovrebbe apparire. Come appare la tua catena di chiamate? In questo modo: 'FooResource # fetchAll (...) -> FooService # getBar (...) -> FooMapper # findAll (...)'? Il 'FooMapper # findAll (...)' restituisce un 'FooCollection'? 'findAll ($ params = array()) { \t $ select = $ this-> getSelect(); \t $ select-> where (...); \t $ paginatorAdapter = $ this-> createPaginationAdapter ($ select); \t $ collection = new FooCollection ($ paginatorAdapter); \t ritorno $ raccolta; } ' – automatix

risposta

4

Non so esattamente come si recuperano i dati, ma il seguente approccio funziona come desiderato: la catena di chiamate si presenta come AddressResource#fetchAll(...) -> AddressService#getBar(...) -> AddressMapper#findAll(...) e il metodo di recupero dei dati restituisce un oggetto 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, 
      ... 
     ), 
     ... 
    ), 
    ... 
); 

Ora un test: Sto chiamando /addresses e osservando il log delle query 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 

...