MagratheaPHP2
Up to date Narrative last written —; no source changes since. Method signatures below are reflected live.

MagratheaApi — RESTful API Framework

File: src/MagratheaApi.php Namespace: Magrathea2

The central class for building RESTful APIs. Handles routing, CORS, request parsing, response formatting, JWT authorization, and caching. The recommended entry point for any API-first application.


Quick Start

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Magrathea2\MagratheaPHP;
use Magrathea2\MagratheaApi;

MagratheaPHP::LoadVendor();
MagratheaPHP::Instance()->AppPath(__DIR__)->Prod()->Load()->Connect();

$api = new MagratheaApi();
$api->AllowAll();

$api->Add("GET", "/ping", null, function() {
    return ["status" => "ok"];
});

$api->Run();

Properties

PropertyTypeDescription
$controlstringDefault control class
$actionstringDefault action
$paramsarrayRequest parameters
$returnRawboolWhether to skip JSON encoding
$apiAddress?stringBase API path prefix
$authClass?MagratheaApiAuthAuthorization class
$baseAuth?stringDefault auth method name
$endpointsarrayAll registered routes
$fallbackcallable|nullFallback for unmatched routes

Configuration Methods

SetAddress(string $addr): MagratheaApi

Set a base path prefix for all routes (e.g., /api/v1).

$api->SetAddress("/api/v1");
// Routes like "/users" become "/api/v1/users"

GetAddress(): string|null

Returns the current base address.

AllowAll(): MagratheaApi

Set Access-Control-Allow-Origin: * (CORS open to all origins).

$api->AllowAll();

Allow(array $allowedOrigins): MagratheaApi

Restrict CORS to specific origins.

$api->Allow(["https://myapp.com", "https://admin.myapp.com"]);

DisableCache(): MagratheaApi

Send Cache-Control: no-cache headers.

AddAcceptHeaders(string|array $accept): void

Append allowed request headers.

$api->AddAcceptHeaders(["X-Api-Key", "X-Custom-Header"]);

AcceptHeaders(?array $headers): void

Set the full list of accepted request headers.

SetRaw(): MagratheaApi

Disable JSON encoding of responses — return raw output.

BaseAuthorization(MagratheaApiControl $authClass, ?string $function): MagratheaApi

Set a default authorization check applied to all protected routes.

$api->BaseAuthorization(new AuthControl(), "ValidateToken");

Registering Endpoints

Add(string $method, string $url, ?MagratheaApiControl $control, string|callable $function, string|bool $auth = false, ?string $description = null): MagratheaApi

Register a single route.

ParameterDescription
$methodHTTP verb: "GET", "POST", "PUT", "DELETE", "PATCH"
$urlRoute pattern, supports {param} placeholders
$controlController instance (null for closure-only routes)
$functionMethod name string or a callable (closure)
$authfalse = no auth, true = use base auth, string = named auth method
$descriptionOptional route description (shown in API explorer)
// Closure route
$api->Add("GET", "/hello", null, function() {
    return ["message" => "Hello!"];
});

// Controller method
$api->Add("GET", "/users", new UserApiControl(), "List");
$api->Add("GET", "/users/{id}", new UserApiControl(), "Read");
$api->Add("POST", "/users", new UserApiControl(), "Create", true); // auth required

// Route with description
$api->Add("DELETE", "/users/{id}", new UserApiControl(), "Delete", true,
    "Delete a user by ID (requires admin token)");

Crud(string|array $url, MagratheaApiControl $control, string|bool $auth = false): MagratheaApi

Registers a full CRUD suite for a resource in one call:

MethodRouteController Method
GET/resourceList()
GET/resource/{id}Read($params)
POST/resourceCreate($data)
PUT/resource/{id}Update($params)
DELETE/resource/{id}Delete($params)
$api->Crud("/products", new ProductApiControl());

// With auth on all CRUD methods:
$api->Crud("/products", new ProductApiControl(), true);

Crud() always registers Update under PUT, never PATCH — if you also want a PATCH route for the same resource/handler, register it yourself with Add():

$api->Crud("/products", new ProductApiControl());
$api->Add("PATCH", "/products/{id}", new ProductApiControl(), "Update", true);

