Artigo
· Fev. 9 6min de leitura

Serviço REST em Produção IRIS: Quando Você Quer Mais Controle Sobre Dados Não Tratados

 

  “A pedido dos sobreviventes, os nomes foram alterados. Por respeito aos mortos, o RESTO foi contado exatamente como aconteceu.

Atenção: Há uma enquete importante no final deste artigo. Estou aguardando ansiosamente suas respostas!

Então, encontramos um obstáculo. Um grande. Não há como pesquisar mensagens em nossa produção.

Claro, uma mensagem chega ao serviço REST, e tudo na produção funciona perfeitamente como deveria.



 

Aqui está uma requisição de exemplo:

{

"case":"2-12-85-06",

"to":"management of ZOO",

"subject":"Children report that the horse has grown a fifth leg"
}

Tudo parece correr bem na produção!

MAS! Então, ou nós ou o cliente queremos mais:

"Ei, podemos filtrar mensagens por critérios específicos? Por exemplo, já recebemos algo relacionado ao número do caso 2-12-85-06?"

E é aí que as coisas tomaram um rumo sinistro.

O tipo de mensagem padrão, EnsLib.HTTP.GenericMessage, armazena dados JSON em fluxos. Uma ótima ideia, certo? Até que deixa de ser.

Porque pesquisar mensagens em fluxos funciona tão bem quanto uma porta de tela em um submarino. Spoiler: Não funciona. Tipo, nem um pouco.

Você provavelmente já viu esse erro antes:


Este adorável "NÃO" vermelho é o guardião vigilante dos seus dados. Sempre em serviço, sempre impedindo seus dedos suados de tocar em qualquer coisa sensível. Um verdadeiro protetor! Mas também uma grande dor de cabeça.

 

O Contra Ataque

  "A maré vermelha, Lester. A vida. Estamos sendo alimentados com porcaria, dia após dia - chefes, esposas, o que for. Está nos matando. E se você não se levantar, se você não mostrar a eles que você ainda é um animal lá no fundo, a maré vai te arrastar."

 

Nós não recuamos, porém. Nunca.

Existem algumas soluções possíveis. Eu pessoalmente optei por uma com armazenamento limitado porque não quero manter dados extras armazenados. Eu só quero ficar dentro do reino das mensagens de produção.

Então, aqui está o plano:

Nós criamos uma classe de mensagem personalizada, herdando de EnsLib.HTTP.GenericMessage. Algo assim:

Class Production.Message.ZooMessage Extends EnsLib.HTTP.GenericMessage
{

Property RequestJSON As %String(MAXLEN = "");
Property CaseId As %String;
Index ZooMessageCaseIdIndex On CaseId;
}

Em seguida, precisamos passar esta mensagem personalizada para a operação e incluir dados adicionais prontos para pesquisa (corpo da mensagem e número do caso).

 

Solução 1: O "Começo Não Tão Bom"

 

 

Não confie no que vem do oceano.

- Mas... nós viemos do oceano.”

 

Criamos um serviço herdando de EnsLib.REST.GenericService, e então o adicionamos à produção. Simples, certo?

Class Production.Service.ZooREST Extends EnsLib.REST.GenericService
{

Parameter DOCCLASS = "Production.Message.ZooMessage";
}

Produção:

  <Item Name="Service.RESTver1" Category="" ClassName="Production.Service.ZooREST">
    <Setting Target="Host" Name="TargetConfigName">Operation.RESTver1</Setting>
    <Setting Target="Adapter" Name="Port">1984</Setting>
  </Item>

Exceto que não é.

O tipo de mensagem de entrada permanece o mesmo. O parâmetro DOCCLASS = "Production.Message.ZooMessage" não funcionou.

 

Solução 2: "Gente Demais Metendo a Colher"

 

  Isso é bem incomum…
Incomum? Uma vez eu achei um pé humano no forno. Aquilo foi incomum. Isso é meramente estranho.

 

Acontece que o problema se resume a esta única linha de código no método OnProcessInput:


