Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
17.39% covered (danger)
17.39%
4 / 23
33.33% covered (danger)
33.33%
1 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractApiService
17.39% covered (danger)
17.39%
4 / 23
33.33% covered (danger)
33.33%
1 / 3
13.02
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 sendRequest
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 getHeaders
n/a
0 / 0
n/a
0 / 0
0
 handleApiError
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 parseResponse
n/a
0 / 0
n/a
0 / 0
0
1<?php
2declare(strict_types=1);
3
4namespace App\Service\Api;
5
6use Cake\Http\Client;
7use Cake\Http\Client\Response;
8use Cake\Http\Exception\ServiceUnavailableException;
9
10/**
11 * AbstractApiService Class
12 *
13 * This abstract class provides a foundation for API service classes,
14 * handling common operations such as sending requests and error handling.
15 */
16abstract class AbstractApiService
17{
18    /**
19     * @var \Cake\Http\Client The HTTP client used to send requests.
20     */
21    protected Client $client;
22
23    /**
24     * @var string The API key used for authentication.
25     */
26    protected string $apiKey;
27
28    /**
29     * @var string The base URL of the API.
30     */
31    protected string $apiUrl;
32
33    /**
34     * @var string The version of the API being used.
35     */
36    protected string $apiVersion;
37
38    /**
39     * AbstractApiService constructor.
40     *
41     * @param \Cake\Http\Client $client The HTTP client instance.
42     * @param string $apiKey The API key for authentication.
43     * @param string $apiUrl The base URL of the API.
44     * @param string $apiVersion The version of the API.
45     */
46    public function __construct(Client $client, string $apiKey, string $apiUrl, string $apiVersion)
47    {
48        $this->client = $client;
49        $this->apiKey = $apiKey;
50        $this->apiUrl = $apiUrl;
51        $this->apiVersion = $apiVersion;
52    }
53
54    /**
55     * Sends a POST request to the API with the given payload.
56     *
57     * @param array $payload The data to be sent in the request body.
58     * @return \Cake\Http\Client\Response The response from the API.
59     * @throws \Cake\Http\Exception\ServiceUnavailableException If the API request fails.
60     */
61    public function sendRequest(array $payload, int $timeOut = 30): Response
62    {
63        $response = $this->client->post(
64            $this->apiUrl,
65            json_encode($payload),
66            [
67                'headers' => $this->getHeaders(),
68                'timeout' => $timeOut,
69            ],
70        );
71
72        if (!$response->isOk()) {
73            $this->handleApiError($response);
74        }
75
76        return $response;
77    }
78
79    /**
80     * Gets the headers for the API request.
81     *
82     * @return array An associative array of headers.
83     */
84    abstract protected function getHeaders(): array;
85
86    /**
87     * Handles API errors by logging the error and throwing an exception.
88     *
89     * @param \Cake\Http\Client\Response $response The response from the API.
90     * @throws \Cake\Http\Exception\ServiceUnavailableException Always thrown to indicate the API request failed.
91     */
92    protected function handleApiError(Response $response): void
93    {
94        $errorBody = $response->getStringBody();
95        $statusCode = $response->getStatusCode();
96
97        throw new ServiceUnavailableException(sprintf(
98            'API request error: Status Code %s Body: %s Reason: %s',
99            $statusCode,
100            $errorBody,
101            $response->getReasonPhrase(),
102        ));
103    }
104
105    /**
106     * Parses the API response.
107     *
108     * @param \Cake\Http\Client\Response $response The response from the API.
109     * @return array The parsed response data.
110     */
111    abstract protected function parseResponse(Response $response): array;
112}