misd-service-development / guzzle-bundle

[NOT MAINTAINED] Integrates Guzzle into your Symfony2 application
99 stars 54 forks source link

Deserialization of non-concrete commands into objects #13

Closed smoorhouse11 closed 11 years ago

smoorhouse11 commented 11 years ago

Scenario: using web service definitions as described in the Guzzle documentation and instantiating service definition and services as described in the MISD Guzzle Bundle docs. test_foo_service is configured using setDescription from a different service description service.

$client = $container->get('test_foo_service');
$command = $client->getCommand('GetFoo');

$command is created by Guzzle and is an instance of Guzzle\Service\Command\OperationCommand. When the onCommandCreate listener is attached it only will attach the serializer for deserializing responses if the created command is an instance of JMSSerializerAwareCommandInterface (Misd\GuzzleBundle\EventListener\CommandListener.php line 89).

Does this mean that automatic deserialization will only work with concrete commands? Maybe commands created by Guzzle be automatically decorated to support this method of deserialization?

thewilkybarkid commented 11 years ago

If you have a concrete command that implements JMSSerializerAwareCommandInterface it will inject the JMSSerializer, you will then need to implement process(). For example:

public function process()
{
    $this->result = $this->serializer->deserialize(
        $this->request->getResponse()->getBody(true),
        'NamedSpaced\ClassName',
        'xml'
    );
}

With OperationCommands, a response parser and request body visitor that handle the (de)serialization automatically are injected in the onCommandCreate() listener (see Misd\GuzzleBundle\Service\Command\JMSSerializerResponseParser and Misd\GuzzleBundle\Service\Command\LocationVisitor\Request\JMSSerializerBodyVisitor).

smoorhouse11 commented 11 years ago

Ah, I now see the visitor hookup to OperationCommands right above it. I actually tracked my problem down to a silly typo in a class name in a service definition file. As I was investigating I saw that there is a class_exists check in line 76 of Service/Command/JMSSerializerResponseParser.php. The problem I was having would have been more evident if that method had thrown an exception when it detected the class didn't exist. I see the way it works now lets it fall back to the normal Guzzle deserialization. It feels like an exception could be appropriate since the deserialization can't really fulfill its contract of creating the object that was requested.

thewilkybarkid commented 11 years ago

Merged