Substituindo por:
Set tRequest=$classmethod(..#DOCCLASS,"%New",pRequestBody,,pRequestBody)

...resolveria o problema. Mas essa mudança tornaria o código do fornecedor inútil em atualizações futuras do IRIS. Uma opção sem saída que deixa um gosto ruim na boca.

 

 

Solução 3: O "Caminho Guardado por um Dragão"

 

 

“Você poderia simplesmente entrar no seu carro e ir embora

- E por que faria isso?

- Porque algumas estradas você simplesmente não deve pegar. Antigamente os mapas marcavam elas, dizendo, ‘Aqui Há Dragões.’ Agora não marcam mais, mas os dragões continuam lá.

 

A ideia? Passar a mensagem para um roteador, transformá-la e enviá-la para o processo.

Componentes necessários:

  • Um roteador
  • Uma transformação
  • Uma pitada de algo misterioso e arcano
Class Production.Rule.Router Extends Ens.Rule.Definition
{

XData RuleDefinition [ XMLNamespace = "http://www.intersystems.com/rule" ]
{
<ruleDefinition alias="" context="EnsLib.MsgRouter.RoutingEngine" production="Production.Test">
<ruleSet name="ZOO Router" effectiveBegin="" effectiveEnd="">
<rule name="ZOO Process Inbound Http" disabled="false">
<constraint name="source" value="Service.RESTver3"></constraint>
<when condition="1">
<send transform="Production.DataTransformation.ZOO" target="Operation.RESTver3"></send>
<return></return>
</when>
</rule>
</ruleSet>
</ruleDefinition>
}

}

 

Class Production.DataTransformation.ZOO Extends Ens.DataTransformDTL [ DependsOn = (EnsLib.HTTP.GenericMessage, Production.Message.ZooMessage) ]
{

Parameter IGNOREMISSINGSOURCE = 1;
Parameter REPORTERRORS = 1;
Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;
XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='EnsLib.HTTP.GenericMessage' targetClass='Production.Message.ZooMessage' create='new' language='objectscript' >
<assign value='source.HTTPHeaders' property='target.HTTPHeaders' action='set' />
<assign value='source.Stream.Read(1000000)' property='target.RequestJSON' action='set' />
<assign value='{}.%FromJSON(source.Stream).case' property='target.CaseId' action='set' />
</transform>
}

}

Um pouco mais volumoso, sim, mas funciona. Sem necessidade de danças rituais.

 

O Veredito?

  “- Ninguém matou um juiz. Nós somos donos de todos os juízes. Qual seria o sentido de matar um?

 

Honestamente, não consigo decidir. É por isso que estou escrevendo isso.

Então, aqui está uma pergunta para você:

  1. Devemos implorar à Intersystems para que eles consertem o código?
  2. Consertar nós mesmos com ferramentas enferrujadas e ética questionável?
  3. Aceitar o status quo atual e construir algo desajeitado, mas funcional?
  4. ?

A decisão é sua.

 

PS: O código dos exemplos acima está disponível neste repositório GitHub:https://github.com/banksiaglobal/http-rest-production

 

Aleksandr Kolesové um desenvolvedor de software experiente da Banksia Global com mais de 30 anos de experiência na indústria de tecnologia, especializado na plataforma InterSystems IRIS. Com um profundo conhecimento em gerenciamento de dados de alto desempenho e arquiteturas de aplicações com uso intensivo de dados, ele desempenhou um papel fundamental no desenvolvimento e otimização de aplicações para empresas em diversos setores. Ao longo dos anos, Alex ganhou uma reputação por sua expertise na construção de sistemas escaláveis e eficientes, bem como por sua paixão em orientar desenvolvedores em ascensão. Quando não está codificando ou resolvendo desafios técnicos complexos, Alex gosta de explorar novas tecnologias e contribuir para a crescente comunidade de desenvolvedores InterSystems.
 
   
Banksia Global é uma consultoria de tecnologia líder que se especializa em ajudar organizações a aproveitar todo o potencial de soluções modernas de gerenciamento de dados. Com um forte foco na plataforma InterSystems IRIS, a Banksia Global fornece orientação estratégica, integração de sistemas e serviços de desenvolvimento de software personalizado para clientes em diversos setores. Sua expertise reside na entrega de soluções escaláveis e de alto desempenho que permitem às empresas impulsionar a inovação, otimizar operações e desbloquear novas oportunidades. Conhecida por sua abordagem ágil colaborativa, a Banksia Global trabalha em estreita colaboração com os clientes para garantir que cada solução seja adaptada para atender às suas necessidades específicas, promovendo parcerias de longo prazo e crescimento sustentável.
Discussão (0)1
Entre ou crie uma conta para continuar