Both PUT and PATCH bodies are read the same way in a controller — GetPut() (or its alias GetPatch()) returns the decoded body regardless of which of the two verbs was used.

Fallback(callable $fn): MagratheaApi

Register a fallback handler for routes that don't match anything.

$api->Fallback(function() {
    return ["error" => "Route not found"];
});

HealthCheck(bool $checkDatabase = false): void

Registers a GET /health-check endpoint that always returns health and time.

When $checkDatabase is true, it also checks DB connectivity and adds database with "ok" or "fail".

$api->HealthCheck();
// {"health":"ok","time":"2026-07-20 10:00:00"}

$api->HealthCheck(true);
// {"health":"ok","time":"2026-07-20 10:00:00","database":"ok"}

Running the API

Run(bool $returnRaw = false): mixed

Matches the incoming request to a route, calls the controller/closure, and outputs the JSON response.

$api->Run();

ExecuteUrl(string $fullUrl, string $method = "GET"): mixed

Manually execute a URL against this API (useful for internal subrequests or tests).

$result = $api->ExecuteUrl("/products/1", "GET");

Response Helpers

These are typically called from within controllers, but can also be called directly.

Json(array|object $response, int $code = 200): mixed

Output a JSON response with an HTTP status code.

$api->Json(["error" => "Not found"], 404);

ReturnSuccess(mixed $data): mixed

Return a standardized success response:

{"success": true, "data": ...}

If $data is a MagratheaPagination instance, a paginated envelope is returned instead:

{"success": true, "data": [...], "page": 0, "count": 20, "has_more": true, "total": 143}

total is only included when it was computed (see MagratheaModelControl::GetPagination()). Just return a MagratheaPagination from a controller action — no other code changes needed:

public function List(array $params = []): MagratheaPagination {
    $query = Query::Select()->Obj(new Article())->Where(["published" => 1])->Order("created_at DESC");
    return ArticleControl::GetPagination($query, page: (int)($params["page"] ?? 0), limit: 20);
}

ReturnFail(mixed $data): mixed

Return a standardized failure response:

{"success": false, "data": ...}

ReturnError(int $code = 500, string $message = "", mixed $data = null, int $status = 200): mixed

Return a standardized error response.

$api->ReturnError(401, "Unauthorized");

Return404(): mixed

Return a 404 response.

ReturnApiException(MagratheaApiException $exception): mixed

Return an error response derived from an exception.

Cache(array $data): void

Store and immediately return a cached response.


Endpoint Introspection

GetEndpoints(): array

Returns all registered endpoints grouped by URL and method.

GetEndpointsDetail(): array

Returns detailed endpoint info including descriptions.

$endpoints = $api->GetEndpoints();
// Used by the Admin API Explorer feature

Debug Mode

Debug(): MagratheaApi

Enable endpoint debugging — outputs route resolution info.

$api->Debug()->Run();

URL Parameter Parsing

Route parameters defined with {param} are passed to the controller method:

$api->Add("GET", "/users/{id}/orders/{orderId}", new OrderControl(), "GetByUser");

// In OrderControl:
public function GetByUser(array $params): array {
    $userId  = $params["id"];
    $orderId = $params["orderId"];
    // ...
}

Full Example: Products API

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Magrathea2\MagratheaPHP;
use Magrathea2\MagratheaApi;
use App\Api\ProductApiControl;
use App\Api\AuthControl;

MagratheaPHP::LoadVendor();
MagratheaPHP::Instance()
    ->AppPath(__DIR__)
    ->AddCodeFolder("models", "controls", "api")
    ->Prod()
    ->Load()
    ->Connect();

$api = new MagratheaApi();

$api->Allow(["https://myapp.com"])
    ->SetAddress("/api/v1")
    ->BaseAuthorization(new AuthControl(), "ValidateToken")
    ->DisableCache();

// Public endpoints
$api->Add("GET",  "/products",     new ProductApiControl(), "List");
$api->Add("GET",  "/products/{id}", new ProductApiControl(), "Read");

// Protected endpoints
$api->Add("POST",   "/products",      new ProductApiControl(), "Create", true);
$api->Add("PUT",    "/products/{id}", new ProductApiControl(), "Update", true);
$api->Add("DELETE", "/products/{id}", new ProductApiControl(), "Delete", true);

