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>