Upload
albert-jessurum
View
4.158
Download
4
Tags:
Embed Size (px)
DESCRIPTION
Guzzle es un cliente HTTP que facilita de forma increíble el crear, consumir e interactuar con servicios web, como por ejemplo, la api REST de un servicio web como Twitter, Amazon AWS, Github, entre otros. Nos ofrece completo control del estándar HTTP para la generación de un Request y nos permite de forma organizada manejar el Response y definir modelos sobre las respuestas para actuar mas facilmente sobre ellas. En esta charla se introducirá como configurar la libreria de forma independiente en menos de 10 minutos, y como integrarlo en un proyecto de Symfony2 y Silex, para empezar a atacar APIs, se explicaran sus usos mas comunes, se hablara de proyectos que ya lo tienen incorporado (como Drupal, el Amazon AWS SDK para PHP, y la libreria Goutte, para hacer Webscraping, de Fabien Potencier, entre otras). Se terminara con un ejemplo practico en dos proyectos de Acilia, para atacar a un servicio web (emailvision), para envíos de emails transaccionales y masivos de dos aplicaciones y posterior recopilación de reportes de dichos envíos, todo mediante llamadas y respuestas HTTP a una API REST.
Citation preview
Albert Jessurum
Albert Jessurum
acilia.es
Albert Jessurum
acilia.es
chess.com
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
@ajessu
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
@ajessu
github.com/ajessu
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
@ajessu
github.com/ajessu
Fan de Symfony
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
@ajessu
github.com/ajessu
Fan de Symfony
Albert Jessurum
acilia.es
chess.com
Maracaibo, Venezuela
@ajessu
github.com/ajessu
Fan de Symfony
Guzzle
¿Que es Guzzle?
¿Que es Guzzle?
¿Que es Guzzle?
• Cliente para realizar peticiones http
¿Que es Guzzle?
• Cliente para realizar peticiones http
• cURL
¿Que es Guzzle?
• Cliente para realizar peticiones http
• cURL
• Conexiones persistentes
¿Que es Guzzle?
• Cliente para realizar peticiones http
• cURL
• Conexiones persistentes
• Peticiones paralelas
¿Que es Guzzle?
• Cliente para realizar peticiones http
• cURL
• Conexiones persistentes
• Peticiones paralelas
• Plugins
¿Por que Guzzle?
¿Por que Guzzle?
¿Por que Guzzle?
• Peticiones http en general
¿Por que Guzzle?
• Peticiones http en general
• API
¿Por que Guzzle?
• Peticiones http en general
• API
• Scrapping
¿Por que Guzzle?
• Peticiones http en general
• API
• Scrapping
• Envio de datos/reportes (POST)
Alternativas
Alternativas
Alternativas
• file_get_contents/fopen
Alternativas
• file_get_contents/fopen
• cURL
Alternativas
• file_get_contents/fopen
• cURL
• pecl_http
Alternativas
• file_get_contents/fopen
• cURL
• pecl_http
• Zend_Http
Alternativas
• file_get_contents/fopen
• cURL
• pecl_http
• Zend_Http
• Buzz
Proyectos que usan Guzzle
Proyectos que usan Guzzle
Proyectos que usan Guzzle
• Drupal 8
Proyectos que usan Guzzle
• Drupal 8
• Goutte
Proyectos que usan Guzzle
• Drupal 8
• Goutte
• Amazon AWS
Guzzle en menos de 1 minuto
Guzzle en menos de 1 minuto
Guzzle en menos de 1 minuto
// Version >= 3.7
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de control
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de controluse Guzzle\Http\Client;
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de controluse Guzzle\Http\Client;
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de controluse Guzzle\Http\Client;
$client = new Client('http://desymfony.com');
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de controluse Guzzle\Http\Client;
$client = new Client('http://desymfony.com');$request = $client->get('/');
Guzzle en menos de 1 minuto
// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');
// Para un poco mas de controluse Guzzle\Http\Client;
$client = new Client('http://desymfony.com');$request = $client->get('/');$response = $request->send();
Guzzle HTTP Client
Guzzle HTTP Client
Guzzle HTTP Client
• Clientes
Guzzle HTTP Client
• Clientes
• Requests
• Sin body
• Con body
Guzzle HTTP Client
• Clientes
• Requests
• Sin body
• Con body
• Responses
Guzzle HTTP Client
Client Object
Client Object
$client = new Client('https://api.github.com/test');
// Absoluta$request = $client->get('https://api.github.com/test');// https://api.github.com/test
// relativa (con slash)$request = $client->get('/users');// https://api.github.com/users
// relativa (sin slash)$request = $client->get('users');// https://api.github.com/test/users
// Configuración de la petición$client->setUserAgent('Test/123');
Guzzle HTTP Client
Request Object
Request Object
// Crear un método en especifico$client->createRequest('METODO', $uri, array $headers, $body, $options);
// GET$client->get($uri, array $headers, $options);
//HEAD$client->head($uri, array $headers, $options);
//DELETE$client->delete($uri, array $headers, $body, $options);
//POST$client->post($uri, array $headers, $postBody, $options);
//PUT$client->put($uri, array $headers, $body, $options);
//PATCH$client->patch($uri, array $headers, $body, $options);
Request Object
// Una petición simple:
$request = $client->head('/path?id=123&nombre=abc');$response = $request->send();
// Una petición con cuerpo adjunto$request = $client->post('http://test.com/upload') ->addPostFiles(array('file' => '/ruta/a/documento.json'));$response = $request->send();
// Content-Type: application/json
Request Object
$request = $client->createRequest('COPY', 'http://example.com/foo', array( 'Destination' => 'http://test.com/bar', 'Overwrite' => 'T'));$response = $request->send();
Guzzle HTTP Client
Response Object
Response Object
$response = $client->get('http://www.amazon.com')->send();
echo $response->getStatusCode();// 200
echo $response->isSuccessful();// true
$response->isRedirect();// false
Response Object
// Respuesta de la peticiónecho $response->getBody();
// Si el formato es correcto:
// Devuelve un array de la respuesta json de la peticiónecho $response->json();
// Devuelve un objeto SimpleXMLElement de la peticiónecho $response->xml();
Plugins
Response Object
// Envía una petición si, y otra no con el plugin:// UnaSiOtraNoPlugin
$unaSiOtraNo = new UnaSiOtraNoPlugin();$client->addSubscriber($unaSiOtraNo);
Plugins
• Async plugin
• Backoff retry plugin
• HTTP Cache plugin
• OAuth plugin
• Cookie plugin
• History plugin
• Log plugin
• MD5 validator plugin
• Mock plugin
Plugins
Async plugin
Plugins
Backoff retry plugin
Plugins
HTTP Cache Plugin
HTTP Cache Plugin
HTTP Cache Plugin
HTTP Cache Plugin
• Chequea el HEAD del Request, para verificar el status.
HTTP Cache Plugin
• Chequea el HEAD del Request, para verificar el status.
HTTP Cache Plugin
• Chequea el HEAD del Request, para verificar el status.
• Se puede crear una cache falsa
Plugins
OAuth Plugin
OAuth Plugin
OAuth Plugin
OAuth Plugin
• OAuth 1.0 (Twiiter)
OAuth Plugin
• OAuth 1.0 (Twiiter)
• OAuth 2.0 (Facebook)
OAuth Plugin
• OAuth 1.0 (Twiiter)
• OAuth 2.0 (Facebook)
• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )
OAuth Plugin
• OAuth 1.0 (Twiiter)
• OAuth 2.0 (Facebook)
• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )
OAuth Plugin
• OAuth 1.0 (Twiiter)
• OAuth 2.0 (Facebook)
• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )
// Cargando el plugin OAuth
$client = new Client('http://api.twitter.com/1.1');$oauth = new OauthPlugin(array( 'consumer_key' => 'mi_key', 'consumer_secret' => 'mi_string_secreto', 'token' => 'mi_token', 'token_secret' => 'mi_token_secreto'));$client->addSubscriber($oauth);
$request = $client->get('statuses/public_timeline.json');
$response = $request->send();
Service Builder
Service Builder
// Create cliente de twitter$client = TwitterClient::factory(array( 'consumer_key' => '****', 'consumer_secret' => '****', 'token' => '****', 'token_secret' => '****'));
Service Builder
// Crear un cliente desde un factory
$builder = ServiceBuilder::factory('/ruta/a/config.json');$twitter = $builder->get('twitter');
Service Builder
{ "services": { "twitter_ajessu": { "class": "ajessu\TwitterClient", "params": { "consumer_key": "****", "consumer_secret": "****", "token": "****", "token_secret": "****" } }, "twitter_desymfony": { "class": "ajessu\TwitterClient", "params": { "consumer_key": "****", "consumer_secret": "****", "token": "****", "token_secret": "****" } } }}
$twitter_ajessu = $builder->get('twitter_ajessu');$twitter_desymfony = $builder->get('twitter_desymfony');
Service Definition
Service Builder
{ "name": "string", "apiVersion": "string|number", "baseUrl": "string", "description": "string", "operations": {}, "models": {}, "includes": ["string.php", "string.json"]}
Service Builder
{ "includes":[ "connection.json" ], "name": "IndividualMember", "apiVersion": "0.1", "description": "Individual Member Api for Emailvision", "baseUrl": "{schema}://{server}/apimember/services/rest", "operations": { "InsertOrUpdateMember": { "httpMethod": "POST", "uri": "member/insertOrUpdateMember/{token}", "summary": "Updates a user if it exists, otherwise it updates it", "responseClass": "InsertOrUpdateMember", "parameters": { "token": { "location": "uri", "description": "Connection token", "required": true }, "user": { "location": "body", "description": "User values in xml", "required": true }, "Content-Type": { "location": "header", "default": "application/xml" } } } }}
Service Builder
{ "name": "Connection", "apiVersion": "0.1", "description": "Connection Api for Emailvision", "operations": { "OpenConnection": { "httpMethod": "GET", "uri": "connect/open/{apiLogin}/{apiPassword}/{apiKey}", "summary": "Opens the connection", "responseClass": "OpenConnection", "parameters": { "apiLogin": { "location": "uri", "description": "API username", "required": true }, "apiPassword": { "location": "uri", "description": "API password", "required": true }, "apiKey": { "location": "uri", "description": "API secret key", "required": true } } }, ... }, "models": { "OpenConnection": { "type": "object", "properties": { "token": { "location": "xml", "type": "string", "sentAs": "result" }, "status": { "type": "int", "location": "statusCode" } } }, ... }}
Service Builder
$memberClient = DataIndividualClient::factory();
// Get the token $openConnectionCommand = $memberClient->getCommand( 'OpenConnection', array( 'apiLogin' => '*****', 'apiPassword' => '****', 'apiKey' => ‘*********’ ) );
$openConnectionResponse = $memberClient->execute($openConnectionCommand);
$token = $openConnectionResponse['token']; $body = EntityBody::factory(‘/foo/user.xml’);
$updateUserCommand = $memberClient->getCommand( 'InsertOrUpdateMember', array( 'token' => $token, 'user' => $body ) );
$memberClient->execute($updateUserCommand);
// Close connection $closeConnectionCommand = $memberClient->getCommand( 'CloseConnection', array('token' => $token) ); $memberClient->execute($closeConnectionCommand);
Guzzle en silex
Guzzle en silex
$app = new Application();
$app->register(new GuzzleServiceProvider(), array( 'guzzle.services' => '/ruta/a/servicios.json',));
Guzzle en Symfony2
Guzzle en Symfony2
Guzzle en Symfony2
• Varios bundles
Guzzle en Symfony2
• Varios bundles
• Mejor opción hoy: MisdGuzzleBundle( https://github.com/misd-service-development/guzzle-bundle )
Guzzle en Symfony2
• Varios bundles
• Mejor opción hoy: MisdGuzzleBundle( https://github.com/misd-service-development/guzzle-bundle )
• Discusion (hace tres dias) = Vamos a unirlos!( https://github.com/misd-service-development/guzzle-bundle/issues/28 )k
Guzzle en Symfony2
// app/AppKernel.php
class AppKernel extends Kernel{ // ... public function registerBundles() { $bundles = array( // ... new Misd\GuzzleBundle\MisdGuzzleBundle() ); }}
Guzzle en Symfony2
// MyBundle/Resources/config/services.xml
<service id="example.client" class="%guzzle.client.class%"> <tag name="guzzle.client"/> <argument>http://api.example.com/</argument> <argument type="collection"> <argument key="setting1">true</argument> <argument key="setting2">false</argument> </argument> <call method="addSubscriber"> <argument type="service" id="some_guzzle_plugin"/> </call> <call method="setUserAgent"> <argument>My Guzzle client</argument> <argument>true</argument> </call> <call method="setDescription"> <argument type="service" id="example.client.service_description"/> </call></service>
Guzzle en Symfony2
$client = $this->get('example.client');
// Service description:<service id="example.client.service_description" class="%guzzle.service_description.class%" factory-class="%guzzle.service_description.class%" factory-method="factory"> <argument>%path.to.my.service_description.file%</argument></service>