WIP - Web/Service/Rest/TRestService - Service provider with TRestResources - #1155
Draft
belisoful wants to merge 7 commits into
Draft
WIP - Web/Service/Rest/TRestService - Service provider with TRestResources#1155belisoful wants to merge 7 commits into
belisoful wants to merge 7 commits into
Conversation
belisoful
marked this pull request as ready for review
May 29, 2026 08:32
Member
Author
|
There needs to be some Strong critique of this before agreeing to merge. Anyone who is interested should see how this implements Rest in the code and comment |
belisoful
marked this pull request as draft
June 1, 2026 04:06
- TRestService rejects AllowCredentials combined with the wildcard AllowOrigin instead of reflecting arbitrary request origins; validated at init() and again in sendCorsHeaders(). - Requests outside BasePath now return 404 instead of matching routes without the prefix; the bare base path resolves to the root path. - 405 responses carry the RFC 7231 Allow header listing the verbs the matched resource supports. - Preflight-only CORS headers (Allow-Methods, Allow-Headers, Max-Age) are emitted only for OPTIONS requests. - TRestResource::validate() throws TConfigurationException for unknown rule names instead of silently skipping them. - TRestResource::query()/input()/hasInput() read true query-string parameters via a getQueryParams() seam instead of THttpRequest's merged parameter map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branch introduces 4 TRest* classes, a self-contained REST API layer for PRADO intended as the backend for single-page applications. It is a standalone TService that runs alongside the existing TPageService / TJsonService / TRpcService family.
The new namespace contains four classes:
Configuration accepts both XML and PHP-array forms. Inline entries can be grouped under a prefix, with enabled accepting boolean-ish values plus the special string "Debug" (active only in TApplicationMode::Debug). A groupfile splits one group's resources into its own file; a service-level configfile moves the entire tree into a separate file, with inline entries appended afterwards.
TRestService
TRestService maintains its own route table independent of TUrlMapping.
Each compiles to a named-capture regular expression — {name} placeholders become (?P(?:constraint)), where the inner non-capturing group lets user-supplied alternations like \d+|new coexist safely with the named capture. Per-parameter regex constraints are declared with attributes such as parameters.id="\d+", defaulting to [^/]+.
The lifecycle through run() is short: CORS headers (and a short-circuit on OPTIONS preflight) → strip BasePath from PATH_INFO → match against the compiled table in declaration order → instantiate the TRestResource subclass, apply any extra XML attributes as properties, inject path parameters → call authorize() → dispatch to the do…() method picked from the verb and route shape → JSON-encode the return value at the resource's chosen status code. HEAD and 204 responses suppress the body; any TRestException (or other Throwable) is converted to a JSON error envelope.
TRestResource
TRestResource is the abstract base every concrete resource extends.
It uses __call rather than typed stubs for the six convention methods so subclasses can declare any signature they need — path parameters become method parameters by name (doShow(string $id)), and any convention method the subclass does not override automatically yields 405 Method Not Allowed. Request bodies are parsed lazily on first access: JSON for application/json, $_POST for form-encoded POST, and php://input via parse_str for form-encoded PUT / PATCH (PHP does not populate $_POST for non-POST verbs).
The validation DSL accepts pipe-delimited rule strings — required, nullable, string, integer, float, numeric, boolean, array, email, url, min:N, max:N, in:a,b,c — applies type coercion where appropriate, and throws 422 Unprocessable Entity with field-level errors on failure.
Status helpers (created() / accepted() / noContent()) set the response code while still returning a value, and exception helpers (notFound() / unauthorized() / forbidden() / conflict() / unprocessable() / abort()) raise a properly-typed TRestException.
Routing classifies routes as item vs. collection based on whether the final path segment is a {param} and pairs that shape with the HTTP verb to pick the resource method; path parameters are injected by name via PHP reflection.
CORS is built in — preflight OPTIONS returns 204, credentialed wildcard origins reflect the request Origin, and Vary: Origin is emitted on non-wildcard origins. Every error — routing failures, method mismatches, thrown TRestException instances, and uncaught exceptions — is serialised as {status, title, detail?, errors?}; ExposeErrors (defaulting on in Debug) controls whether 500 details leak.