1

I'm creating a client to a third-party soap web service in my application. Here is the way I'm thinking of doing it:

  • Create a ClientFactory that makes a client based on the wsdl file, and sets needed options on it, then returns it.
  • Have several Request objects, preferably implementing the Request interface, that take the Client as their constructor argument, and then make requests to the web service through that client.

Here is a short example to illustrate my point.

class ClientFactory
{

    public function create()
    {
        return new \SoapClient('http://www.example.com/example.wsdl', [
            'trace' => true
        ]);
    }

}

class LockSeatRequest implements RequestInterface
{

    public function __construct(Client $client)
    {
        $this->client = $client;
    }

    public function execute($id, $count, $date)
    {
        $result = $this->client->lockSeat($id, $count, $date);

        // Make some changes to $result here...

        return $result;
    }

}

interface Request
{

    // what should I put in here?

}

Client code example:

$client = $clientFactory->create();
$lockSeatRequest = new lockSeatRequest($client);
$lockSeatRequest->execute(1, 5, '2015-04-04');

My problem here is that the number of arguments, and the type of arguments, are different from request to request, and this makes it impossible to define an interface. The way I have seen it done in other PHP libraries is to accept an array of parameters, but my issue with that approach is that it makes the user have to look up the parameters for each function call instead of making it explicit. Also, I would then have to add cruft such as checking whether the right keys are defined in the array, to each Request, instead of having the language ensure each parameter with the right type is passed to the function.

How can I have multiple methods, each of them requiring a different number of arguments, but still have them implement a particular interface?

Or, am I seeing this totally wrong?

  • 2
    Can you give a short example for how the different requests are made "through that client"? Who is calling whom here? And which parameters control which request arguments are the correct ones? – Doc Brown Dec 28 '15 at 10:47
  • Why dont you have methods on the client for the various operations? Iwle client.DoThing(argument1, argument2...) – Ewan Dec 28 '15 at 11:08
  • I added a code example. – Parham Doustdar Dec 28 '15 at 12:02
  • @Ewan, the Client class will get too big, since those functions do transformations on the data they receive from the third-party web service to make it consumable by higher-level classes. – Parham Doustdar Dec 28 '15 at 12:03
  • Why not use a code generator to convert the service's WSDL to code, then use that generated code (possibly with a custom wrapper)? Code generators will automatically create the relevant argument structure. – Brian Dec 28 '15 at 16:07
1

I would consider moving the params to the __construct() so each request will do only one thing.

I would also consider decoule the params out using valueobject.

Something like this:

class LockSeatRequest implements RequestInterface
{

    public function __construct(Client $client, LockSeatRequestValueObject $params)
    {
        $this->client = $client;
        $this->params = $params;
    }

    public function execute()
    {
        $result = $this->client->lockSeat($this->params->getId(), $this->params->getCount(), $this->params->getDate());

        // Make some changes to $result here...

        return $result;
    }

}

interface Request
{

    public function execute();
}

class LockSeatRequestValueObject
{
    private $id;
    ....

    public function __construct ($id, $count, $date)
    // or in php7
    // public function __construct (int $id, int $count, \DateTime $date)
    {
        $this->id = $id;
        $this->validate(); // Might be redundant in php7
    }

    public function getId()
    {
        return $this->id;
    }
    ......
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.