ApiRequestService.php 4.7 KB

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