John Davidson

php - How to handle OOP in this particular situation

0 comments
Message:


I have to integrate my Drupal application with a third party API through Soap and Rest services.


I would like to be more orthogonal as possible! But i'm not satisfied what i come out with, and I'm asking help here because i don't want to loose too much time with this.


these are my abstract Rest and Soap services:


 abstract class RestService {

protected $config;

protected $httpClient;

public function __construct(ConfigFactoryInterface $configFactory) {
$this->config = $configFactory->get('third_party.rest_service');
$this->httpClient = new Client(['base_uri' => $this->setBaseUri()]);
}

protected abstract function setBaseUri();

}

abstract class SoapService {

protected $client;

protected $credentials;

public function __construct(ConfigFactoryInterface $configFactory) {
$config = $configFactory->get('third_party.soap_service');
$this->client = new SoapClient($config->get('wsdl_url'));
$this->credentials = new SoapCredentials();
}

}

and now the "specialized" services:


class AuthService extends RestService {

protected function setBaseUri() {
return $this->config->get('auth_basepath');
}

public function getAccessToken() {
$accessToken = $this->config->get('access_token');

if (!$this->isTokenValid($accessToken)) {
$accessToken = $this->refreshToken();
}

return $accessToken;
}

protected function isTokenValid($accessToken) {...}

}


class ContactsService extends SoapService {

public function __construct(ConfigFactoryInterface $configFactory, AuthService $authService) {
parent::__construct($configFactory);

$this->credentials->password = $authService->getAccessToken();
}

public function ... {}

}


class EventsService extends RestService {

protected $accessToken;

public function __construct(ConfigFactoryInterface $configFactory, AuthService $authService) {
parent::__construct($configFactory);

$this->accessToken = $authService->getAccessToken();
}

protected function setBaseUri() {
return $this->config->get('events_basepath');
}

public function getEvents(array $filters = null) {...}

}

As you can see AuthService is used for get Access Token and use it in both soap and rest authenticated api calls, but it extends RestService as EventsService already does.


My doubt is in EventsService actually, i don't know if it's a good practice do depencency injection of a class (AuthService) that extends the same class of the "container" (EventsService itself).


I know it could be a strange use case but: what would you do in this situation?


Thank you in advance for your help!



My Answer:
In this situation, it is not necessarily a bad practice to inject a class (AuthService) that extends the same class (RestService) as the container class (EventsService). However, if you want to make your code more orthogonal and avoid potential issues with circular dependencies, you could consider refactoring your code slightly.

One approach could be to create a separate interface for the authentication functionality that both AuthService and EventsService can implement. This way, EventsService can depend on the interface instead of the concrete AuthService class. This can help decouple the classes and make your code more flexible and easier to maintain.

Here is an example of how you could refactor your code:

1. Create an interface for the authentication functionality:

php
interface AuthenticationServiceInterface {
public function getAccessToken();
}


2. Update AuthService to implement the interface:

php
class AuthService extends RestService implements AuthenticationServiceInterface {
// Implement the getAccessToken method
}


3. Update EventsService to depend on the interface instead of the concrete AuthService class:

php
class EventsService extends RestService {
protected $accessToken;

public function __construct(ConfigFactoryInterface $configFactory, AuthenticationServiceInterface $authService) {
parent::__construct($configFactory);

$this->accessToken = $authService->getAccessToken();
}

// Rest of the EventsService implementation
}


By following this approach, you can make your code more flexible and easier to maintain, while still achieving the desired functionality.

Rate this post

4 of 5 based on 2680 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us