feat(*.php, *.psql): deduplicate API code + performance improvements
This commit is contained in:
parent
cf3dac8a46
commit
4bad005e58
31 changed files with 502 additions and 666 deletions
|
@ -1,72 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
require __DIR__ . "/../../vendor/autoload.php";
|
||||
require __DIR__ . "/BaseHandler.php";
|
||||
|
||||
abstract class ApiHandler
|
||||
abstract class ApiHandler extends BaseHandler
|
||||
{
|
||||
protected string $postgrestUrl;
|
||||
protected string $postgrestApiKey;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->loadEnvironment();
|
||||
}
|
||||
|
||||
private function loadEnvironment(): void
|
||||
{
|
||||
$this->postgrestUrl =
|
||||
$_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL") ?: "";
|
||||
$this->postgrestApiKey =
|
||||
$_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY") ?: "";
|
||||
}
|
||||
|
||||
protected function ensureCliAccess(): void
|
||||
{
|
||||
if (php_sapi_name() !== "cli" && $_SERVER["REQUEST_METHOD"] !== "POST") {
|
||||
$this->redirectNotFound();
|
||||
if (php_sapi_name() !== 'cli' && $_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
$this->sendErrorResponse("Not Found", 404);
|
||||
}
|
||||
}
|
||||
|
||||
protected function redirectNotFound(): void
|
||||
{
|
||||
header("Location: /404", true, 302);
|
||||
exit();
|
||||
}
|
||||
|
||||
protected function fetchFromPostgREST(
|
||||
string $endpoint,
|
||||
string $query = "",
|
||||
string $method = "GET",
|
||||
?array $body = null
|
||||
): array {
|
||||
$url = "{$this->postgrestUrl}/{$endpoint}?{$query}";
|
||||
$options = [
|
||||
"headers" => [
|
||||
"Content-Type" => "application/json",
|
||||
"Authorization" => "Bearer {$this->postgrestApiKey}",
|
||||
],
|
||||
];
|
||||
|
||||
if ($method === "POST" && $body) $options["json"] = $body;
|
||||
|
||||
$response = (new Client())->request($method, $url, $options);
|
||||
|
||||
return json_decode($response->getBody(), true) ?? [];
|
||||
}
|
||||
|
||||
protected function sendResponse(string $message, int $statusCode): void
|
||||
{
|
||||
http_response_code($statusCode);
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode(["message" => $message]);
|
||||
exit();
|
||||
}
|
||||
|
||||
protected function sendErrorResponse(string $message, int $statusCode): void
|
||||
{
|
||||
$this->sendResponse($message, $statusCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,60 +16,71 @@ abstract class BaseHandler
|
|||
public function __construct()
|
||||
{
|
||||
$this->loadEnvironment();
|
||||
$this->initializeCache();
|
||||
}
|
||||
|
||||
private function loadEnvironment(): void
|
||||
{
|
||||
$this->postgrestUrl =
|
||||
$_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL") ?: "";
|
||||
$this->postgrestApiKey =
|
||||
$_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY") ?: "";
|
||||
$this->postgrestUrl = $_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL") ?? "";
|
||||
$this->postgrestApiKey = $_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY") ?? "";
|
||||
}
|
||||
|
||||
protected function makeRequest(
|
||||
string $method,
|
||||
string $endpoint,
|
||||
array $options = []
|
||||
): array {
|
||||
protected function initializeCache(): void
|
||||
{
|
||||
if (class_exists("Redis")) {
|
||||
try {
|
||||
$redis = new \Redis();
|
||||
$redis->connect("127.0.0.1", 6379);
|
||||
$this->cache = $redis;
|
||||
} catch (\Exception $e) {
|
||||
error_log("Redis connection failed: " . $e->getMessage());
|
||||
$this->cache = null;
|
||||
}
|
||||
} else {
|
||||
error_log("Redis extension not found — caching disabled.");
|
||||
$this->cache = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function makeRequest(string $method, string $endpoint, array $options = []): array
|
||||
{
|
||||
$client = new Client();
|
||||
$url = rtrim($this->postgrestUrl, "/") . "/" . ltrim($endpoint, "/");
|
||||
|
||||
try {
|
||||
$response = $client->request(
|
||||
$method,
|
||||
$url,
|
||||
array_merge($options, [
|
||||
"headers" => [
|
||||
"Authorization" => "Bearer {$this->postgrestApiKey}",
|
||||
"Content-Type" => "application/json",
|
||||
],
|
||||
])
|
||||
);
|
||||
$response = $client->request($method, $url, array_merge_recursive([
|
||||
"headers" => [
|
||||
"Authorization" => "Bearer {$this->postgrestApiKey}",
|
||||
"Content-Type" => "application/json",
|
||||
]
|
||||
], $options));
|
||||
|
||||
$responseBody = $response->getBody()->getContents();
|
||||
|
||||
if (empty($responseBody)) return [];
|
||||
|
||||
$responseData = json_decode($responseBody, true);
|
||||
$data = json_decode($responseBody, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new \Exception("Invalid JSON: " . json_last_error_msg());
|
||||
}
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) throw new \Exception("Invalid JSON response: {$responseBody}");
|
||||
|
||||
return $responseData;
|
||||
return $data;
|
||||
} catch (RequestException $e) {
|
||||
$response = $e->getResponse();
|
||||
$statusCode = $response ? $response->getStatusCode() : "N/A";
|
||||
$responseBody = $response
|
||||
? $response->getBody()->getContents()
|
||||
: "No response body";
|
||||
$statusCode = $response ? $response->getStatusCode() : 'N/A';
|
||||
$responseBody = $response ? $response->getBody()->getContents() : 'No response';
|
||||
|
||||
throw new \Exception(
|
||||
"Request to {$url} failed with status {$statusCode}. Response: {$responseBody}"
|
||||
);
|
||||
throw new \Exception("HTTP {$method} {$url} failed with status {$statusCode}: {$responseBody}");
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception("Request to {$url} failed: " . $e->getMessage());
|
||||
throw new \Exception("Request error: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function fetchFromApi(string $endpoint, string $query = ""): array
|
||||
{
|
||||
$url = $endpoint . ($query ? "?{$query}" : "");
|
||||
return $this->makeRequest("GET", $url);
|
||||
}
|
||||
|
||||
protected function sendResponse(array $data, int $statusCode = 200): void
|
||||
{
|
||||
http_response_code($statusCode);
|
||||
|
@ -78,52 +89,8 @@ abstract class BaseHandler
|
|||
exit();
|
||||
}
|
||||
|
||||
protected function sendErrorResponse(
|
||||
string $message,
|
||||
int $statusCode = 500
|
||||
): void {
|
||||
protected function sendErrorResponse(string $message, int $statusCode = 500): void
|
||||
{
|
||||
$this->sendResponse(["error" => $message], $statusCode);
|
||||
}
|
||||
|
||||
protected function fetchFromApi(string $endpoint, string $query): array
|
||||
{
|
||||
$client = new Client();
|
||||
$url =
|
||||
rtrim($this->postgrestUrl, "/") .
|
||||
"/" .
|
||||
ltrim($endpoint, "/") .
|
||||
"?" .
|
||||
$query;
|
||||
|
||||
try {
|
||||
$response = $client->request("GET", $url, [
|
||||
"headers" => [
|
||||
"Content-Type" => "application/json",
|
||||
"Authorization" => "Bearer {$this->postgrestApiKey}",
|
||||
],
|
||||
]);
|
||||
|
||||
if ($response->getStatusCode() !== 200) throw new Exception("API call to {$url} failed with status code " . $response->getStatusCode());
|
||||
|
||||
return json_decode($response->getBody(), true);
|
||||
} catch (RequestException $e) {
|
||||
throw new Exception("Error fetching from API: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected function initializeCache(): void
|
||||
{
|
||||
if (class_exists("Redis")) {
|
||||
$redis = new \Redis();
|
||||
try {
|
||||
$redis->connect("127.0.0.1", 6379);
|
||||
$this->cache = $redis;
|
||||
} catch (Exception $e) {
|
||||
error_log("Redis connection failed: " . $e->getMessage());
|
||||
$this->cache = null;
|
||||
}
|
||||
} else {
|
||||
$this->cache = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue