O blog da AWS

Modernização de aplicações SOAP usando o Amazon API Gateway e o AWS Lambda

Por Daniel Abib, Arquiteo Especialista de Soluções Senior na Amazon Web Services (AWS).

Esta publicação demonstra como você pode modernizar aplicações SOAP legadas usando o Amazon API Gateway e o AWS Lambda para criar arquiteturas de Proxy bidirecionais que permitem a integração entre protocolos SOAP e REST sem interromper as operações comerciais existentes.

Atualmente, muitas organizações enfrentam o desafio de manter sistemas comerciais essenciais que foram construídos décadas atrás. Essas aplicações legadas ainda impulsionam operações comerciais essenciais, apesar de dependerem de tecnologias e padrões de integração desatualizados. Embora a substituição completa do sistema seja ideal, restrições práticas, como limitações orçamentárias, disponibilidade de recursos, complexidade técnica e falta de documentação, muitas vezes tornam os esforços de modernização desafiadores.

Esta postagem mostra primeiro os padrões de arquitetura de Proxy para expor um servidor SOAP legado por meio de uma API REST. Em seguida, mostra como integrar um cliente SOAP legado a aplicativos usando uma API REST.

Embora as APIs SOAP e REST compartilhem o HTTP como base, o SOAP tem algumas limitações em comparação ao REST, como métodos HTTP limitados (somente GET/POST) e formatação XML obrigatória. O REST é mais flexível com vários métodos HTTP e diversos formatos de carga útil (texto simples, binário, HTML, JSON, XML).

Usando o API Gateway e o Lambda para Proxy do serviço SOAP

Considere uma solução legada que só ofereça suporte a SOAP. O diagrama a seguir mostra a arquitetura de um servidor Proxy SOAP usando o API Gateway e o Lambda.

Figura 1: Proxy de servidor SOAP para arquitetura modernizada

O Proxy expõe as APIs hospedadas no servidor SOAP (no lado direito da imagem) em uma interface REST. Um serviço SOAP espera o cabeçalho HTTP Content-Type definido como text/xml e uma carga no formato XML que siga a especificação WSDL definida pelo servidor.

Na arquitetura proposta, a função Lambda é o principal mecanismo de transformação, manipulando a conversão bidirecional entre os formatos JSON e XML. As funções do Lambda podem ser desenvolvidas em várias linguagens de programação, como Python, Node.js, Java, C#, Go, Ruby e PowerShell, permitindo que você use sua experiência de desenvolvimento existente. A natureza Serverless do Lambda fornece escalabilidade automática para lidar com picos de tráfego sem precisar de gerenciamento de infraestrutura ou planejamento de capacidade.

O API Gateway atua como a porta de entrada inteligente, gerenciando todas as solicitações recebidas e encaminhando-as adequadamente. Ele fornece recursos de nível corporativo, como limitação de solicitações para proteger os sistemas de back-end contra sobrecarga, mecanismos abrangentes de autenticação e autorização, gerenciamento de chaves de API para controle de acesso de parceiros, validação de solicitações e respostas, recursos de cache para melhorar o desempenho e monitoramento e registro detalhados. Esses recursos integrados eliminam a necessidade de desenvolvimento de middleware personalizado e fornecem benefícios operacionais imediatos. O API Gateway pode receber vários formatos de carga útil, como XML, JSON, dados binários e texto sem formatação. Isso o torna adequado para diversos cenários de integração.

Usando o API Gateway e o Lambda para oferecer suporte a clientes SOAP antigos

A seção anterior se concentrou em expor os serviços SOAP por meio de APIs REST. As organizações também enfrentam o desafio inverso, em que aplicativos clientes SOAP antigos precisam acessar os serviços REST. A arquitetura para dar suporte a clientes SOAP antigos segue um padrão semelhante, mas com fluxo de dados invertido. Nesse caso, o cliente SOAP legado envia solicitações em formato XML para o que ele acredita ser um servidor SOAP. No entanto, nos bastidores, o API Gateway e o Lambda trabalham juntos para traduzir essas solicitações em chamadas de API REST.

Figura 2: Arquitetura de modernização do cliente legado SOAP

O aplicativo cliente SOAP legado envia mensagens XML SOAP para o API Gateway. A função Lambda recebe essas solicitações SOAP, extrai os dados relevantes do envelope XML e os transforma no formato JSON para o serviço REST moderno.

A função Lambda agrupa a resposta JSON dos serviços REST no formato SOAP XML que o cliente legado espera. Ele recria a estrutura XML apropriada, os cabeçalhos SOAP e garante que a resposta esteja em conformidade com a especificação WSDL que o aplicativo cliente foi projetado para consumir.

Cenário de exemplo

Suponhamos que nosso aplicativo cliente antigo precise enviar uma solicitação SOAP para converter um número inteiro em sua forma de palavra. O envelope SOAP para converter o número 1519 em sua forma longa “mil quinhentos e dezenove” tem a seguinte aparência:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body> \
        <ConvertNumberToWordsSoapIn>
            <NumberToWordsRequest>1519</NumberToWordsRequest>
        </ConvertNumberToWordsSoapIn>
    </soap:Body>
</soap:Envelope>
XML

O serviço de conversão REST espera uma carga JSON da seguinte forma:

jsonObject = {
	"data" : 1519
}
JavaScript

O bloco de código a seguir mostra um exemplo de implementação da função Lambda para isso. Essa função converte o envelope XML SOAP em JSON, altera o cabeçalho http para application/json e converte a resposta do serviço REST para o formato SOAP.

var parseString = require('xml2js').parseString;
const axios = require('axios');

exports.handler = async (event, context) => {
    var valueNumber;
    
    try {
        console.log("Parsing XML string");

        // Parsing the XML to obtain data needed for conversion (number to words)
        parseString(event.body, function (err, result) {
            if (!err) {
                valueNumber = result['soap:Envelope']['soap:Body'][0]
                              ['ConvertNumberToWordsSoapIn'][0]
                              ['NumberToWordsRequest'][0];
            } else { 
                console.log (err);
                throw (err);
            }
        });
        console.log("Creating JSON for calling the service");
        // Creating JSON to call service
        var jsonObject = {
            "data" : valueNumber
        }
        
        console.log("Calling Microservice (NumberToWords)");
        const headers = { 
            'Content-Type': 'Application/json'
        };
        
        console.log ("Parameter for NumberToWords URL:" + 
                    JSON.stringify(process.env.NumberToWordMicroservice));

        // Calling numberToWords REST Server
        var resultNumberToWords = await 
            axios.post(process.env.NumberToWordMicroservice, jsonObject, { headers });
        
        // Creating the response
        console.log("Creating response XML");

        var resp =  create_response (JSON.stringify(resultNumberToWords.data.message));
        console.log("Response in XML: "+ resp);
        
        // Returning the value in XML using text/xml content type
        let response = {'statusCode': 200, headers: {"content-type": "text/xml"}, 
                        'body': JSON.stringify(resp)}
        return response;
        
    } catch (err) {
        console.log ("Error: " + err);
        let response = {'statusCode': 500, 
                        headers: {"content-type": "text/xml"}, 'body': err}
        return response;
    }
};

// Function to create a SOAP XML envelope with the result value
function create_response(numberInWords) {
  return '<?xml version="1.0" encoding="utf-8"?> \ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">\ <soap:Body>\ <m:ConvertNumberToWordsResponse xmlns:m="http://www.dataaccess.com/webservicesserver/"> \ <m:ConvertNumberToWordsResponseResult>' + numberInWords + '</m:ConvertNumberToWordsResponseResult> \ </m:ConvertNumberToWordsResponse> \ </soap:Body>\ </soap:Envelope>';
}
JavaScript

Com essa abordagem, você pode manter seus aplicativos cliente SOAP existentes sem modificações, permitindo que eles consumam serviços REST modernos. Você pode preservar os investimentos em aplicativos antigos do cliente e, ao mesmo tempo, modernizar gradualmente o sistema geral. Essa arquitetura é particularmente valiosa em cenários em que vários clientes SOAP antigos precisam acessar os mesmos serviços REST modernos. Isso ocorre porque um único Proxy pode atender a vários aplicativos clientes simultaneamente. A natureza Serverless da arquitetura garante que ela seja escalada automaticamente com base no número de solicitações do cliente, fornecendo uma operação econômica, independentemente dos padrões de uso.

Abordagem alternativa usando recursos de transformação do API Gateway

A abordagem baseada em Lambda fornece flexibilidade e controle máximos. O API Gateway também oferece recursos de transformação integrados que podem lidar com determinados cenários de modernização do SOAP sem a necessidade de recursos computacionais.

A transformação nativa do API Gateway usa modelos de mapeamento da Apache Velocity Template Language. Ele converte a carga útil (payload) diretamente no gateway, oferecendo uma solução simplificada para cenários específicos de modernização.

A abordagem VTL funciona definindo modelos de mapeamento que lidam com o processo de conversão entre diferentes formatos de carga útil. Ao modernizar os serviços SOAP, esses modelos podem interceptar solicitações REST com cargas JSON, reestruturar os dados no formato XML compatível com seus endpoints SOAP legados e reverter o processo de retorno das respostas ao cliente.

Figura 3: API Gateway com transformação da linguagem de modelo de velocidade

Essa estratégia de transformação nativa do gateway oferece várias vantagens operacionais. Você se beneficia da arquitetura simplificada porque a lógica de transformação reside inteiramente no serviço do API Gateway. Não há outros componentes de infraestrutura para gerenciar ou monitorar, e a solução evita a complexidade da coordenação entre vários serviços da AWS. A eficiência de custos é outro benefício importante, pois não há cobranças de computação além do preço padrão do API Gateway.

Considere o exemplo anterior de conversão de um número em seu formato de palavra. A transformação da VTL no API Gateway terá a seguinte aparência:

