27 Marzo, 2013 | Di

Guzzle HTTP client

Guzzle HTTP client

Guzzle è un potente framework PHP per implementare client HTTP e REST basato sulla libreria cURL. Verrà integrato nella prossima versione di Drupal (la 8 in uscita verso fine 2013) ed è già utilizzato come base del nuovo SDK di Amazon per fornire l'accesso alle API dei loro Webservices. In questo articolo vedremo come integrarlo all'interno della propria applicazione. Iniziamo dai requisiti, per funzionare Guzzle ha bisogno della versione 5.3.2 di PHP o superiore con integrato il supporto a cURL e la libreria cURL stessa in versione 7.16.2 o superiore con OpenSSL e zlib abilitati. Niente che non si possa ottenere con un paio di apt-get su un sistema Debian like. Una volta sistemato il problema dei requisiti passiamo all'installazione di Guzzle all'interno del nostro progetto. La strada più veloce è quella di usare Composer per scaricare tutti i file necessari e aggiornare in automatico il file autoload.php, per farlo è sufficiente aggiungere queste righe al proprio file composer.json

{ "require": { "guzzle/guzzle": "~3.1.1" } }

La tilde (~) davanti alla versione ci garantisce il download di Guzzle fino alla versione 4.0.0 esclusa. Come primo esempio possiamo utilizzare Guzzle per recuperare i dati di un account di Github:

get('/user')->setAuth('user', 'pass'); $response = $request->send(); echo $response->getBody(); // >>> {"type":"User", ... echo $response->getHeader('Content-Length'); // >>> 792 $data = $response->json(); echo $data['type']; // >>> User

Alla riga 5 creiamo un'istanza della classe Guzzle\Http\Client passando al costruttore l'URL di base che verrà utilizzato per le richieste successive; usiamo poi questa classe per fare una richiesta di tipo GET all'indirizzo api.github.com/user. La richiesta va autenticata aggiungendo un nome utente e una password (l'autenticazione in questo caso sarà di tipo Basic). Il metodo send() della classe Guzzle\Http\Message\Request invia la richiesta al server. Se la connessione va a buon fine otteniamo un'istanza della classe Guzzle\Http\Message\Response che possiamo utilizzare per accedere a tutte le informazioni che il server ci ha rimandato indietro, tra cui il contenuto della risposta stessa e tutti gli header HTTP. Il metodo json() trasforma il body della risposta (se in formato JSON corretto) in un array PHP. Allo stesso modo possiamo inviare informazioni ad un server utilizzando una richiesta HTTP di tipo POST:

$request = $client->post('httpbin.org/post') ->addPostFields(array('custom_key' => 'value')) ->addPostFiles(array('file' => '/path/to/file.xml'));

Automaticamente Guzzle imposta il formato si invio su multipart/form-data. Guzzle mette a disposizione un'infrastruttura per realizzare client di Web Services velocemente utilizzando il pattern Command. La descrizione del servizio web va scritta dentro un file JSON:

{ "name": "Foo", "apiVersion": "2012-10-14", "baseUrl": "api.foo.com", "description": "Foo is an API that allows you to Baz Bar", "operations": { "GetUser": { "httpMethod": "GET", "uri": "/users/{id}", "summary": "Retrieves a single user", "parameters": { "id": { "location": "uri", "description": "User to retrieve by ID", "required": true } } }, "CreateUser": { "httpMethod": "POST", "uri": "/users", "summary": "Creates a new user", "parameters": { "name": { "location": "json", "type": "string" }, "age": { "location": "json", "type": "integer" } } }, } } Il file JSON viene poi utilizzato dalla classe Guzzle\Service\Description\ServiceDescription per configurare un'istanza della classe Guzzle\Service\Client:
setDescription($description); $command = $client->getCommand('GetUser', array('id' => 123)); $responseModel = $client->execute($command); var_dump($responseModel); } catch (Exception $e) { print($e->getMessage()); }

In questo frammento di codice creiamo un ServiceDescriptor a partire dal file JSON e lo passiamo come descrizione all'oggetto Client, fatto questo possiamo invocare direttamente tutti i comandi che abbiamo definito nel file JSON sotto la voce operations, come ad esempio GetUser. Il comando GetUser ha bisogno di un parametro obbligatorio da passare nella url, dobbiamo quindi specificarne il valore utilizzando il secondo argomento del metodo getCommand. La distribuzione base di Guzzle include un insieme di plugin già pronti per le più svariate necessità, dal logging alla gestione dei cookie, dall'autenticazione alla cache. Oltre a tutte queste funzionalità Guzzle è in grado di gestire connessioni in parallelo, di configurare nel dettaglio la libreria cUrl e supporta in toto la specifica RFC6570 sugli URI templates.