ApiRequestService.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service\Rest;
  4. use App\Service\Utils\UrlBuilder;
  5. use Symfony\Component\HttpKernel\Exception\HttpException;
  6. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  7. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  8. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  9. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  10. use Symfony\Contracts\HttpClient\HttpClientInterface;
  11. use Symfony\Contracts\HttpClient\ResponseInterface;
  12. /**
  13. * Base class for services sending requests to an external API.
  14. */
  15. class ApiRequestService implements ApiRequestInterface
  16. {
  17. public function __construct(
  18. protected HttpClientInterface $client,
  19. ) {
  20. }
  21. /**
  22. * Sends a GET request and returns the response's body decoded as json.
  23. *
  24. * @param array<mixed> $parameters
  25. * @param array<mixed> $options
  26. * @param bool $throw @see https://symfony.com/doc/current/http_client.html#handling-exceptions
  27. *
  28. * @return array<mixed>
  29. *
  30. * @throws HttpException
  31. * @throws \JsonException
  32. */
  33. public function getJsonContent(string $path, array $parameters = [], array $options = [], bool $throw = true): array
  34. {
  35. return json_decode($this->getContent($path, $parameters, $options, $throw), true, 512, JSON_THROW_ON_ERROR);
  36. }
  37. /**
  38. * Sends a GET request and returns the response's body.
  39. *
  40. * @param array<mixed> $parameters
  41. * @param array<mixed> $options
  42. * @param bool $throw @see https://symfony.com/doc/current/http_client.html#handling-exceptions
  43. *
  44. * @throws HttpException
  45. */
  46. public function getContent(string $path, array $parameters = [], array $options = [], bool $throw = true): string
  47. {
  48. try {
  49. return $this->get($path, $parameters, $options)->getContent($throw);
  50. } catch (ClientExceptionInterface|TransportExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface $e) {
  51. throw new HttpException($e->getCode(), 'Request error : '.$e->getMessage(), $e);
  52. }
  53. }
  54. /**
  55. * Sends a GET request and returns the response.
  56. *
  57. * @param array<mixed> $parameters
  58. * @param array<mixed> $options
  59. *
  60. * @throws HttpException
  61. */
  62. public function get(string $path, array $parameters = [], array $options = []): ResponseInterface
  63. {
  64. return $this->request('GET', $path, $parameters, $options);
  65. }
  66. /**
  67. * Complète les options en y ajoutant le body.
  68. *
  69. * @param array<mixed> $options
  70. * @param array<mixed>|string $body
  71. *
  72. * @return array<mixed>
  73. */
  74. protected function addBodyOption(array $options, array|string $body): array
  75. {
  76. $option = is_array($body) ? ['json' => $body] : ['body' => $body];
  77. return array_merge($options, $option);
  78. }
  79. /**
  80. * Sends a POST request and returns the response.
  81. *
  82. * @param array<mixed>|string $body
  83. * @param array<mixed> $parameters
  84. * @param array<mixed> $options
  85. *
  86. * @throws HttpException
  87. */
  88. public function post(string $path, array|string $body, array $parameters = [], array $options = []): ResponseInterface
  89. {
  90. $options = $this->addBodyOption($options, $body);
  91. return $this->request('POST', $path, $parameters, $options);
  92. }
  93. /**
  94. * Sends a PUT request and returns the response.
  95. *
  96. * @param array<mixed>|string $body
  97. * @param array<mixed> $parameters
  98. * @param array<mixed> $options
  99. *
  100. * @throws HttpException
  101. */
  102. public function put(string $path, array|string $body, array $parameters = [], array $options = []): ResponseInterface
  103. {
  104. $options = $this->addBodyOption($options, $body);
  105. return $this->request('PUT', $path, $parameters, $options);
  106. }
  107. /**
  108. * Sends a DELETE request and returns the response.
  109. *
  110. * @param array<mixed> $parameters
  111. * @param array<mixed> $options
  112. *
  113. * @throws HttpException
  114. */
  115. public function delete(string $path, array $parameters = [], array $options = []): ResponseInterface
  116. {
  117. return $this->request('DELETE', $path, $parameters, $options);
  118. }
  119. /**
  120. * Send an HTTP request to a REST API,
  121. * and return the decoded content of the response's body.
  122. *
  123. * @param array<mixed> $parameters
  124. * @param array<mixed> $options
  125. *
  126. * @throws HttpException
  127. */
  128. public function request(
  129. string $method,
  130. string $url,
  131. array $parameters = [],
  132. array $options = [],
  133. ): ResponseInterface {
  134. $url = ltrim($url, '/');
  135. $url = UrlBuilder::concatParameters($url, $parameters);
  136. try {
  137. return $this->client->request($method, $url, $options);
  138. } catch (TransportExceptionInterface $e) {
  139. throw new HttpException($e->getCode(), 'Request error : '.$e->getMessage(), $e);
  140. }
  141. }
  142. }