TheCodeNaked

Paralelismo - Episódio 34 (Copy)

Episódio 34 - Encadeando chamadas REST sem dor: filtrando resultados dinamicamente

No mundo real, sistemas REST são a espinha dorsal de muitos aplicativos Delphi. A comunicação com servidores envolve sequências de chamadas que, quando mal tratadas, geram esperas bloqueantes, códigos duplicados e erros silenciosos. No episódio de hoje, vamos mostrar como transformar essa dor em algo elegante com TTaskChain e TSafeThread.


Cenário comum:

Imagine que você precise:

  • Buscar dados de produtos via REST (GET /produtos)
  • Aplicar um filtro local baseado na escolha do usuário
  • Exibir esses dados na UI
  • Em caso de erro, mostrar uma notificação amigável
  • Tudo isso sem travar a interface

Solução ingênua (e perigosa):

Memo1.Lines.Text := RESTClient.Get('...');
Filtrar(Memo1.Lines.Text);
AtualizarUI();

Problemas:

  • Bloqueia a UI
  • Se a conexão falhar, a aplicação congela
  • Erros de rede ou parsing geram exceções não tratadas

Solução com TTaskChain

Vamos fazer da forma correta, segmentando cada etapa:

TaskChain := TTaskChain.Create(False);

TaskChain.AddTask('Buscar Produtos',
  procedure(const TaskName: string; OnSuccess: TProc; OnError: TErrorCallback)
  begin
    TSafeThread.ExecuteThread(
      TSafeThreadParams.New
        .SetOnExecute(
          procedure(Context: TThreadContext)
          begin
            DadosJSON := RESTClient.Get('https://api.exemplo.com/produtos');
            if Assigned(OnSuccess) then
              OnSuccess();
          end)
        .SetOnError(
          procedure(const Msg: string)
          begin
            OnError('Erro ao buscar produtos: ' + Msg);
          end)
        .SetCompleteWithError(True)
    );
  end);

TaskChain.AddTask('Filtrar Produtos',
  procedure(const TaskName: string; OnSuccess: TProc; OnError: TErrorCallback)
  begin
    TSafeThread.ExecuteThread(
      TSafeThreadParams.New
        .SetOnExecute(
          procedure(Context: TThreadContext)
          begin
            DadosFiltrados := FiltrarPorCategoria(DadosJSON, CategoriaEscolhida);
            if Assigned(OnSuccess) then
              OnSuccess();
          end)
        .SetOnError(
          procedure(const Msg: string)
          begin
            OnError('Erro ao filtrar: ' + Msg);
          end)
    );
  end);

TaskChain.AddTask('Atualizar UI',
  procedure(const TaskName: string; OnSuccess: TProc; OnError: TErrorCallback)
  begin
    TSafeThread.ExecuteThread(
      TSafeThreadParams.New
        .SetOnExecute(
          procedure(Context: TThreadContext)
          begin
            TThread.Synchronize(nil,
              procedure
              begin
                ExibirProdutos(DadosFiltrados);
              end);
            if Assigned(OnSuccess) then
              OnSuccess();
          end)
    );
  end);

TaskChain.Start;

Resultado:

  • Cada etapa é controlada e segura
  • Nenhum travamento de UI
  • Filtros são reaproveitáveis
  • Erros podem ser tratados individualmente

Esse tipo de estrutura é ideal não apenas para REST, mas para qualquer sequência de operações assíncronas com dependências lógicas entre elas.

No próximo episódio, vamos aplicar esse mesmo modelo para sincronizar dados com um banco SQLite local. Sim, offline também pode ser bonito.

Sobre o autor

TheCodeNaked

No TheCodeNaked, programar é consequência, não ponto de partida. Antes do código, vem a dúvida, a análise, o contexto. Não seguimos fórmulas — questionamos. Criar software é pensar com clareza. O resto é só digitação.

TheCodeNaked

Criar com clareza. Codificar com intenção.

TheCodeNaked

Ótimo! Você se inscreveu com sucesso.

Bem-vindo de volta! Você acessou com sucesso.

Você se inscreveu com sucesso o TheCodeNaked.

Sucesso! Verifique seu e-mail para acessar com o link mágico.

As suas informações de faturamento foram atualizadas.

Seu pagamento não foi atualizado