Preview. Logic Apps Standard SDK está em preview e sujeito aos Termos Suplementares de Uso para Microsoft Azure Previews.
TL;DR: o novo Logic Apps Standard SDK (Microsoft.Azure.Workflows.Sdk, em preview) permite que times .NET abandonem o designer visual e JSON para escrever workflows de integração e agentic workflows em C# fortemente tipado. O runtime do Logic Apps Standard não muda — mesmos conectores, monitoramento e run history. Isso significa versionamento real em Git, code review via pull requests, depuração com F5 e um caminho natural para adoção de coding agents (LLMs geram código compilável, não JSON declarativo).
O workflow que você sempre quis escrever em código
Se você já construiu algo com Logic Apps Standard, conhece bem o runtime: ele é excelente na parte não glamourosa da integração — conectar sistemas, fazer retry, escalar, manter um run history que você realmente consegue debugar. O que faltava era uma porta de entrada diferente. Você é um desenvolvedor .NET. Você vive em C#, source control e pull requests. E por muito tempo, criar um workflow significava deixar tudo isso de lado para usar um designer visual e um arquivo JSON.
É essa lacuna que o novo Logic Apps Standard SDK fecha. Ele permite que você defina workflows do Logic Apps Standard em código — C# fortemente tipado, guiado por IntelliSense — sem abrir mão de nada que o runtime já faz por você.
O que é o Logic Apps Standard SDK?
O Logic Apps Standard SDK (Microsoft.Azure.Workflows.Sdk) é um pacote NuGet que oferece uma forma fluente e code-first para construir definições de workflow em C#. Em vez de arrastar ações para uma tela, você compõe um workflow com method chaining: um trigger, depois as ações que o seguem, até chegar a uma resposta.
Vale dizer claramente, porque as pessoas perguntam: esta é uma nova forma de definir workflows — não um novo runtime. Os workflows que você escreve com o SDK são compilados para as mesmas definições e executados no mesmo runtime do Logic Apps Standard que você usa hoje. Mesmos conectores. Mesmo hosting. Mesmo run history e monitoramento. Você está mudando a experiência de autoria, não o motor subjacente.
Por que isso importa para desenvolvedores
Quando seu workflow vive em C#, ele se comporta como o resto do seu código. Algumas coisas surgem quase de graça:
- Type safety e IntelliSense — operações de conectores, triggers e saídas são descobertas enquanto você digita, e o compilador pega erros antes de executar.
- Source control e reviews reais — workflows diff como código, são revisados em pull requests e versionados junto com os serviços que orquestram.
- Ferramentas familiares — refatore, debug com F5 e apoie-se no ecossistema .NET que você já conhece.
- Extensibilidade nos seus termos — componha seu workflow declarativamente com o fluent builder e, depois, caia em C# imperativo puro sempre que um passo precisar de lógica complexa demais para ser declarativa — loops, branches, chamadas para sua própria biblioteca, tudo encapsulado sem sair do arquivo ou da linguagem.
E não se limita a um estilo de trabalho. O SDK cobre tanto workflows de integração enterprise — os cenários de conectar sistemas e mover dados pelos quais o Logic Apps é conhecido — quanto agentic workflows, onde um agente de IA conversacional ou autônomo dirige os passos. Ambos são cidadãos de primeira classe no mesmo SDK, construídos com os mesmos blocos.
Há mais um ângulo que merece destaque, porque está se tornando impossível ignorar: coding agents são simplesmente melhores a escrever código imperativo do que JSON declarativo. E a razão é o mesmo conjunto de guardrails que ajuda você. Tipagem forte e uma etapa de compilação significam que o código produzido por um agente é sintaticamente correto de partida — o sistema de tipos e o compilador fazem a verificação, então você não precisa. Adicione unit tests por cima e você cobre mais de 90% do que importa; o que sobra é teste de integração. Levar um LLM ao mesmo nível de precisão contra JSON declarativo exigiria construir ferramentas dedicadas para substituir tudo o que o compilador te dá de graça. Com workflows code-first, essas guardrails estão simplesmente lá — o que torna essa abordagem um ajuste natural para construção assistida por agentes.
Como começar
Tudo aqui vive na extensão do Logic Apps para VS Code. Você vai precisar da extensão Logic Apps Standard VS Code versão 5.961.10 ou superior, que inclui todos os componentes para criar workflows code-first. Além disso, os pré-requisitos são os esperados — VS Code com a extensão Logic Apps, uma assinatura Azure onde você possa criar recursos e familiaridade com C# e .NET.
De um início limpo, você está a alguns passos de um workflow em execução:
- Crie o workspace — inicie a extensão Logic Apps e escolha Create new Logic Apps workspace. Escolha uma pasta, nomeie o workspace e o projeto e, quando solicitado o tipo de workflow, escolha Logic Apps codeful — essa é a opção code-first que usa o SDK.
- Escolha um tipo de workflow — nomeie seu primeiro workflow e escolha como ele executa: Stateful, Autonomous agents (Preview) ou Conversational agents (Preview). As opções de agente são onde os cenários agentic vivem.
- Habilite conectores — quando solicitado, selecione Use connectors from Azure, escolha sua assinatura e resource group, e escolha Connection Keys para autenticação. Managed identity ainda está em desenvolvimento, então connection keys são o caminho por enquanto.
- Conheça o projeto — o projeto abre com Program.cs, que constrói e inicia o host, além de um arquivo de workflow (como workflow1.cs) onde seu trigger e ações estão definidos. O SDK compila essas definições e as executa no runtime do Logic Apps.
- Execute — pressione F5 (ou clique com o botão direito em Program.cs e escolha Overview). O runtime inicia localmente e uma página de visão geral abre onde você pode disparar triggers, observar o run history e inspecionar entradas e saídas.
Essa última parte merece atenção: o run history para workflows do SDK usa a mesma visual rica dos workflows criados com designer. Você autoriza em código, mas monitora e soluciona problemas exatamente como sempre fez.
Uma olhada nas capacidades
Conectores e triggers
Todo workflow começa com um trigger e executa uma série de ações. O SDK expõe ambos através de dois entry points — WorkflowTriggers e WorkflowActions — cada um dividido em BuiltIn e Managed.
- Built-in: triggers e ações que rodam diretamente no runtime: requisição HTTP, recorrência e o trigger de agente conversacional; ações como Compose, HTTP, Response e custom code.
- Managed: conectores que dão acesso ao catálogo completo do Logic Apps — Service Bus, SharePoint, SQL, e centenas mais — tipados e prontos para chamar.
A superfície managed é gerada a partir das mesmas definições de conector que o designer usa, então as operações que você conhece estão lá:
// Built-in trigger
var trigger = WorkflowTriggers.BuiltIn.CreateHttpTrigger();
// Managed connector action — full catalog, strongly typed
var getItems = WorkflowActions.Managed
.Sharepointonline("sharepoint")
.GetItems(
dataset: () => "https://contoso.sharepoint.com",
table: () => "orders-list-id")
.WithName("GetOrders");
A fluent API simplifica a definição
É aqui que tudo se junta. Você compõe um workflow encadeando operações com .Then(...). A forma do seu código espelha a forma do seu workflow — leia de cima para baixo e você lê o caminho de execução.
trigger
.Then(validateOrder)
.Then(getOrders)
.Then(sendResponse);
O fluxo de controle faz parte do mesmo modelo fluente. Estruturas built-in como Condition (if/else) e ForEach — junto com Switch, Until, Scope e Terminate — são apenas ações que você encadeia, cada uma recebendo uma pequena factory para o branch ou corpo do loop:
var checkTotal = WorkflowActions.BuiltIn.Control.Condition(
expression: () => order.Total > 1000,
trueBranch: () => requireApproval,
falseBranch: () => autoApprove
).WithName("CheckOrderValue");
E ForEach recebe a coleção a iterar e uma factory que constrói o corpo para cada item:
var processLines = WorkflowActions.BuiltIn.Control.ForEach(
items: () => order.LineItems,
actions: (item) => new WorkflowBuiltInActions()
.Compose(inputs: () => $"Line: {item}").WithName("HandleLine")
).WithName("ProcessLineItems");
Precisa de branches paralelos que convergem? O mesmo padrão Then lida com branching e join — sem JSON para configurar, sem bloco run-after para editar manualmente.
Estendendo workflows com custom code
Alguma lógica não pertence a um conector ou a uma expressão — é apenas código. A ação CustomCode permite que você insira um método C# real no meio de um workflow. Ele recebe um WorkflowContext, para que você possa ler o payload do trigger ou resultados de ações anteriores e retornar um valor fortemente tipado que o próximo passo pode usar:
var enrich = WorkflowActions.BuiltIn.CustomCode<string>(async (context) =>
{
var trigger = await context.GetTriggerResults();
var order = await context.GetActionResults("GetOrders");
// your logic, your libraries, your types
return "enriched";
}).WithName("EnrichOrder");
Essa é a escotilha de escape que mantém você no fluxo: quando um passo precisa de transformação personalizada, validação ou uma chamada para suas próprias bibliotecas, você escreve um método em vez de forçar uma expressão a fazer algo para o qual ela nunca foi feita.
Tratamento de falhas: try/catch com run-after
Workflows reais precisam lidar com erros, e o SDK oferece a mesma estrutura try/catch que o Logic Apps sempre teve — expressa em código. A sobrecarga de .Then(...) aceita uma condição FlowStatus[] de run-after, para que um handler execute apenas quando o passo anterior terminar em um status que você nomear. Coloque o trabalho arriscado em um Scope (seu try), depois encadeie um handler que executa após Failed ou TimedOut (seu catch):
var tryProcess = WorkflowActions.BuiltIn.Control.Scope(() =>
callPaymentApi.Then(saveOrder)
).WithName("ProcessPayment");
var handleFailure = WorkflowActions.BuiltIn
.Compose(inputs: () => "Payment failed — compensating")
.WithName("HandleFailure");
trigger
.Then(tryProcess)
.Then(handleFailure,
runAfter: new[] { FlowStatus.Failed, FlowStatus.TimedOut });
O conjunto de status é o vocabulário completo: Succeeded, Failed, Skipped e TimedOut. Combine-os como um passo precisar — uma ação de limpeza que deve rodar independentemente do resultado pode listar todos os status; um finally é apenas a união.
A mesma ideia escala para fan-in. Quando vários branches paralelos convergem, a sobrecarga de RunAfter por predecessor permite que o join espere em cada branch independentemente — assim você pode exigir que alguns sucedam e tolerar que outros falhem:
leftChain
.Join(rightChain)
.Then(merge, runAfter: new[]
{
new RunAfter(leftChain, FlowStatus.Succeeded),
new RunAfter(rightChain, FlowStatus.Succeeded),
});
Juntando tudo
Aqui está um exemplo pequeno mas completo — um workflow de pedidos acionado por HTTP que valida entrada, ramifica com base no valor do pedido, itera sobre itens de linha, executa código personalizado e responde. Os passos principais ficam dentro de um Scope para que um único handler de falha possa capturar qualquer erro, e uma resposta limpa só executa quando o trabalho é bem-sucedido. Observe que é tudo uma cadeia legível:
namespace LogicApps
{
using Microsoft.Azure.Workflows.Sdk;
using Microsoft.Azure.Workflows.Sdk.Connectors.Msnweather;
using System.Net;
public class OrderWorkflow : IWorkflowProvider
{
public FlowDefinition[] GetWorkflows()
{
var trigger = WorkflowTriggers.BuiltIn.CreateHttpTrigger();
var getWeather = WorkflowActions.Managed.Msnweather("msnweather").CurrentWeather(
location: () => "98058",
units: () => unitsInput.Imperial).WithName("GetWeather");
var enrich = WorkflowActions.BuiltIn.CustomCode<string>(async (context) =>
{
var triggerResults = await context.GetTriggerResults();
var weather = await context.GetActionResults("GetWeather");
return "enriched";
}).WithName("EnrichOrder");
var processLines = WorkflowActions.BuiltIn.Control.ForEach(
items: () => trigger.TriggerOutput.Body["lineItems"],
actions: (item) => WorkflowActions.BuiltIn
.Compose(inputs: () => $"Line: {item}").WithName("HandleLine")
).WithName("ProcessLineItems");
var checkTotal = WorkflowActions.BuiltIn.Control.Condition(
expression: () => true,
trueBranch: () => processLines,
falseBranch: () => WorkflowActions.BuiltIn
.Compose(inputs: () => "Auto-approved").WithName("AutoApprove")
).WithName("CheckOrderValue");
var processOrder = WorkflowActions.BuiltIn.Control.Scope(() =>
checkTotal
.Then(getWeather)
.Then(enrich)
).WithName("ProcessOrder");
var ok = WorkflowActions.BuiltIn.Response(
responseBody: () => "Order processed").WithName("Reply");
var failed = WorkflowActions.BuiltIn.Response(
statusCode: () => HttpStatusCode.InternalServerError,
responseBody: () => "Order failed").WithName("ReplyFailed");
trigger
.Then(processOrder)
.Then(ok, runAfter: new[] { FlowStatus.Succeeded })
.Then(failed, runAfter: new[] { FlowStatus.Failed, FlowStatus.TimedOut });
return new[] { WorkflowFactory.CreateStatefulWorkflow("OrderWorkflow", trigger) };
}
}
}
Esse último trecho é a forma de melhor prática em miniatura: o Reply de caminho feliz só executa após o Scope ter Succeeded, enquanto um handler separado captura Failed ou TimedOut e retorna um 500 — sem encanamento de exceções, apenas condições run-after.
Você implementa IWorkflowProvider, entrega seu grafo de trigger para WorkflowFactory como um workflow stateful, stateless ou agent, e o host o registra. Execute com F5 e o runtime do Logic Apps inicia localmente — como qualquer projeto Standard.
Antes de construir: realidades da preview
Prefiro que você entre de olhos abertos. Embora o SDK esteja em preview pública, tenha em mente:
- Service Provider connectors ainda não são suportados — esse tipo de conector virá em uma versão futura.
- Dynamic schemas não são suportados — suporte está planejado.
- Custom code suporta apenas callback methods — lambdas inline não estão disponíveis nesta versão.
- Defina e nomeie ações antes de referenciá-las — nomeie uma ação antes de usá-la como dependência em outro lugar.
- Autenticação via managed identity está em desenvolvimento — use connection keys para conectores por enquanto.
Experimente e nos diga o que achou
Se você sempre quis que seus workflows vivessem onde o resto do seu código vive — em C#, em source control, nos seus pull requests — isso é para você. Instale a extensão Logic Apps para VS Code, crie um projeto Logic Apps codeful e construa seu primeiro workflow em código.
Esta é uma preview, o que significa que seu feedback realmente molda para onde ela vai — quais capacidades vêm a seguir, onde estão as arestas.
Leve issues, feature requests e feedback para nossa página no GitHub. Eu leio. Vamos tornar workflows code-first algo que você realmente queira usar.
Perguntas Frequentes
-
O Logic Apps Standard SDK substitui o designer visual do portal?
Não. O SDK é uma alternativa code-first para definir workflows — você continua usando o mesmo runtime, conectores, monitoramento e run history. O designer tradicional continua existindo. Essa é apenas uma nova forma de autoria. -
Posso usar o SDK em cenários de agentic workflows com IA?
Sim. O SDK suporta workflows do tipo Stateful, Autonomous agents (Preview) e Conversational agents (Preview). Isso significa que você pode construir fluxos orquestrados por IA usando o mesmo código C# fortemente tipado. -
Quais são as limitações mais importantes da preview?
Service Provider connectors não são suportados ainda; dynamic schemas estão na lista futura; custom code só funciona com callback methods (sem inline lambdas); e a autenticação via managed identity está em desenvolvimento — por enquanto, use connection keys. -
Coding agents realmente funcionam melhor com o SDK do que com JSON declarativo?
Segundo a Microsoft, sim. O sistema de tipos e a etapa de compilação garantem que o código gerado por LLMs seja sintaticamente correto de partida — ao contrário do JSON declarativo, que exigiria ferramentas dedicadas para atingir o mesmo nível de precisão. -
Preciso de alguma versão específica do VS Code para começar?
Sim. Você precisa da extensão Logic Apps Standard para VS Code versão 5.961.10 ou superior, que já inclui os templates para criar projetos 'codeful' (code-first) do zero.
Artigo originalmente publicado por WSilveira em Azure Updates - Latest from Azure Charts.