Download - deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Transcript
Page 1: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2
Page 2: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2
Page 3: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

Page 4: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

Page 5: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Page 6: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

Page 7: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

@ajessu

Page 8: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

@ajessu

github.com/ajessu

Page 9: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

@ajessu

github.com/ajessu

Fan de Symfony

Page 10: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

@ajessu

github.com/ajessu

Fan de Symfony

Page 11: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Albert Jessurum

acilia.es

chess.com

Maracaibo, Venezuela

@ajessu

github.com/ajessu

Fan de Symfony

Page 12: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle

Page 13: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

Page 14: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

Page 15: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

• Cliente para realizar peticiones http

Page 16: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

• Cliente para realizar peticiones http

• cURL

Page 17: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

• Cliente para realizar peticiones http

• cURL

• Conexiones persistentes

Page 18: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

• Cliente para realizar peticiones http

• cURL

• Conexiones persistentes

• Peticiones paralelas

Page 19: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Que es Guzzle?

• Cliente para realizar peticiones http

• cURL

• Conexiones persistentes

• Peticiones paralelas

• Plugins

Page 20: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

Page 21: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

Page 22: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

• Peticiones http en general

Page 23: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

• Peticiones http en general

• API

Page 24: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

• Peticiones http en general

• API

• Scrapping

Page 25: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

¿Por que Guzzle?

• Peticiones http en general

• API

• Scrapping

• Envio de datos/reportes (POST)

Page 26: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

Page 27: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

Page 28: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

• file_get_contents/fopen

Page 29: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

• file_get_contents/fopen

• cURL

Page 30: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

• file_get_contents/fopen

• cURL

• pecl_http

Page 31: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

• file_get_contents/fopen

• cURL

• pecl_http

• Zend_Http

Page 32: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Alternativas

• file_get_contents/fopen

• cURL

• pecl_http

• Zend_Http

• Buzz

Page 33: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Proyectos que usan Guzzle

Page 34: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Proyectos que usan Guzzle

Page 35: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Proyectos que usan Guzzle

• Drupal 8

Page 36: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Proyectos que usan Guzzle

• Drupal 8

• Goutte

Page 37: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Proyectos que usan Guzzle

• Drupal 8

• Goutte

• Amazon AWS

Page 38: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

Page 39: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

Page 40: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

// Version >= 3.7

Page 41: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

// Version >= 3.7Guzzle\Http\StaticClient::mount();

Page 42: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');

Page 43: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');

Page 44: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en menos de 1 minuto

// Version >= 3.7Guzzle\Http\StaticClient::mount();$response = Guzzle::get('http://desymfony.com');

// Para un poco mas de control

Page 45: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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;

Page 46: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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;

Page 47: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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');

Page 48: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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('/');

Page 49: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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();

Page 50: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

Page 51: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

Page 52: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

• Clientes

Page 53: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

• Clientes

• Requests

• Sin body

• Con body

Page 54: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

• Clientes

• Requests

• Sin body

• Con body

• Responses

Page 55: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

Client Object

Page 56: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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');

Page 57: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

Request Object

Page 58: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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);

Page 59: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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

Page 60: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Request Object

$request = $client->createRequest('COPY', 'http://example.com/foo', array( 'Destination' => 'http://test.com/bar', 'Overwrite' => 'T'));$response = $request->send();

Page 61: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle HTTP Client

Response Object

Page 62: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Response Object

$response = $client->get('http://www.amazon.com')->send();

echo $response->getStatusCode();// 200

echo $response->isSuccessful();// true

$response->isRedirect();// false

Page 63: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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();

Page 64: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

Page 65: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Response Object

// Envía una petición si, y otra no con el plugin:// UnaSiOtraNoPlugin

$unaSiOtraNo = new UnaSiOtraNoPlugin();$client->addSubscriber($unaSiOtraNo);

Page 66: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

• Async plugin

• Backoff retry plugin

• HTTP Cache plugin

• OAuth plugin

• Cookie plugin

• History plugin

• Log plugin

• MD5 validator plugin

• Mock plugin

Page 67: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

Async plugin

Page 68: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

Backoff retry plugin

Page 69: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

HTTP Cache Plugin

Page 70: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

HTTP Cache Plugin

Page 71: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

HTTP Cache Plugin

Page 72: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

HTTP Cache Plugin

• Chequea el HEAD del Request, para verificar el status.

Page 73: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

HTTP Cache Plugin

• Chequea el HEAD del Request, para verificar el status.

Page 74: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

HTTP Cache Plugin

• Chequea el HEAD del Request, para verificar el status.

• Se puede crear una cache falsa

Page 75: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Plugins

OAuth Plugin

Page 76: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

Page 77: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

Page 78: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

• OAuth 1.0 (Twiiter)

Page 79: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

• OAuth 1.0 (Twiiter)

• OAuth 2.0 (Facebook)

Page 80: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

• OAuth 1.0 (Twiiter)

• OAuth 2.0 (Facebook)

• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )

Page 81: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

• OAuth 1.0 (Twiiter)

• OAuth 2.0 (Facebook)

• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )

Page 82: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

OAuth Plugin

• OAuth 1.0 (Twiiter)

• OAuth 2.0 (Facebook)

• OAuth2 en los planes pero sin fecha: ( https://github.com/guzzle/guzzle/issues/319 )

Page 83: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

// 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();

Page 84: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Service Builder

Page 85: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Service Builder

// Create cliente de twitter$client = TwitterClient::factory(array( 'consumer_key' => '****', 'consumer_secret' => '****', 'token' => '****', 'token_secret' => '****'));

Page 86: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Service Builder

// Crear un cliente desde un factory

$builder = ServiceBuilder::factory('/ruta/a/config.json');$twitter = $builder->get('twitter');

Page 87: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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');

Page 88: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Service Definition

Page 89: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Service Builder

{ "name": "string", "apiVersion": "string|number", "baseUrl": "string", "description": "string", "operations": {}, "models": {}, "includes": ["string.php", "string.json"]}

Page 90: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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" } } } }}

Page 91: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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" } } }, ... }}

Page 92: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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);

Page 93: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en silex

Page 94: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en silex

$app = new Application();

$app->register(new GuzzleServiceProvider(), array( 'guzzle.services' => '/ruta/a/servicios.json',));

Page 95: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en Symfony2

Page 96: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en Symfony2

Page 97: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en Symfony2

• Varios bundles

Page 98: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en Symfony2

• Varios bundles

• Mejor opción hoy: MisdGuzzleBundle( https://github.com/misd-service-development/guzzle-bundle )

Page 99: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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

Page 100: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Guzzle en Symfony2

// app/AppKernel.php

class AppKernel extends Kernel{ // ... public function registerBundles() { $bundles = array( // ... new Misd\GuzzleBundle\MisdGuzzleBundle() ); }}

Page 101: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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>

Page 102: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

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>

Page 103: deSymfony 2013 Consumiendo APIs REST con Guzzle y Symfony2

Gracias!

Feedback: https://joind.in/8840

Albert [email protected]/ajessu