Immaginiamo di trovarci in una situazione diversa rispetto a quella descritta nelle precedenti lezioni: la nostra API delle categorie possiede un metodo che restituisce la singola categoria con tutti i suoi dettagli e con un link a una seconda API per caricare tutti i prodotti della categoria stessa. La nostra pagina dovrà quindi eseguire delle richieste multiple.
Ovviamente possiamo ipotizzare una situazione in cui lato server venga creato un file unico JSON, contenente tutte le informazioni: in questo caso non ci sarebbero particolari novità rispetto a quanto già esposto. Cambiano le cose se vogliamo combinare i risultati a seguito di più richieste del client. Per gestire richieste multiple Angular, nelle versioni successive alla prima che si basava sulle promise
, mette a disposizione Observable
. La differenza risiede nel fatto che mentre le promise
gestiscono un singolo evento, observable
permette di gestire pi ù eventi cancellabili.
La libreria rxJs
fornisce degli operatori che permetteranno poi di combinare i risultati. Integriamo il nostro backend PHP con gli script necessari, quindi aggiungiamo un metodo per la lettura di una singola categoria al file category.php
:
function read($id){
$query = "SELECT c.nome, c.id FROM " . $this->table_name . " c WHERE c.id = ?";
$stmt = $this->conn->prepare( $query );
$stmt->bindParam(1, $id);
$stmt->execute();
return $stmt;
}
Nella API inseriamo invece un blocco if else
basato sulla presenza (o meno) del parametro id
. Se esso è assente leggiamo l'elenco delle categorie, altrimenti accediamo alla singola categoria:
$stmt = $category->read($id);
$categories_arr=array();
$categories_arr["records"]=array();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$row['prodotti']="http://localhost/phprest/api/v1/categorie-prodotti/".$row['id'];
echo json_encode($row);
In questo caso è importante notare che al JSON di risposta viene aggiunto l'URL per una richiesta che restituirà tutti i prodotti di quella categoria.
Costruiamo la classe CategorieProdotti
con lo stesso principio di prodotti e categorie:
class CategorieProdotti{
private $conn;
private $table_name = "categorie";
public function __construct($db){
$this->conn = $db;
}
function readProdottoPerCategoria($id){
$query = "SELECT
c.nome as categoria_nome, p.id, p.nome, p.descrizione, p.prezzo, p.categoria_id, p.data_insert
FROM
" . $this->table_name . " c
LEFT JOIN
prodotti p
ON p.categoria_id = c.id
WHERE
c.id = ?";
$stmt = $this->conn->prepare( $query );
$stmt->bindParam(1, $id);
$stmt->execute();
return $stmt;
}
}
E ora l'API che si appoggia questa classe:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
include_once '../../config/database.php';
include_once '../../objects/categorie-prodotti.php';
$database = new Database();
$db = $database->getConnection();
$method = $_SERVER['REQUEST_METHOD'];
if($method == 'OPTIONS'){
$method = $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'];
}
$id=0;if(isset($_REQUEST['request'])){$id=$_REQUEST['request'];}
switch ($method) {
case 'GET':
$category = new CategorieProdotti($db);
$stmt = $category->readProdottoPerCategoria($id);
$categories_arr=array();
$categories_arr["records"]=array();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($rows);
break;
}
Riassumendo, abbiamo aggiunto al backend un metodo per avere la singola categoria, i dati in risposta sono integrati con un URL che richiama una nuova API deputata a fornire i prodotti per una specifica categoria.