Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.

projection

Projection is for building JSON responses that show only the fields a particular audience should see. For example, a public issue list might include a title and status, while an internal audit view can also include private notes. This module lets you name those field lists once and reuse them when rendering responses.

import projection backs the json ... projected by ... mapping form. A ProjectionPolicy names the allowed fields for one response surface; the FieldProjection helper writes JSON values only when the field is allowed.

Mental model

A response surface has a single visibility policy: the audit log gets a different set of fields than the public API, even when both render the same row type. A ProjectionPolicy makes that visibility list addressable: the same row type can flow through multiple policies.

import projection

let public_field_policy = projection.projection_policy(
    "public",
    "issue",
    "list",
    None,
    ["id", "title", "severity", "created_at"])

let audit_field_policy = projection.projection_policy(
    "audit",
    "issue",
    "list",
    Some("audit.read"),
    ["id", "title", "severity", "created_at", "private_notes", "actor_id"])
FieldMeaning
nameStable policy id used in artifacts and tests.
targetDomain type the policy describes (e.g. "issue").
surfaceResponse surface ("list", "detail", "export", etc.).
capabilityOptional gate, e.g. Some("audit.read").
fieldsThe allow-list of field names.

Applying a projection

import projection

let projector = projection.field_projection_for(public_field_policy)
let body = Json.empty_object()
projector.set_str(body, "id", row.id)
projector.set_str(body, "title", row.title)
projector.set_int(body, "created_at", row.created_at)

FieldProjection exposes typed set_* helpers (set_str, set_int, set_bool, set_array, set_object, set_object_as, set_nullable_str) plus bulk helpers (project_str_fields, project_int_fields, project_object_alias_fields, project_json_fields) for code that builds an object from parallel arrays.

projection_policy_json(policy) returns the policy as a JSON object, which is what release artifacts ship.

Using projections in a json declaration

json issue_summary from IssueRow as row projected by public_field_policy {
    id: row.id
    title: row.title
    severity: row.severity
    private_notes? if has_capability(ctx, "audit.read"): row.private_notes
}

The projected by clause is the allow-list; per-field markers (?, ?always, if expr) decide whether allowed fields appear in a specific response. A field not in the policy is omitted regardless of marker.