ReadHandler#

com.palmyralabs.palmyra.handlers.ReadHandler

Single-record read endpoint. Returns one object identified by the {id} path placeholder — the primary key of the table mapped through @CrudMapping.type.

Request / response shape#

  • HTTP: GET <secondaryMapping> — e.g. GET /api/masterdata/industrySector/42.
  • Request body: none.
  • Response body: a single JSON object carrying every attribute declared on the model class from @CrudMapping.type, minus any field flagged DropMode.OUTGOING. Not wrapped — just the object.
{
  "id": 42,
  "name": "Health Care",
  "code": "HC",
  "createdAt": "2026-04-01T09:12:00Z"
}

Internally the endpoint operates from a FilterCriteria / QueryFilter split (similar to QueryHandler but narrowed to a single-row lookup).

Methods#

Method Signature
aclCheck int aclCheck(HandlerContext ctx)
preApplyCriteria void preApplyCriteria(FilterCriteria criteria, HandlerContext ctx) — default copies ctx.getParams() into the criteria
applyFilter QueryFilter applyFilter(QueryFilter filter, HandlerContext ctx)
onQueryResult Tuple onQueryResult(Tuple tuple, Action action)

Example#

@Component
@CrudMapping(value = "/v1/admin/user/{id}", type = User.class)
public class UserReadHandler implements ReadHandler {

    @Autowired
    private UserProvider userProvider;

    @Override
    public int aclCheck(HandlerContext ctx) {
        return userProvider.hasRole("USER_READ") ? 0 : -1;
    }

    @Override
    public void preApplyCriteria(FilterCriteria criteria, HandlerContext ctx) {
        ReadHandler.super.preApplyCriteria(criteria, ctx);
        criteria.addAttribute("requestedBy", userProvider.getUserId());
    }

    @Override
    public QueryFilter applyFilter(QueryFilter filter, HandlerContext ctx) {
        // restrict to records owned by the calling user
        filter.addCondition("userId", userProvider.getUserId());
        return filter;
    }

    @Override
    public Tuple onQueryResult(Tuple tuple, Action action) {
        // strip sensitive columns before returning
        tuple.remove("passwordHash");
        return tuple;
    }
}