
Solicitação no Connexus (Parte 6): Criando uma Requisição e Resposta HTTP
Introdução
Este artigo faz parte de uma série em andamento onde estamos construindo uma biblioteca chamada Connexus. No primeiro artigo, abordamos a funcionalidade básica da função WebRequest, entendendo cada um de seus parâmetros e criando um código de exemplo que demonstra seu uso e os desafios associados. No artigo anterior, exploramos o que são métodos HTTP e os códigos de status retornados pelo servidor, indicando se a requisição foi processada com sucesso ou se houve um erro no lado do cliente ou do servidor.
Neste sexto artigo da série da biblioteca Connexus, focamos em uma requisição HTTP completa, cobrindo cada componente que compõe uma requisição. Criamos uma classe que representa a requisição como um todo, o que nos ajudou a reunir as classes criadas anteriormente. Além disso, desenvolvemos uma classe semelhante para lidar com a resposta do servidor, contendo os dados da resposta, o código de status e até mesmo a duração da requisição.
Na comunicação HTTP, uma requisição é composta por vários componentes que juntos formam a requisição completa. Já exploramos todos esses componentes em artigos anteriores e criamos classes individuais para cada elemento da requisição. Vamos recapitular os elementos abaixo:
- URL: Define o endereço do servidor na web e é composta por partes menores como domínio, porta, caminho etc. Isso foi abordado em mais detalhes na Parte 2 do Connexus, onde criamos uma classe para formatar corretamente uma URL.
- Cabeçalho: São dados adicionais enviados junto com a requisição, destinados a fornecer detalhes sobre a requisição que não fazem parte do corpo ou da URL. Isso foi abordado em mais detalhes na Parte 3 do Connexus, onde também criamos uma classe responsável por organizar o cabeçalho da requisição.
- Corpo: Refere-se ao conteúdo real que está sendo enviado ou recebido. Simplificando, o corpo é onde ficam armazenados os dados que nos interessam, que queremos enviar ao servidor. Na Parte 4, discutimos isso em mais detalhes e também criamos uma classe responsável por armazenar o corpo da requisição, que suporta adicionar o corpo em diferentes formatos, como texto simples (string), JSON ou char[] (binário).
- Método HTTP: Os métodos HTTP são usados pelo cliente para informar ao servidor qual ação deseja executar. Isso foi discutido em mais detalhes na Parte 5 do Connexus.
- Timeout: O tempo limite não foi abordado em artigos anteriores, mas, explicando brevemente, é o tempo em milissegundos que o servidor tem para responder. Se a requisição levar mais do que o tempo estipulado, ela é encerrada, resultando em um erro de timeout. Esse valor pode ser útil para evitar cenários em que o servidor demore muito para responder, já que a função WebRequest é síncrona, ou seja, o Expert Advisor fica “pausado” enquanto aguarda a resposta do servidor. Isso pode ser problemático se a requisição levar muito mais tempo do que o esperado. Para evitar esse cenário, recomenda-se o uso de timeout. O valor do timeout pode variar dependendo da sua necessidade, mas para a maioria dos servidores, 5000 milissegundos (5 segundos) são suficientes para que a requisição seja processada corretamente.
Cada um desses componentes desempenha um papel fundamental na construção de uma requisição HTTP adequada, mas é importante observar que nem todos são obrigatórios. Os únicos elementos obrigatórios são a URL e o método HTTP (GET, POST, PUT etc.).
Para nos guiar sobre o progresso da biblioteca e as classes que já criamos, vamos dar uma olhada no diagrama atual da biblioteca:
Observe que já temos classes prontas para lidar com Métodos HTTP, Códigos de Status, URLs com parâmetros de consulta, Cabeçalhos e o Corpo.
Padrão de Projeto Facade
Para continuar construindo a biblioteca, implementaremos um padrão de projeto. Se você não está familiarizado com padrões de projeto, recomendo a leitura da série de artigos Padrões de Projeto em Desenvolvimento de Software e MQL5, escrita por Mohamed Abdelmaaboud. Nessa série, o autor descreve vários padrões de projeto com códigos de exemplo. Para a biblioteca Connexus, implementaremos o padrão de projeto “Facade”, que é um padrão bem conhecido na programação. Esse padrão fornece uma interface simplificada para um conjunto mais complexo de subsistemas, ocultando a complexidade interna e permitindo que o cliente interaja com o sistema de uma forma muito mais simples.
Vamos imaginar um exemplo no contexto da biblioteca: você quer criar uma requisição. Para isso, você precisaria criar uma instância de cada um dos elementos da requisição e configurá-los, algo como isto:
CURL m_url; m_url.Parse("http://example.com/api"); CHttpBody m_body; m_body.AddString("my text"); CHttpHeader m_headers; m_headers.Add("content-type","text/plain"); CHttpMethod m_method; m_method = HTTP_METHOD_GET; int m_timeout = 5000;
Essa abordagem torna o código poluído, exigindo a criação de múltiplas instâncias, consumindo muitas linhas e deixando o código menos legível. A situação piora ao trabalhar com várias requisições, já que gerenciar múltiplos objetos como cabeçalhos, corpo e URL se torna complicado e difícil de manter. É aqui que o padrão de projeto Facade entra em cena. Voltando ao conceito: Esse padrão fornece uma interface simplificada para um conjunto mais complexo de subsistemas, ocultando a complexidade interna e permitindo que o cliente interaja com o sistema de uma forma muito mais simples.
Nesse contexto, os subsistemas são as classes para elementos de requisição como CHttpBody, CHttpHeaders etc., e o objetivo é criar uma interface mais intuitiva para eles. Esse padrão resolve o problema introduzindo uma classe ou interface que atua como uma “Facade” para acessar os subsistemas. O desenvolvedor final interage apenas com essa interface simplificada.
Em resumo, a arquitetura Facade oferece os seguintes benefícios:
- Interação Simplificada: Em vez de lidar diretamente com uma série de classes complexas, o desenvolvedor pode usar uma interface simplificada que oculta os detalhes internos.
- Acoplamento Reduzido: Como o cliente não fica acoplado diretamente aos subsistemas internos, mudanças nesses subsistemas podem ser feitas sem afetar o cliente.
- Melhor Manutenibilidade: A separação clara entre a interface Facade e os subsistemas internos torna o código mais fácil de manter e expandir, já que quaisquer mudanças internas podem ser abstraídas pela fachada.
Como esse padrão de projeto seria implementado na biblioteca? Para isso, criaremos uma nova classe chamada CHttpRequest, que conterá os subsistemas. Para o usuário da biblioteca, o uso dessa classe deve se parecer com isto:
CHttpRequest request; request.Method() = HTTP_METHOD_GET; request.Url().Parse("http://example.com/api"); request.Body().AddString("my text"); request.Header().Add("content-type","text/plain");
Perceba como o código ficou muito mais simples e legível, que é exatamente a ideia por trás desse padrão de projeto. O padrão Facade fornece uma interface simplificada (CHttpRequest) para um conjunto mais complexo de subsistemas (gerenciando instâncias de CHttpBody, CHttpHeader etc.), ocultando a complexidade interna e permitindo que o cliente interaja com o sistema de uma forma muito mais simples.
Criando a Classe CHttpRequest
Agora que entendemos o conceito de Facade, podemos aplicar essa arquitetura à classe CHttpRequest. Vamos criar essa classe dentro de uma nova pasta chamada core. O arquivo se chamará HttpRequest.mqh, e o caminho final será Include/Connexus/Core/HttpRequest.mqh. Inicialmente, o arquivo ficará assim://+------------------------------------------------------------------+ //| HttpRequest.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpRequest | //| | //| [PROPERTY] | //| Name : CHttpRequest | //| Heritage : No heritage | //| Description : Gathers elements of an http request such as url, | //| body, header, method and timeout | //| | //+------------------------------------------------------------------+ class CHttpRequest { public: CHttpRequest(void); ~CHttpRequest(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpRequest::CHttpRequest(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpRequest::~CHttpRequest(void) { } //+------------------------------------------------------------------+
Vamos importar as classes criadas nos últimos arquivos: CURL, CHttpBody, CHttpHeader e CHttpMethod. Criaremos uma instância de cada uma, adicionando o "*" para informar ao compilador que gerenciaremos o ponteiro manualmente. Além disso, adicionaremos uma variável chamada m_timeout do tipo int, que armazenará o valor de timeout da requisição.
//+------------------------------------------------------------------+ //| HttpRequest.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "../URL/URL.mqh" #include "../Header/HttpBody.mqh" #include "../Header/HttpHeader.mqh" #include "../Constants/HttpMethod.mqh" //+------------------------------------------------------------------+ //| class : CHttpRequest | //| | //| [PROPERTY] | //| Name : CHttpRequest | //| Heritage : No heritage | //| Description : Gathers elements of an http request such as url, | //| body, header, method and timeout | //| | //+------------------------------------------------------------------+ class CHttpRequest { private: CURL *m_url; CHttpBody *m_body; CHttpHeader *m_headers; CHttpMethod *m_method; int m_timeout; public: CHttpRequest(void); ~CHttpRequest(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpRequest::CHttpRequest(void) { m_url = new CURL(); m_body = new CHttpBody(); m_headers = new CHttpHeader(); m_method = new CHttpMethod(); m_timeout = 5000; // Default timeout (5 seconds) } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpRequest::~CHttpRequest(void) { delete m_url; delete m_body; delete m_headers; delete m_method; } //+------------------------------------------------------------------+
Agora, vamos adicionar alguns métodos para acessar o ponteiro de cada instância, bem como métodos para definir e obter o valor de timeout:
- CURL *Url(void): Retorna o ponteiro para a URL
- CHttpBody *Body(void): Retorna o ponteiro para o corpo
- CHttpHeader *Header(void): Retorna o ponteiro para o cabeçalho
- CHttpMethod *Method(void): Retorna o ponteiro para o método
- CHttpRequest *Timeout(int timeout): Define o timeout
- int Timeout(void): Obtém o timeout
Além desses métodos, adicionaremos alguns métodos auxiliares:
-
void Clear(void): Remove todos os dados das instâncias
-
string FormatString(void): Gera uma string contendo todos os dados da requisição
Exemplo de uma requisição formatada:
HTTP Request: --------------- Method: GET URL: https://api.example.com/resource?id=123&filter=active Headers: --------------- Authorization: Bearer token Content-Type: application/json User-Agent: MyHttpClient/1.0 Body: --------------- { "key": "value", "data": [1, 2, 3] } ---------------
Aqui está a implementação dos métodos.
//+------------------------------------------------------------------+ //| HttpRequest.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpRequest | //| | //| [PROPERTY] | //| Name : CHttpRequest | //| Heritage : No heritage | //| Description : Gathers elements of an http request such as url, | //| body, header, method and timeout | //| | //+------------------------------------------------------------------+ class CHttpRequest { public: //--- HTTP CURL *Url(void); // Get url object CHttpBody *Body(void); // Get body object CHttpHeader *Header(void); // Get header object CHttpMethod *Method(void); // Get method object //--- Timeout CHttpRequest *Timeout(int timeout); // Set timeout int Timeout(void); // Get timeout //--- Auxiliary methods void Clear(void); // Reset data string FormatString(void); // Format data }; //+------------------------------------------------------------------+ //| Get url object | //+------------------------------------------------------------------+ CURL *CHttpRequest::Url(void) { return(GetPointer(m_url)); } //+------------------------------------------------------------------+ //| Get body object | //+------------------------------------------------------------------+ CHttpBody *CHttpRequest::Body(void) { return(GetPointer(m_body)); } //+------------------------------------------------------------------+ //| Get header object | //+------------------------------------------------------------------+ CHttpHeader *CHttpRequest::Header(void) { return(GetPointer(m_headers)); } //+------------------------------------------------------------------+ //| Get method object | //+------------------------------------------------------------------+ CHttpMethod *CHttpRequest::Method(void) { return(GetPointer(m_method)); } //+------------------------------------------------------------------+ //| Set timeout | //+------------------------------------------------------------------+ CHttpRequest *CHttpRequest::Timeout(int timeout) { m_timeout = timeout; return(GetPointer(this)); } //+------------------------------------------------------------------+ //| Get timeout | //+------------------------------------------------------------------+ int CHttpRequest::Timeout(void) { return(m_timeout); } //+------------------------------------------------------------------+ //| Reset data | //+------------------------------------------------------------------+ void CHttpRequest::Clear(void) { m_url.Clear(); m_body.Clear(); m_headers.Clear(); m_timeout = 5000; } //+------------------------------------------------------------------+ //| Format data | //+------------------------------------------------------------------+ string CHttpRequest::FormatString(void) { return( "HTTP Request:"+ "\n---------------"+ "\nMethod: "+m_method.GetMethodDescription()+ "\nURL: "+m_url.FullUrl()+ "\n"+ "\n---------------"+ "\nHeaders:"+ "\n"+m_headers.Serialize()+ "\n"+ "\n---------------"+ "\nBody:"+ "\n"+m_body.GetAsString()+ "\n---------------" ); } //+------------------------------------------------------------------+
Assim, concluímos esta classe, que serve como uma fachada para acessar os objetos que formam uma requisição HTTP. É importante observar que estou adicionando apenas as partes que foram modificadas no código. O arquivo completo pode ser encontrado ao final do artigo anexado.
Com essa nova classe CHttpRequest, o diagrama atualizado da biblioteca fica assim:
Em resumo, a CHttpRequest atua como uma fachada, simplificando o processo de configurar e enviar uma requisição HTTP. Internamente, a classe CHttpHeaders lida com a lógica de cabeçalhos, enquanto a CHttpBody cuida da construção do corpo da requisição. O desenvolvedor que usa esta biblioteca não precisa se preocupar com os detalhes de como os cabeçalhos ou o corpo são manipulados — ele simplesmente define os valores usando os métodos de CHttpRequest, e a classe fachada cuida do restante.
Criando a Classe CHttpResponse
Seguindo a mesma ideia, vamos criar outra classe que será usada para representar os dados da resposta do servidor. Ela seguirá uma estrutura semelhante à CHttpRequest. Estes são os elementos que compõem uma resposta:
- Cabeçalho: Assim como na requisição, a resposta também inclui um cabeçalho, que informa ao cliente metadados sobre a requisição.
- Corpo: Aqui ficará o corpo da resposta do servidor. É onde o servidor envia os dados que queremos obter, sendo o núcleo da mensagem.
- Código de Status: Contém o código de status, que discutimos em mais detalhes na Parte 5 da série. Esse código é um número de 3 dígitos que informa se a requisição foi processada com sucesso ou se encontrou um erro do cliente ou do servidor.
- Duração: Armazena o tempo que a requisição levou para ser concluída, medido em milissegundos.
Criaremos um novo arquivo dentro da pasta core chamado HttpResponse, e o caminho final será Include/Connexus/Core/HttpResponse.mqh. A classe criada deve se parecer com isto:
//+------------------------------------------------------------------+ //| HttpResponse.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpResponse | //| | //| [PROPERTY] | //| Name : CHttpResponse | //| Heritage : No heritage | //| Description : gathers elements of an http response such as body, | //| header, status code and duration | //| | //+------------------------------------------------------------------+ class CHttpResponse { public: CHttpResponse(void); ~CHttpResponse(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpResponse::CHttpResponse(void) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpResponse::~CHttpResponse(void) { } //+------------------------------------------------------------------+
Importaremos os elementos de uma resposta, que são: CHttpHeader, CHttpBody e CHttpStatusCode. Em seguida, criaremos uma instância de cada uma dessas classes e também uma variável privada do tipo ulong, que armazenará a duração da requisição. O código final ficará assim:
//+------------------------------------------------------------------+ //| HttpResponse.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "../Constants/HttpStatusCode.mqh" #include "../Header/HttpBody.mqh" #include "../Header/HttpHeader.mqh" //+------------------------------------------------------------------+ //| class : CHttpResponse | //| | //| [PROPERTY] | //| Name : CHttpResponse | //| Heritage : No heritage | //| Description : gathers elements of an http response such as body, | //| header, status code and duration | //| | //+------------------------------------------------------------------+ class CHttpResponse { private: CHttpHeader *m_header; CHttpBody *m_body; CHttpStatusCodes *m_status_code; ulong m_duration; public: CHttpResponse(void); ~CHttpResponse(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CHttpResponse::CHttpResponse(void) { m_header = new CHttpHeader(); m_body = new CHttpBody(); m_status_code = new CHttpStatusCodes(); m_duration = 0; // Reset duration } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CHttpResponse::~CHttpResponse(void) { delete m_header; delete m_body; delete m_status_code; } //+------------------------------------------------------------------+
Agora vamos avançar para os métodos que serão adicionados a essa classe. Começaremos pelos mais simples, que apenas retornam os ponteiros de cada uma das instâncias das classes, e métodos para definir e obter a duração:
- CHttpHeader *Header(void): Retorna o ponteiro para o cabeçalho.
- CHttpBody *Body(void): Retorna o ponteiro para o corpo.
- CHttpStatusCodes *StatusCode(void) : Retorna o ponteiro para o código de status.
- void Duration(ulong duration) : Define a duração.
- ulong Duration(void) : Obtém a duração.
Criaremos os mesmos métodos auxiliares de CHttpRequest para esta classe:
-
void Clear(void) : Remove todos os dados das instâncias.
-
string FormatString(void) : Gera uma string contendo todos os dados da resposta.
Exemplo de uma resposta formatada
HTTP Response: --------------- Status Code: 200 OK Duration: 120ms Headers: --------------- Content-Type: application/json Content-Length: 256 Server: Apache/2.4.41 (Ubuntu) Date: Wed, 02 Oct 2024 12:34:56 GMT Body: --------------- { "message": "Success", "data": { "id": 123, "name": "Sample Item", "status": "active" } } ---------------
Aqui está o código com a implementação dessas funções:
//+------------------------------------------------------------------+ //| HttpResponse.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| class : CHttpResponse | //| | //| [PROPERTY] | //| Name : CHttpResponse | //| Heritage : No heritage | //| Description : gathers elements of an http response such as body, | //| header, status code and duration | //| | //+------------------------------------------------------------------+ class CHttpResponse { public: //--- HTTP CHttpHeader *Header(void); // Get header object CHttpBody *Body(void); // Get body object CHttpStatusCodes *StatusCode(void); // Get status code object //--- Duration void Duration(ulong duration); // Set duration ulong Duration(void); // Get duration //--- Auxiliary methods void Clear(void); // Reset data string FormatString(void); // Format data }; //+------------------------------------------------------------------+ //| Get header object | //+------------------------------------------------------------------+ CHttpHeader *CHttpResponse::Header(void) { return(GetPointer(m_header)); } //+------------------------------------------------------------------+ //| Get body object | //+------------------------------------------------------------------+ CHttpBody *CHttpResponse::Body(void) { return(GetPointer(m_body)); }; //+------------------------------------------------------------------+ //| Get status code object | //+------------------------------------------------------------------+ CHttpStatusCodes *CHttpResponse::StatusCode(void) { return(GetPointer(m_status_code)); }; //+------------------------------------------------------------------+ //| Set duration | //+------------------------------------------------------------------+ void CHttpResponse::Duration(ulong duration) { m_duration = duration; } //+------------------------------------------------------------------+ //| Get duration | //+------------------------------------------------------------------+ ulong CHttpResponse::Duration(void) { return(m_duration); } //+------------------------------------------------------------------+ //| Reset data | //+------------------------------------------------------------------+ void CHttpResponse::Clear(void) { m_header.Clear(); m_body.Clear(); m_status_code.SetStatusCode(HTTP_STATUS_URL_NOT_ALLOWED); } //+------------------------------------------------------------------+ //| Format data | //+------------------------------------------------------------------+ string CHttpResponse::FormatString(void) { return( "HTTP Response:"+ "\n---------------"+ "\nStatus Code: "+m_status_code.GetStatusCodeFormat()+ "\nDuration: "+IntegerToString(m_duration)+" ms"+ "\n"+ "\n---------------"+ "\nHeaders:"+ "\n"+m_header.Serialize()+ "\n---------------"+ "\nBody:"+ "\n"+m_body.GetAsString()+ "\n---------------" ); } //+------------------------------------------------------------------+
Apenas para lembrar, aqui estou incluindo somente as alterações da classe para que o artigo não fique muito extenso. Todo o código utilizado está anexado ao final do artigo.
Com isso, concluímos a classe de resposta. Essas são classes relativamente simples, e o objetivo é um só: agrupar os elementos de uma requisição ou resposta. Dessa forma, podemos trabalhar com uma requisição como um único objeto, simplificando significativamente o uso de requisições e respostas HTTP. Com essa nova classe CHttpResponse, o diagrama atualizado fica assim:
Exemplos de uso
De forma breve, darei alguns exemplos de uso dessas classes. Começando com a CHttpRequest, construirei uma requisição HTTP usando essa classe.
//--- Example 1 - GET CHttpRequest request; request.Method() = HTTP_METHOD_GET; request.Url().Parse("http://example.com/api/symbols"); //--- Example 2 - POST CHttpRequest request; request.Method() = HTTP_METHOD_POST; request.Url().Parse("http://example.com/api/symbols"); request.Body().AddToString("{\"EURUSD\":1.08312}"); request.Header().Add("content-type","application/json"); //--- Example 3 - DELETE CHttpRequest request; request.Method() = HTTP_METHOD_DELETE; request.Url().Parse("http://example.com/api/symbols?symbol=EURUSD");
A grande vantagem aqui é a simplicidade de criar uma requisição, adicionar um cabeçalho e corpo ou alterar o método HTTP.
Para as respostas, o que precisamos é do oposto disso, ou seja, em vez de criar um objeto de requisição facilmente, queremos ler um objeto de resposta facilmente — e ambos funcionam de maneira semelhante, o que permite criação e leitura simples. Incluirei uma imagem mostrando como fica a tela do desenvolvedor ao usar o Connexus:
Note que podemos acessar o corpo da resposta em diferentes formatos, como string, JSON ou binário. Aqui acessamos diretamente o ponteiro da classe CHttpBody e, em seguida, acessamos todos os métodos que ela possui. Quando criamos uma classe para cada um desses elementos de uma resposta, eu já estava pensando em chegar a essa parte da biblioteca, onde utilizamos cada uma das classes.
Conclusão
Neste artigo, exploramos a importância de ter um objeto CHttpRequest que agrupe todos os componentes de uma requisição HTTP, garantindo clareza, reutilização e fácil manutenção do código. Também vimos como o padrão de projeto Facade pode ser aplicado para simplificar a interação com componentes complexos, ocultando a complexidade interna e oferecendo uma interface limpa e eficiente. No contexto do Connexus, aplicar o padrão Facade à classe CHttpRequest facilita a criação de requisições HTTP completas, simplificando o processo para o desenvolvedor, além de criar a classe CHttpResponse que segue o mesmo formato, mas deve facilitar o acesso aos dados de uma resposta HTTP.
No próximo artigo, vamos aprofundar na camada de transporte, que deve receber um objeto CHttpRequest e converter os dados para a função WebRequest, que é a camada final da biblioteca.Ela deve ser capaz de processar os dados da resposta e retornar um objeto do tipo CHttpResponse para que o desenvolvedor então utilize os dados da resposta. Até lá!
Traduzido do Inglês pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/en/articles/16182
Aviso: Todos os direitos sobre esses materiais pertencem à MetaQuotes Ltd. É proibida a reimpressão total ou parcial.
Esse artigo foi escrito por um usuário do site e reflete seu ponto de vista pessoal. A MetaQuotes Ltd. não se responsabiliza pela precisão das informações apresentadas nem pelas possíveis consequências decorrentes do uso das soluções, estratégias ou recomendações descritas.






- Aplicativos de negociação gratuitos
- 8 000+ sinais para cópia
- Notícias econômicas para análise dos mercados financeiros
Você concorda com a política do site e com os termos de uso