## Parse the SOAP envelope and extract the number value
#set(\$xmlDoc = \$input.path('\$'))
#set(\$numberToWords = \$xmlDoc.Envelope.Body.ConvertNumberToWordsSoapIn.NumberToWordsRequest)

## Convert to integer if it's a string
#if(\$numberToWords.toString().matches("^\d+\$"))
  #set(\$dataValue = \$numberToWords.toInteger())
#else
  #set(\$dataValue = \$numberToWords)
#end

{
  "data": \$dataValue
}
Code

Você deve considerar as transformações de VTL quando seus serviços SOAP têm esquemas previsíveis e estáveis com estruturas XML relativamente diretas. Essa abordagem funciona particularmente bem para sistemas legados que raramente sofrem alterações e têm padrões claros de solicitação-resposta. Para ambientes mais dinâmicos ou requisitos complexos de transformação, a solução baseada em Lambda oferece flexibilidade e capacidade de manutenção superiores.

Considerações de segurança

Uma consideração importante ao trabalhar com serviços SOAP antigos é entender seus mecanismos de autenticação. Os protocolos SOAP geralmente implementam a autenticação por meio de padrões de segurança, nos quais as credenciais de autenticação e os tokens de segurança são incorporados diretamente nos cabeçalhos do envelope SOAP. Isso inclui tokens de nome de usuário, assinaturas digitais e elementos de criptografia que fazem parte da estrutura XML.

Quando os envelopes SOAP contêm informações de autenticação não criptografadas nos cabeçalhos, a arquitetura do proxy normalmente funciona sem mais modificações. Isso ocorre porque a função Lambda pode passar por esses elementos de autenticação de forma transparente para o serviço SOAP de backend. No entanto, devido à natureza da autenticação SOAP estar totalmente integrada à estrutura do envelope XML, certos cenários podem precisar de tratamento personalizado na função Lambda.

Por exemplo, se o serviço SOAP usa tokens de autenticação baseados em carimbo de data/hora (timestamp), gerenciamento de sessão ou precisa de modificações específicas no cabeçalho de segurança, a função Lambda pode precisar de personalização para manipular, validar ou atualizar adequadamente esses elementos de autenticação durante o processo de transformação de JSON para XML. As organizações devem analisar cuidadosamente seus requisitos de autenticação do serviço SOAP para determinar se é necessária mais lógica Lambda para manter a conformidade de segurança.

Além disso, certifique-se de que todas as credenciais de autenticação SOAP processadas pela função Lambda sejam tratadas com segurança e nunca sejam registradas em texto simples.

Conclusão

Nesta postagem, você aprendeu como os serviços nativos da nuvem podem preencher a lacuna entre sistemas legados e arquiteturas de aplicativos modernas, permitindo que você mantenha suas aplicações existentes enquanto adota práticas e tecnologias de desenvolvimento mais modernas.

O Amazon API Gateway e o AWS Lambda permitem que as organizações criem serviços REST que servem como proxy de servidores SOAP legados, permitindo que aplicativos modernos consumam serviços legados por meio de cargas JSON, preservando a infraestrutura SOAP existente. Essa solução Serverless oferece economia, escalabilidade automática e redução da sobrecarga operacional, ao mesmo tempo em que facilita a modernização da empresa por meio de APIs escaláveis sem abandonar os investimentos antigos em software.

Essa estratégia de modernização permite que você faça a transição gradual dos serviços SOAP legados para as APIs REST modernas sem interromper as operações comerciais existentes. À medida que sua jornada de modernização progride, você pode estender esse padrão para oferecer suporte a mais serviços SOAP ou implementar uma lógica de transformação mais sofisticada com base em seus requisitos comerciais específicos.

Para obter mais recursos de aprendizado sem servidor, visite Serverless Land.

Este conteúdo foi traduzido da postagem original do blog, que pode ser encontrada aqui.

Biografia do Autor

Daniel Abib é Arquiteto de Soluções Sênior e Especialista em Amazon Bedrock na AWS, com mais de 25 anos trabalhando com gerenciamento de projetos, arquiteturas de soluções escaláveis, desenvolvimento de sistemas e CI/CD, microsserviços, arquitetura Serverless & Containers e especialização em Machine Learning. Ele trabalha apoiando Startups, ajudando-os em sua jornada para a nuvem.

https://www.linkedin.com/in/danielabib/

Biografia do tradutores

Daniel Abib é Arquiteto de Soluções Sênior e Especialista em Amazon Bedrock na AWS, com mais de 25 anos trabalhando com gerenciamento de projetos, arquiteturas de soluções escaláveis, desenvolvimento de sistemas e CI/CD, microsserviços, arquitetura Serverless & Containers e especialização em Machine Learning. Ele trabalha apoiando Startups, ajudando-os em sua jornada para a nuvem.

https://www.linkedin.com/in/danielabib/

Rodrigo Peres é Arquiteto de Soluções na AWS, com mais de 20 anos de experiência trabalhando com arquitetura de soluções, desenvolvimento de sistemas e modernização de sistemas legados.