{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/dataverse-business-rules-vs-client-scripting-model-driven/","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Dataverse: business rules vs client scripting em model-driven","description":"Entenda quando a logica de formulario em model-driven apps deve ser uma business rule no-code e quando exige JavaScript, com limites de escopo, execucao e manutencao.","date":"23 de outubro de 2026","thumbnail":null},"html":"<p>Em formularios de model-driven apps existe uma camada de logica que roda no cliente, antes de qualquer plugin ou fluxo entrar em cena: a validacao e o comportamento da interface. A Microsoft oferece dois caminhos para isso — <strong>business rules</strong> (no-code, declarativas) e <strong>client scripting</strong> em JavaScript (Client API). A escolha errada entre eles gera ou regras impossiveis de evoluir ou uma base de scripts fragil que ninguem quer tocar. Este post delimita onde cada abordagem ganha.</p>\n<p><strong>O que business rules realmente fazem (e onde param)</strong></p>\n<p>Uma business rule e uma regra declarativa configurada no designer, composta de condicoes e acoes. Ela pode: mostrar/ocultar campos, tornar campos obrigatorios ou opcionais, habilitar/desabilitar campos, definir valores de campo, validar com mensagem de erro e aplicar recomendacoes. O ponto forte e o escopo de execucao: uma business rule pode rodar no formulario (cliente) <strong>ou na entidade inteira</strong>, incluindo server-side. Quando configurada com escopo Entity, a regra e aplicada tambem em criacao/atualizacao via API, importacao e outros formularios — algo que um script OnLoad jamais alcanca.</p>\n<p>Mas o teto chega rapido:</p>\n<ul>\n<li>So opera sobre campos do proprio formulario/registro — nao consulta outras tabelas.</li>\n<li>Nao faz chamadas assincronas (sem Web API, sem await).</li>\n<li>Logica condicional e limitada a AND/OR simples, sem loops nem calculo complexo.</li>\n<li>Nao manipula subgrids, abas dinamicas por dados externos ou controles customizados.</li>\n<li>Set Field Value nao dispara eventos OnChange de outros campos em cadeia de forma confiavel.</li>\n</ul>\n<p><strong>Quando o JavaScript (Client API) e inevitavel</strong></p>\n<p>Client scripting entra quando a regra precisa de dados que nao estao no formulario ou de comportamento que business rules nao expressam. Casos tipicos:</p>\n<ul>\n<li><strong>Consultar outra tabela</strong> antes de validar — <code>Xrm.WebApi.retrieveMultipleRecords</code> para checar duplicidade, buscar limite de credito, validar estoque.</li>\n<li><strong>OnSave assincrono</strong> com <code>executionContext.getEventArgs().preventDefault()</code> e uma Promise, para bloquear o salvamento ate uma validacao remota retornar.</li>\n<li><strong>Manipular a UI alem de campos</strong>: controlar visibilidade de abas/secoes, filtrar lookups dinamicamente com <code>addPreSearch</code>/<code>addCustomFilter</code>, reagir a eventos de subgrid.</li>\n<li><strong>Logica de calculo</strong> que envolve varios campos com condicionais, formatacao ou transformacao de texto.</li>\n</ul>\n<p>O preco e manutencao: JavaScript vive em web resources, precisa ser versionado em solucao, testado em cada atualizacao de plataforma (a Client API evolui) e e sensivel a mudancas de schema. Um <code>getAttribute</code> para um campo removido quebra silenciosamente o formulario.</p>\n<p><strong>O erro de colocar regra de negocio critica no cliente</strong></p>\n<p>Tanto business rules de escopo Form quanto client scripting rodam no navegador — e podem ser contornados. Um usuario pode gravar o registro via API, importacao de Excel, fluxo do Power Automate ou um segundo formulario sem o script. Portanto:</p>\n<ul>\n<li>Validacao de <strong>conveniencia/UX</strong> (obrigatoriedade visual, mensagem amigavel, ocultar campos) fica no cliente.</li>\n<li>Validacao que <strong>garante integridade de dados</strong> (nao pode existir registro em estado X sem campo Y) tem que estar no servidor — business rule de escopo Entity para casos simples, ou plugin em pre-operation/pre-validation para casos que exigem consulta e transacao.</li>\n</ul>\n<p>O padrao robusto e dupla camada: a mesma regra no cliente (para feedback imediato) e no servidor (para garantia real). Business rules de escopo Entity cobrem esse caso sem duplicar codigo quando a logica e simples.</p>\n<p><strong>Roteiro de decisao</strong></p>\n<ol>\n<li>A regra so mostra/oculta/obriga/valida campos do proprio registro, sem consultar nada externo? → <strong>Business rule</strong>. Se precisar valer tambem na API/importacao, use escopo Entity.</li>\n<li>Precisa consultar outra tabela, fazer validacao assincrona, filtrar lookup ou manipular subgrid/aba por dados? → <strong>Client scripting</strong>.</li>\n<li>A regra protege integridade de dados que nao pode depender da UI? → <strong>Servidor</strong> (business rule Entity para o simples, plugin para o que exige consulta/transacao), com eventual espelho no cliente para UX.</li>\n<li>A logica precisa de reuso entre varias tabelas/forms? → Considere <strong>plugin ou PCF</strong>, nao copiar script.</li>\n</ol>\n<p>Comecar pela business rule e so escalar para JavaScript quando o limite aparecer mantem o formulario sustentavel. Em model-driven apps que crescem, misturar dezenas de scripts desconexos com dezenas de business rules sobre os mesmos campos vira um pesadelo de depuracao — a disciplina de saber onde cada regra vive e o que separa um app mantido de um app temido.</p>\n<p>Se sua organizacao opera model-driven apps e Dynamics 365 em escala e precisa estruturar essa camada de logica de formulario com governanca e ALM, a Dynamic Solucoes pode ajudar a desenhar a arquitetura e os padroes certos, do no-code ao servidor.</p>\n<p>In model-driven app forms there is a layer of logic that runs on the client, before any plugin or flow comes into play: form validation and interface behavior. Microsoft offers two paths for this — <strong>business rules</strong> (no-code, declarative) and <strong>client scripting</strong> in JavaScript (Client API). The wrong choice between them produces either rules that are impossible to evolve or a fragile script base that nobody wants to touch. This post defines where each approach wins.</p>\n<p><strong>What business rules actually do (and where they stop)</strong></p>\n<p>A business rule is a declarative rule configured in the designer, made of conditions and actions. It can: show/hide fields, make fields required or optional, enable/disable fields, set field values, validate with an error message, and apply recommendations. Its strength is the execution scope: a business rule can run on the form (client) <strong>or on the entire entity</strong>, including server-side. When configured with Entity scope, the rule is also applied during create/update via API, import, and other forms — something an OnLoad script can never reach.</p>\n<p>But the ceiling arrives quickly:</p>\n<ul>\n<li>It only operates on fields of the current form/record — it does not query other tables.</li>\n<li>It makes no asynchronous calls (no Web API, no await).</li>\n<li>Conditional logic is limited to simple AND/OR, with no loops or complex computation.</li>\n<li>It does not manipulate subgrids, data-driven dynamic tabs, or custom controls.</li>\n<li>Set Field Value does not reliably trigger OnChange events of other fields in a chain.</li>\n</ul>\n<p><strong>When JavaScript (Client API) is unavoidable</strong></p>\n<p>Client scripting comes in when the rule needs data that is not on the form or behavior that business rules cannot express. Typical cases:</p>\n<ul>\n<li><strong>Querying another table</strong> before validating — <code>Xrm.WebApi.retrieveMultipleRecords</code> to check for duplicates, fetch a credit limit, validate stock.</li>\n<li><strong>Asynchronous OnSave</strong> with <code>executionContext.getEventArgs().preventDefault()</code> and a Promise, to block the save until a remote validation returns.</li>\n<li><strong>Manipulating the UI beyond fields</strong>: controlling tab/section visibility, dynamically filtering lookups with <code>addPreSearch</code>/<code>addCustomFilter</code>, reacting to subgrid events.</li>\n<li><strong>Calculation logic</strong> involving several fields with conditionals, formatting, or text transformation.</li>\n</ul>\n<p>The cost is maintenance: JavaScript lives in web resources, must be versioned in a solution, tested at each platform update (the Client API evolves), and is sensitive to schema changes. A <code>getAttribute</code> for a removed field silently breaks the form.</p>\n<p><strong>The mistake of putting critical business rules on the client</strong></p>\n<p>Both Form-scoped business rules and client scripting run in the browser — and can be bypassed. A user can save the record via API, Excel import, Power Automate flow, or a second form without the script. Therefore:</p>\n<ul>\n<li><strong>Convenience/UX</strong> validation (visual requiredness, friendly message, hiding fields) stays on the client.</li>\n<li>Validation that <strong>guarantees data integrity</strong> (no record can exist in state X without field Y) must live on the server — an Entity-scoped business rule for simple cases, or a plugin in pre-operation/pre-validation for cases that require a query and a transaction.</li>\n</ul>\n<p>The robust pattern is dual-layer: the same rule on the client (for immediate feedback) and on the server (for real enforcement). Entity-scoped business rules cover this case without duplicating code when the logic is simple.</p>\n<p><strong>Decision guide</strong></p>\n<ol>\n<li>Does the rule only show/hide/require/validate fields of the current record, with no external lookup? → <strong>Business rule</strong>. If it must also hold on API/import, use Entity scope.</li>\n<li>Does it need to query another table, do asynchronous validation, filter a lookup, or manipulate a subgrid/tab from data? → <strong>Client scripting</strong>.</li>\n<li>Does the rule protect data integrity that cannot depend on the UI? → <strong>Server</strong> (Entity business rule for the simple case, plugin for what needs a query/transaction), with an optional client mirror for UX.</li>\n<li>Does the logic need reuse across several tables/forms? → Consider a <strong>plugin or PCF</strong>, not copying the script.</li>\n</ol>\n<p>Starting with the business rule and only escalating to JavaScript when the limit appears keeps the form sustainable. In model-driven apps that grow, mixing dozens of disconnected scripts with dozens of business rules over the same fields becomes a debugging nightmare — the discipline of knowing where each rule lives and what separates them is what distinguishes a maintained app from a feared one.</p>\n<p>If your organization runs model-driven apps and Dynamics 365 at scale and needs to structure this form logic layer with governance and ALM, Dynamic Solucoes can help design the right architecture and patterns, from no-code to server.</p>"}},"pageContext":{"slug":"/blog/dataverse-business-rules-vs-client-scripting-model-driven/","previousPost":null,"nextPost":{"frontmatter":{"title":"Power Pages: Liquid vs Web API vs FetchXML para acessar Dataverse"},"fields":{"slug":"/blog/power-pages-liquid-web-api-fetchxml-dataverse-acesso-dados/"}}}},"staticQueryHashes":["2269431855"]}