跳转到内容

模板的上下文

当您生成代码时,Restorm 会把 您的整个设计 以一个 ctx 对象的形式传给 模板。您的模型、您的枚举、您的路由,尤其是 它们的意图(searchable、PII、 cache,以及模型的整个运行画像:volumetry、accessPattern、traffic、freshness、 sensitivity、retention)都在其中 —— 模板读取它们来决定生成什么。为此不需要一个 变量:您已经在设计中输入的信息可以直接使用。

一个属性的 Code generation 标签页:它的标志和被模板读取的变量

ctx
├─ design # name, version, description, basePath, defaultAuth, vars
├─ enums[] # name, description, values[]
├─ models[] # name, description, inherits, identifier, timestamps, softDelete,
│ # volumetry, accessPattern, traffic, freshness, sensitivity,
│ # retention, properties[], allProperties[], examples[], vars
└─ groups[] # name, basePath, versionPrefix, headers[], routes[]
└─ routes[] # method, path, fullPath, params[], body, responses[],
# auth, pagination, cacheSeconds, idempotent, deprecated, vars

引用通过名称进行(从不通过内部标识符):property.enum 是枚举的名称, property.references.model 是所指向模型的名称,model.inherits 是父级的名称。 在一个模型上,properties[] 列出它 自有的 属性(用于类型声明),而 allProperties[] 列出 自有 + 继承、被展平的 属性(用于一个完整实例:示例 数据、SQL 列、请求正文)。

布尔标志 只有在被启用时 才出现在 ctx 中。引擎以 StrictUndefined 渲染: 因此必须 测试键的存在,绝不测试它的值。

{# ✅ correct — on teste la présence #}
{% if 'searchable' in p %}INDEX({{ p['name'] }}){% endif %}
{# ❌ faux — lève une erreur quand le flag est absent #}
{% if p.searchable %}…{% endif %}

只有 property.required(布尔)和 route.auth(枚举)始终 存在。其他布尔 标志是「存在 = 真」;带 值 的字段(volumetry、运行画像、cache……)在被填写时 带有它们的值,否则不存在 —— 同样的存在规则。

在 属性 上在 模型 上在 路由 上
readOnly · writeOnly · nullabletimestamps · softDelete(布尔)idempotent · deprecated(布尔)
unique · searchable · immutable · pii运行画像(值):volumetry · accessPattern · traffic · freshness · sensitivity · retentioncacheSeconds(数字) · pagination(对象)

一个模型的 运行画像 的值:accessPattern (readHeavy / writeHeavy / balanced / appendOnly)、traffic (low / medium / high)、freshness(strong / shortCache / longCache)、 sensitivity(public / internal / confidential / pii)、retention (permanent / archivable / ephemeral)、volumetry(hundreds / tenThousands / millions)。

有两种情况,取决于该信息是否已经存在于设计中。

如果您在一条路由上填写了一个 缓存时长,它会到达 route['cacheSeconds']; route['idempotent'] 告诉您它可以安全地缓存(只读):

{% for group in ctx['groups'] %}
{% for route in group['routes'] %}
{% if 'cacheSeconds' in route and 'idempotent' in route %}
// {{ route['method'] }} {{ route['fullPath'] }}
app.use("{{ route['fullPath'] }}", cache({{ route['cacheSeconds'] }}));
{% endif %}
{% endfor %}
{% endfor %}

b)「读取需求高」是模型的一个原生字段

Section titled “b)「读取需求高」是模型的一个原生字段”

不需要变量:「读取需求高」直接就是模型的 访问画像。在模型的设置中、运行画像 组里,您选择 Lecture dominante(以读为主)—— 模板在 model['accessPattern'] 中 读取它。把它与 model['freshness'](对新鲜度的容忍度)结合,来决定是否要缓存, 以及缓存多久:

{% for model in ctx['models'] %}
{% if model['accessPattern'] == 'readHeavy' and model['freshness'] != 'strong' %}
{% set ttl = 3600 if model['freshness'] == 'longCache' else 60 %}
registerCache("{{ model['name'] }}", {{ ttl }}); // cache activé ({{ ttl }}s)
{% endif %}
{% endfor %}

注意 != 'strong' 这个测试:一个以读为主 但 要求强一致性的模型 不应 被 缓存。这正是把两个意图在设计中并排放置的全部价值所在。

请把生成变量留给设计尚未承载的东西(一个模板自身的 设置):业务意图 —— volumetry、accessPattern、traffic、freshness、sensitivity、 retention —— 是模型的 原生字段。

这个上下文是受版本控制的(ctx['contextVersion']),并由一份随应用程序仓库一起 交付的 JSON-Schema(docs/contributing/design-codegen-context.schema.json)详尽 描述 —— 把它复制到您的模板中,好让它的 CI 验证参考上下文。一个 AI 智能体通过 MCP 工具 get_design_template_contract 即时获得同样的契约。