$api->HealthCheck();

$api->Run();

Notes

Class Reference — MagratheaApi

Magrathea2\MagratheaApi /home/platypusweb/platypusweb.com.br/site/magratheaphp2/src/MagratheaApi.php

Creates and manages a RESTful API server. This class is responsible for routing requests, handling authorization, and returning JSON responses.

AcceptHeaders(?array $headers = null)

Sets the `Access-Control-Allow-Headers` CORS header.

ParamTypeDefault
$headers ?array null
Add(string $method, string $url, ?Magrathea2\MagratheaApiControl $control, callable|string $function, string|bool $auth = false, ?string $description = null): Magrathea2\MagratheaApi

Adds a custom endpoint to the API.

ParamTypeDefault
$method string required
$url string required
$control ?Magrathea2\MagratheaApiControl required
$function callable|string required
$auth string|bool false
$description ?string null
AddAcceptHeaders($accept)

Adds a header to the list of accepted headers for CORS.

ParamTypeDefault
$accept mixed required
Allow(array $allowedOrigins): Magrathea2\MagratheaApi

Includes CORS headers to allow requests from a specific list of origins.

ParamTypeDefault
$allowedOrigins array required
AllowAll(): Magrathea2\MagratheaApi

Includes CORS headers to allow requests from any origin.

BaseAuthorization(Magrathea2\MagratheaApiControl $authClass, ?string $function): Magrathea2\MagratheaApi

Defines the base authorization handler.

ParamTypeDefault
$authClass Magrathea2\MagratheaApiControl required
$function ?string required
Cache($data)

Handles caching for the API response.

ParamTypeDefault
$data mixed required
Crud(array|string $url, Magrathea2\MagratheaApiControl $control, string|bool $auth = false): Magrathea2\MagratheaApi

Adds a standard set of CRUD (Create, Read, Update, Delete) endpoints for a model.

ParamTypeDefault
$url array|string required
$control Magrathea2\MagratheaApiControl required
$auth string|bool false
Debug(): Magrathea2\MagratheaApi

Prints a debug view of all registered endpoints.

DisableCache(): Magrathea2\MagratheaApi

Sets headers to disable browser and proxy caching.

ExecuteUrl($fullUrl, $method = "GET")

Finds the matching endpoint for a given URL and method, and executes it.

ParamTypeDefault
$fullUrl mixed required
$method mixed "GET"
Fallback($fn): Magrathea2\MagratheaApi

Sets a fallback function to be called when no route matches the request.

ParamTypeDefault
$fn mixed required
GetAddress(): ?string

Gets the base address of the API.

GetEndpoints(): array

Gets a structured array of all registered endpoints, grouped by control class.

GetEndpointsDetail()

Gets a detailed list of all endpoints, grouped by URL.

HealthCheck(bool $checkDatabase = false)

Creates a simple `/health-check` endpoint.

ParamTypeDefault
$checkDatabase bool false
Json($response, int $code = 200)

Outputs a JSON response and terminates the script.

ParamTypeDefault
$response mixed required
$code int 200
ReturnApiException($exception)

Formats and returns a MagratheaApiException as a JSON response.

ParamTypeDefault
$exception mixed required
ReturnError($code = 500, $message = "", $data = null, $status = 200)

Returns a generic JSON error response.

ParamTypeDefault
$code mixed 500
$message mixed ""
$data mixed null
$status mixed 200
ReturnFail($data)

Returns a failure JSON response.

ParamTypeDefault
$data mixed required
ReturnSuccess($data)

Returns a successful JSON response. If $data is a MagratheaPagination, builds a paginated envelope instead ({success, data, page, count, has_more, total?}).

ParamTypeDefault
$data mixed required
Run($returnRaw = false)

Starts the API, processes the request, and returns the response.

ParamTypeDefault
$returnRaw mixed false
SetAddress($addr): Magrathea2\MagratheaApi

Sets the base address for the API.

ParamTypeDefault
$addr mixed required
SetRaw(): Magrathea2\MagratheaApi

Configures the API to return the raw result instead of a JSON-encoded response.

Start(): Magrathea2\MagratheaApi

Start the server, getting base calls

__construct()

Constructor. Initializes the endpoint arrays for different HTTP methods.

Examples