A HAL document can tell a client where to go but not how to submit a change. What does the Siren media type add with its actions array, and what does the HAL-FORMS extension do about the same gap?
answer
- links = where; actions and _templates = how
- Siren: class, properties, entities, links, actions
- action: name, method, href, type, fields
- HAL-FORMS: _templates with contentType, method, properties
- only pays with a generic consumer
basics
~20 sSiren entities carry an actions array where each action names itself and declares method, href, request content type, and a list of fields with names and types - enough for a client to render and submit a form. HAL-FORMS adds an equivalent _templates member to HAL documents.
solid answer
~50 sPlain links are underspecified for writes: they give a URL and a relation, leaving method, content type and payload shape to out-of-band documentation. Siren fixes that. A Siren entity has class, properties, entities (sub-entities, linked or embedded), links, and actions. Each action carries name (the identifier the client looks up), title, method, href, type - the request content type - and fields, each with name, type and optionally value. A generic client can render a form straight from that, submit it, and never hardcode a route. HAL-FORMS reaches the same place from the HAL side with a _templates member holding method, contentType and properties, under its own media type. Spring HATEOAS can emit HAL, HAL-FORMS and Siren via configuration. The payoff is real only when something generic consumes it - admin consoles, workflow tools, machine agents. For a hand-built frontend shipped with the API, the extra ceremony is usually dead weight.
code
json · 13 lines{
"class": ["order"],
"properties": { "orderNumber": 42, "status": "PENDING" },
"actions": [
{ "name": "cancel-order",
"title": "Cancel order",
"method": "POST",
"href": "/orders/42/cancel",
"type": "application/json",
"fields": [ { "name": "reason", "type": "text" } ] }
],
"links": [ { "rel": ["self"], "href": "/orders/42" } ]
}go deeper
Know that some hypermedia formats describe actions, not just links, and that plain HAL only has links.
Name Siren's action members - method, href, type, fields - and mention HAL-FORMS templates as the HAL-side answer.
Judge when action metadata earns its keep, and note the validation-duplication and flat-field-type limitations.
Frame it as a client-population decision: generic or independently evolving consumers justify it, lockstep bespoke UIs do not, and the thin ecosystem is a real cost.
## The gap in link-only formats A link relation and an href answer where. They do not answer: which method, what content type, which fields, which of them are required, what types they take. In practice that knowledge is in the API documentation and therefore compiled into the client - which is precisely the coupling hypermedia was meant to remove. A client can follow a cancel link only because a human told it to POST an empty body. ## Siren's model Siren describes an **entity**, which has: - **class** - an array of strings naming the entity's kind, for example order - **properties** - the entity's own state - **entities** - sub-entities, either embedded representations or embedded links, each carrying its own rel - **links** - the familiar rel plus href navigational links - **actions** - the distinguishing feature An **action** contains name (a client-facing identifier, unique within the entity), optional class and title, method (defaulting to GET), href, type (the request media type, defaulting to form encoding), and fields. Each **field** has a name, a type drawn from the HTML5 input types, and optionally a value and title. That is enough for a client to build a form: label from title, control from type, submit target from href and method, encoding from type. The client's only real knowledge is what an action called cancel-order means - the mechanics are all in the document. ## HAL-FORMS HAL-FORMS keeps HAL's _links and _embedded and adds **_templates**, a map from template name (there is a conventional default name) to an object with contentType, method, and properties, where each property has a name and may declare required, readOnly, regex, prompt and more. It has its own media type so a client can ask for it explicitly rather than guessing whether templates will be present. The important difference from Siren is trajectory rather than capability: HAL-FORMS is an extension you can adopt incrementally on top of an existing HAL API, while Siren is a different document model. ## When action descriptions pay They pay when the consumer is generic: an internal admin console that renders any resource it is pointed at, a workflow engine driving a multi-step process, an integration partner who would otherwise need a code change for every new step, or an agent traversing the API without a compiled client. In those settings the server can add a whole new step to a workflow and existing clients render it. They do not pay when the consumer is a bespoke UI released alongside the API. That client's designers have already decided what the Cancel button looks like and what confirmation it shows; the server's field descriptors are ignored, and you are paying payload and serializer complexity for nothing. ## The honest downsides The ecosystems are small. Tooling, documentation generators and client libraries are far thinner than for plain JSON or OpenAPI, so you write more of the stack yourself. Field types are drawn from the HTML input vocabulary, which is a poor fit for structured or nested payloads - describing a nested object graph in a flat field list gets awkward fast. And validation rules expressed in a form template inevitably duplicate the server's real validation, so they must be generated from the same source or they will drift. ## The interview point Be able to say: links describe navigation, actions and templates describe writes; Siren has actions natively, HAL needs the HAL-FORMS extension; and the value is entirely a function of whether a generic client is on the other end.
- Does describing fields in an action mean the server can skip validating the submission?No. The action description is a rendering hint that travels to the client and can be ignored or altered. The server must validate every submitted payload as if the descriptors had never been sent, and ideally the descriptors are generated from the same constraint definitions the validator uses so they cannot drift apart.
saying these in an interview costs you the question
- Claiming plain HAL can describe HTTP methods and form fields
- Trusting client-side field descriptors as a substitute for server validation
- Adopting Siren for a bespoke first-party UI that ignores the action metadata
- Assuming action field types can express arbitrarily nested request bodies