Mars development
Develop REST APIs with MARS-Curiosity (Delphi REST library) - writing resources, REST attributes, parameter binding, JWT authentication and roles, FireDAC dataset publishing, server-sent events (SSE), WebStencils HTML templating, client components, configuration, serialization. Use this skill whenever the user is working in a Delphi project that uses MARS (units named MARS.*, Server.Ignition, Server.Resources.*), asks how to add or modify REST endpoints, secure endpoints with tokens/roles, expose datasets, push events to clients, render server-side HTML, consume a MARS server from a client, handle errors, or configure a MARS server - even if they don't mention MARS by name but the code clearly uses it.From its SKILL.md
npx -y skills add andrea-magni/MARS --skill mars-developmentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
6.0 KB, as published. Nobody here has run it
Developing with MARS-Curiosity
MARS (https://github.com/andrea-magni/MARS) maps HTTP requests onto plain Delphi classes via attributes and RTTI. Runtime model:
- Engine (
IMARSEngine, usuallyTServerEngine.DefaultinServer.Ignition.pas): owns HTTP-level config (port, base path/rest, CORS, compression) and one or more Applications added withAddApplication('DefaultApp', '/default', ['Server.Resources.*'])— the third argument is a list of unit-name masks selecting which registered resources belong to the app. - Resources: classes annotated with
[Path('...')], registered viaMARSRegister(TMyResource)(orMARSRegister([TResA, TResB]), orTMARSResourceRegistry.Instance.RegisterResource<TMyResource>) in the unitinitialization. A new instance is created per request and freed afterwards. - Activation (
IMARSActivation): per-request context (request, response, token, URL...). Injectable anywhere with[Context]. - URL = engine BasePath + app path + resource
[Path]+ method[Path]:/rest/default/customers/123.
Minimal resource
unit Server.Resources.Customers;
interface
uses
SysUtils, Classes
, MARS.Core.Attributes, MARS.Core.MediaType, MARS.Core.JSON;
type
TCustomer = record
Id: Integer;
Name: string;
end;
[Path('customers'), Produces(TMediaType.APPLICATION_JSON)]
TCustomersResource = class
public
[GET]
function List([QueryParam] search: string): TArray<TCustomer>;
[GET, Path('{id}')]
function GetById([PathParam] id: Integer): TCustomer;
[POST, Consumes(TMediaType.APPLICATION_JSON)]
function Add([BodyParam] ACustomer: TCustomer): TCustomer;
end;
implementation
uses
MARS.Core.Registry;
// ... method bodies ...
initialization
MARSRegister(TCustomersResource);
end.
Records, arrays of records, objects, TJSONObject/TJSONArray, strings, numbers, streams and datasets are serialized automatically by the MessageBodyWriter registry; same in reverse for [BodyParam] via MessageBodyReaders. No manual JSON code needed for plain data.
Returned objects (class instances) are freed by MARS after writing the response. Mark the method [IsReference] when returning a shared/long-lived instance that must NOT be freed.
Raise EMARSHttpException.Create('Not found', 404) for error statuses; raise EMARSWithResponseException to return a structured (JSON) error body. Both are in MARS.Core.Exceptions. Exceptions raised while binding parameters (custom MessageBodyReaders included) keep their status if they are EMARSHttpException, otherwise they become a 500: the built-in JSON readers use this to answer 400 when the request body is missing or malformed.
Reference files — read the one matching the task
references/attributes.md— complete attribute catalog (HTTP methods,Path,Produces/Consumes, all*Parambinding attributes,Context, config params, authorization, invocation events, response shaping). Read when writing or reviewing resource declarations.references/authentication.md— JWT tokens,TMARSTokenResourcelogin endpoint,Authenticateoverride,[RolesAllowed]/[PermitAll]/[DenyAll],[Context] Token: TMARSToken, JWT ini parameters. Read for anything auth/security related.references/firedac.md— publishing datasets withTMARSFDDatasetResource+[SQLStatement], ad-hoc queries with[Context] FD: TMARSFireDAC, connection defs from ini, macro/param injection, applying deltas. Read for database endpoints.references/client.md— consuming a MARS server:TMARSNetClient/TMARSIndyClient,TMARSClientApplication, typed client resources,TMARSClientToken, sync/async calls,EMARSClientHttpException. Read when writing Delphi client code.references/configuration.md— ini file structure, engine/application parameters (port, CORS, compression, SSL, JWT, OpenAPI info, FireDAC), reading params in code,[EngineParam]/[ApplicationParam]injection.references/sse.md— server-sent events:TMARSServerSideEventendpoints with worker procs,text/event-stream, client-sideTMARSClientResourceSSE. Read for push/streaming/live-update endpoints.references/webstencils.md— server-side HTML with WebStencils (Delphi 12.2+):[Context] TMARSWebStencils,ContentFromFile,AddVarValue/AddDataVar, template folders. Read for HTML-rendering endpoints (also htmx-style apps).
For hosting/deployment (Windows service, ISAPI, Apache, FastCGI, Linux daemon, HTTPS) see references/deployment.md in the companion skill mars-new-project.
Conventions worth keeping
- One resource per unit, unit named
Server.Resources.<Topic>, so the standard'Server.Resources.*'mask finds it; remember to add new units to the .dpr uses clause, otherwise the unit'sinitializationnever runs and the resource is silently missing. - Prefer attribute-driven binding over reading
IMARSRequestmanually; inject what you need with[Context]. - Working demos for most features live in
Demos/in the MARS repo:MARSTemplate(baseline),TokenRenew(JWT+roles),OTPDemo(FireDAC+auth),ErrorObjects(structured errors),SSEDemo(server-sent events),HtmxDemo,WebStencilsDemo. When unsure about an API, check the corresponding demo or the source unit inSource/— it is the ground truth.