Você está na página 1de 40

Criando Web Services de Alto Desempenho com

Delphi

Esta é a sua cópia pessoal da apostila

Olá! É com grande satisfação que lhe disponibilizamos esta apostila


sobre o tema Criando Web Services de Alto Desempenho com Delphi.

ATENÇÃO: Este material está sendo liberado de forma gratuita do jeito que esta. Perdoe as
eventuais lacunas – Este material está licenciado sob os termos da CopyLeft

Por conta de um compromisso em poupar recursos e contribuir por um


mundo melhor não imprimiremos o material e acreditamos que em geral não
há necessidade de se fazer isto. Por isto esta é uma cópia pessoal do material.

Esperamos que você compartilhe este material com seus colegas.

Sugestões de melhoria serão sempre bem vindas!

Muito obrigado pelo prestígio de sua companhia.

Sobre esta apostila

Versão: 003 - Junho/2014


Revisor: José Mário Silva Guedes

Sobre a arrayOF

A arrayOF Consultoria e Treinamento tem por filosofia desenvolver o


potencial de seus parceiros ensinando e aprendendo com eles.

1 de 40
Criando Web Services de Alto Desempenho com
Delphi

Sumário
Esta é a sua cópia pessoal da apostila ...................................................................... 1
Sobre esta apostila ........................................................................................................ 1
Sobre a arrayOF ............................................................................................................. 1
Material de apoio .......................................................................................................... 4
Introdução ...................................................................................................................... 4
Protocolo de Transporte X Protocolo de Comunicação ......................................... 6
TCP/IP – Protocolo de Transporte ............................................................................. 6
HTTP – Protocolo de Comunicação ........................................................................ 7
Momento mão na massa: Criando o seu próprio protocolo .............................. 7
SOA – Arquitetura Orientada a Serviço ...................................................................... 8
Provedor ...................................................................................................................... 8
Consumidor ................................................................................................................. 8
Comunicação ............................................................................................................ 9
ROA - Arquitetura Orientada a Recursos ................................................................... 9
Entendendo o HTTP para entender o REST ................................................................. 9
Web Humana X Web Programável ....................................................................... 10
HTTP ............................................................................................................................. 10
REST ............................................................................................................................. 11
Estado Representacional .................................................................................... 11
Roy Fielding e Tim Berners-Lee ............................................................................ 12
Dissecando o protocolo HTTP sob o ponto de vista do REST ............................. 12
Regras gerais do protocolo HTTP ........................................................................ 13
Momento mão na massa........................................................................................ 18
Dominando o JSON ..................................................................................................... 19
Estrutura do JSON ................................................................................................. 19
Interagindo com o JSON pelo Delphi................................................................ 23
Momento mão na massa: Recuperando o aniversário e as fotos dos seus
amigos do Facebook ........................................................................................... 24
Serialização de objetos ............................................................................................... 26
ORM – Mapeamento Objeto – Relacional ........................................................... 27
DataSnap ...................................................................................................................... 28
No que o DataSnap se apoia? .............................................................................. 29
Mas... .......................................................................................................................... 29

2 de 40
Criando Web Services de Alto Desempenho com
Delphi

Existe alternativas ao DataSnap? .......................................................................... 30


DataSnap TCP/IP X DataSnap REST ....................................................................... 30
Momento mão na massa: Nosso “Olá Mundo” em três camadas! ................. 31
Componentes envolvidos em um servidor DataSnap ........................................ 32
Funcionamento geral de um servidor DataSnap/REST....................................... 33
Manipulando as requisições e respostas HTTP ..................................................... 33
DSServerClass e a Classe manipuladora de requisições HTTP ....................... 34
Conteúdo JSON .................................................................................................... 35
Hackeando a resposta de um servidor DataSnap/REST................................. 35
Manipulando a QueryString da URL................................................................... 36
Explorando algumas possibilidades ...................................................................... 36
Cache: Evitando armazenamento das informações pelos browsers e
proxies..................................................................................................................... 36
Modularização de um servidor DataSnap ............................................................... 38
Pool de Conexões com o Banco de Dados ............................................................ 39
Para aprender mais ..................................................................................................... 40
Livros recomendados .................................................................................................. 40

3 de 40
Criando Web Services de Alto Desempenho com
Delphi

Material de apoio

Todos os códigos dos exemplos citados nesta apostila estão disponíveis


no GitHub:

https://github.com/arrayOF/criando_web_services_alto_desempenho.git

Introdução

Existe uma grande mudança em curso: estamos saindo da era das


soluções on premisse para as soluções in cloud.

Esta mudança, que esta se acelerando cada vez mais, exige mudanças
drásticas na forma como encaramos o desenvolvimento de software.

Isto porque o usuário final quer a informação onde ele, o usuário, estiver.
A necessidade de se possuir um servidor dedicado esta fazendo tanto sentido
quanto a de um mainframe.

Nós, desenvolvedores, precisamos nos reposicionar.

Esta apostila trata deste assunto. Como nós, desenvolvedores Delphi,


podemos nos adaptar a esta nova realidade? Como tirar o melhor da
ferramenta e atender às demandas atuais?

Algo que se deve ter em mente é que o Delphi não esta sozinho. Uma
grande solução necessariamente envolve outras tecnologias. Ainda nesta
apostila conheceremos um pouco de:

 Apache;
 Python;
 noSQL e mongoDB;

É importante alinharmos as expectativas desde já em relação ao


assunto principal, o Delphi. Como ele se posiciona neste novo cenário?

Obviamente temos o DataSnap como tecnologia oficial da


Embarcadero para soluções multi camadas. Porém para entender o
funcionamento do DataSnap é necessário entender os conceitos que o
sustenta e é este o objetivo primordial deste treinamento.

4 de 40
Criando Web Services de Alto Desempenho com
Delphi

Para isto vamos nos concentrar em quatro pilares de um framework


REST:

 Protocolo de Comunicação – HTTP;


 Representação da Informação – JSON;
 Processamento concorrente e suas implicações – Thread;
 Orientação à Objeto e Metaprogramação com RTTI;

5 de 40
Criando Web Services de Alto Desempenho com
Delphi

Protocolo de Transporte X Protocolo de Comunicação

Antes de iniciarmos de fato faz diferença entender uma questão que é


abstrata a muitos programadores (e tem que ser abstrato, pois já temos
preocupações demais).

Vamos falar muito de HTTP durante o treinamento. E o TCP/IP?

O DataSnap aumenta ainda mais esta confusão ao oferecer dois


protocolos: TCP e HTTP. Mas na verdade um não anula o outro.

TCP/IP – Protocolo de Transporte

Não vamos nos aprofundar, pois foge ao escopo do treinamento. Mas é


importante entender que o protocolo TCP/IP é um protocolo de transporte
entre os equipamentos de uma rede padrão Ethernet.

TCP Protocolo de Controle de Transmissão


IP Protocolo de Internet

Então quando uma mensagem sai de um equipamento a outro é este


protocolo que garante que a mensagem chegará ao seu destino, mesmo que
passe por dezenas de equipamentos e softwares como roteadores, switchs,
proxies e por ai vai.

É um mecanismo fantástico e vale a pena estudar! A piada a seguir dá


uma ideia do que estamos falando:

Computador 1: Olá, eu gostaria de ouvir uma piada TCP


Computador 2: Olá, você gostaria de ouvir uma piada TCP?
Computador 1: Sim, eu gostaria de ouvir uma piada TCP
Computador 2: Ok, eu vou lhe contar uma piada TCP
Computador 1: Ok, eu irei ouvir uma piada TCP
Computador 2: Você está pronto para ouvir uma piada TCP?
Computador 1: Sim, eu estou pronto para ouvir uma piada TCP
Computador 2: Ok, estou prestes a lhe enviar uma piada TCP. Ela irá
durar 10 segundos, tem dois caracteres, não possui um contexto,
termina com uma punchline.
Computador 1: Ok, estou pronto para receber a sua piada TCP que irá
durar 10 segundos, tem dois caracteres, não possui um contexto
explícito, e termina com uma punchline.
Computador 2: Desculpe, a sua conexão expirou. Olá, você gostaria de
ouvir uma piada TCP?
http://www.dicas-l.com.br/arquivo/piada_tcp.php#.U-wWNfldWYA

6 de 40
Criando Web Services de Alto Desempenho com
Delphi

HTTP – Protocolo de Comunicação

Já o HTTP, assim como outros (FTP, SMTP e por ai vai) que é o objeto
central dos nossos estudos é um protocolo de comunicação entre softwares. É
como se fosse uma “língua”.

As informações contidas em uma mensagem HTTP trafegam via TCP/IP


de uma máquina à outra.

Quando os pacotes TCP/IP finalmente chegam ao software destinatário,


a mensagem contida só fará sentido para este software se estiver em uma
determinada estrutura – no nosso caso HTTP.

Momento mão na massa: Criando o seu próprio protocolo

Esperamos que isso nunca aconteça com você, mas eventualmente


você precisará fazer uma integração com equipamentos de algum
fabricante: Balança, Telefonia, Máquina Fabril e por ai vai.

Isso poderá ser via cabo serial ou via TCP/IP e para isso você terá que
estudar o protocolo de comunicação do fabricante do equipamento.

Em teoria esses protocolos são mais rápidos que os disponíveis, pois são
otimizados, não tendo informações supérfluas.

Vamos então desenvolver o nosso próprio protocolo, onde haverá um


servidor aguardando conexões e ao receber uma mensagem, corretamente
formatada, devolverá a hora atual da máquina onde ele está.

7 de 40
Criando Web Services de Alto Desempenho com
Delphi

SOA – Arquitetura Orientada a Serviço

Arquitetura Orientada a Serviço é uma abordagem extremamente


eficiente para a otimização dos recursos de TI de uma empresa.

Isso porque ela promove a desvinculação entre o domínio do negócio


(essencialmente as regras de negócio) e modelos específicos como
linguagens de desenvolvimento, sistemas operacionais, sistema de banco de
dados e por ai vai.

Portanto a organização consegue acompanhar a evolução


tecnológica sem fazer grandes rupturas.

Vale ressaltar de que é um modelo conceitual e, portanto esta


arquitetura não implica necessariamente na existência de webservices, mas
nos dias atuais é difícil imaginar outra forma de operacionalizar o SOA.

Basicamente temos dois papéis bem definidos: o de Provedor e o de


Consumidor.

CONSUMIDOR PROVEDOR
COMUNICAÇÃO

Figura 1 - Esquema macro Provedor/Cliente

Provedor

Estrutura que provê funcionalidades de domínio de negócios. No nosso


escopo é um conjunto de softwares com acesso a um banco de dados. Neste
software estarão as regras de negócio.

Consumidor

Estrutura de software que promove a visualização das informações bem


como a interação com o usuário final. Apesar desta descrição é possível
também que um consumidor seja outro software “provedor”.

8 de 40
Criando Web Services de Alto Desempenho com
Delphi

Comunicação

Para duas partes distintas se comunicarem é necessário haver um meio


e um protocolo suportado por ambos. Aqui estamos falando de uma
comunicação TCP/IP utilizando o protocolo HTTP para o DataSnap\REST.

ROA - Arquitetura Orientada a Recursos

REST é a base do ROA: Arquitetura Orientada a Recursos.

ROA é um modo de resolver um problema em um serviço web REST.


Continua existindo os mesmos elementos descritos na seção anterior (Provedor
e Consumidor), porém a abstração diminui um pouco.

Aqui estamos colocando o REST em evidência e a forma como ele


funciona é fortemente aderente ao HTTP. E é este funcionamento que
entenderemos a partir da próxima seção.

Entendendo o HTTP para entender o REST

O HTTP está fortemente presente em nosso dia a dia e é interessante


perceber esta realidade. É incrível o fato de muitos não se darem conta
certamente por ser algo intangível.

Mas o fato é que o HTTP é o protocolo que sustenta o planeta no que


tange ao compartilhamento de conteúdo. Em um mundo interconectado,
onde a informação está presente mesmo onde você não a quer, é o HTTP que
permite toda esta... Mágica!

As soluções de software, então, tem que acompanhar esta realidade e


há algum tempo conhecemos o SOA, sendo o SOAP sua implementação mais
difundida.

Porém nos últimos anos o REST vem ganhando força e seu aspecto mais
marcante é o de justamente “reaproveitar” os conceitos do HTTP.

“Um sistema complexo que funciona é, invariavelmente, considerado


como evoluído a partir de um simples que funcionava” - John Gall.

O objetivo desta seção, então, é o de desmistificar o HTTP mostrando


que não há mágica e sim simplicidade e eficiência. Com isto entenderemos o
REST e finalmente o DataSnap\REST.

9 de 40
Criando Web Services de Alto Desempenho com
Delphi

Web Humana X Web Programável

Existem duas WEBs: a humana e a programável.

A humana é a que todos nós conhecemos: Um navegador, uma URL e


horas de distração. Já a WEB programável foi feita para ser consumida por
softwares.

HTTP

O HTTP é a sigla para “Protocolo de Transferência de Hipertexto”.


Provavelmente disto você já saiba. Mas vamos estudar cada uma destas
palavras e entender do que se trata.

A princípio pense no HTTP como um envelope. No envelope vão as


informações necessárias para que o carteiro consiga entregar ao destinatário,
certo? E dentro do envelope há um conteúdo.

Para chegar ao seu destino toda esta estrutura passa por uma rede.
Vamos encarar então a rede e todo o seu aparato como o carteiro.

PROTOCOLO

Na informática protocolo é uma convenção, ou seja, um conjunto de


regras bem estabelecidas, que torna possível a comunicação entre duas
partes. Existem diversos protocolos além do HTTP como o FTP (transferência de
arquivos), SMTP (envio de e-mail) e por ai vai. Cada um com um propósito
bem específico e não existe um protocolo melhor que outro de um modo
geral. Em um grande sistema eles se complementam.

TRANSFERÊNCIA

Esta parte do significado do HTTP explicita o objetivo primário deste


protocolo: a transferência. Transferir é fazer a movimentação da informação
de uma ponta à outra, seja no mesmo dispositivo, passando por uma rede
local até chegar à grande web.

HIPERTEXTO

Hipertexto basicamente é um texto com referências (os famosos links)


que nos levam a outros textos. O “hiper” vem do grego e significa “sobre” ou
“além”. Grosso modo é um texto que possui ligações com outros textos e estes
com outros, o que nos possibilita “saltar” do ponto em que estamos
diretamente para um mais interessante.

10 de 40
Criando Web Services de Alto Desempenho com
Delphi

Obviamente isso já nos remete ao HTML que por sinal surgiu junto com o
HTTP. Não à toa HTML significa Linguagem de Marcação de Hipertexto.

REST

REST é o acrônimo para “Transferência de Estado Representacional”. É


fortemente baseado no HTTP tirando proveito de seus aspectos para simplificar
o desenvolvimento de um serviço web.

O REST não é uma tecnologia por si só, mas uma técnica, ou conjunto
de princípios, para o desenvolvimento de sistemas distribuídos. É, portanto,
uma arquitetura ou, em outras palavras, uma proposta de trabalho. Sendo
assim, temos que entender ao máximo a proposta do REST para conseguir
aplica-la na prática.

O termo “transferência” foi visto um pouco mais acima. Vamos falar


então do “estado representacional”.

Estado Representacional

O “estado representacional” refere-se à situação em que determinado


recurso se encontra.

Um consenso no REST é que ele não guarda estado, dai vem o termo
recorrente stateless (sem estado). Então cabe a cada ponta (cliente e servidor
basicamente) receber, modificar e repassar o estado do recurso. Logo, a
mensagem HTTP deve possuir todas as informações necessárias sobre o recurso
que esta sendo trabalhado.

Os objetivos da arquitetura REST vão mais além:

 Aumentar a escalabilidade;
 Diminuir a latência;
 Encapsulamento de sistemas legados;
 Definição clara das responsabilidades do cliente e do servidor;
 Evolvabilidade, que é a capacidade de evoluir e se adaptar;

Da lista acima, dois termos são de suma importância: escalabilidade e


latência.

Escalabilidade é a qualidade de permitir que se aumente a carga sem


comprometer o sistema. Em um sistema web isso é crucial afinal não
desejamos reescrever os softwares quando percebermos que ele não está
suportando a carga, certo?

11 de 40
Criando Web Services de Alto Desempenho com
Delphi

Para trabalhar na web o sistema tem que ser desenhado para isso. E
não estamos falando de página web ou da aplicação móvel. Estamos falando
de back-end.

Já a latência, de modo geral, é o tempo que leva para determinada


tarefa ser executada: A solicitação do cliente, o envio do pedido pela rede, a
recepção pelos servidores envolvidos (proxy, roteadores e por ai vai), o
processamento pelo end-point (com um eventual acesso ao banco de dados)
e todo o caminho de volta da resposta.

Muita coisa pode dar errada e comprometer o sistema. Temos que


sempre identificar e agir para diminuir a latência. Há problemas relacionados à
infraestrutura de rede, porém há muita responsabilidade nossa relacionada à
programação.

Roy Fielding e Tim Berners-Lee

Há um elo muito importante entre o HTTP e o REST e o nome dele é Roy


Fielding. Ele é um dos principais autores da especificação do protocolo HTTP e
não satisfeito cunhou o termo REST em uma tese de doutorado no ano de
2000. Vale citar que ele é um dos fundadores da Apache Foundation, empresa
responsável por um dos principais web-servers da indústria.

Já o Tim Berners-Lee também é co-autor das especificações HTTP e seu


principal objetivo foi a criação de um protocolo de transferência de objetos
HTML. Ou seja, o HTTP e o HTML nasceram juntos.

Obviamente existem diversas outras mentes brilhantes envolvidas neste


processo.

Apesar de não ser uma leitura obrigatória vale a pena citar que as
especificações do HTTP estão no RFC 2616 cujo link é:

http://www.ietf.org/rfc/rfc2616.txt

Dissecando o protocolo HTTP sob o ponto de vista do REST

Nesta seção iremos nos aprofundar no HTTP. O HTTP é muito amplo,


portanto focaremos nos aspectos que farão diferença no desenvolvimento de
uma aplicação REST.

O HTTP é um protocolo orientado a documentos. O propósito primário é


o de justamente recuperarmos de um computador remoto um determinado
documento.

12 de 40
Criando Web Services de Alto Desempenho com
Delphi

Na web humana o formato de documento mais evidente é o HTML, que


são documentos estruturados para a interpretação de um navegador web.

Com isso fica evidente outra característica importante do HTTP que é o


fato dele ser baseada no paradigma de requisição e reposta.

Regras gerais do protocolo HTTP

Uma mensagem HTTP possui três partes distintas:

 Cabeçalho HTTP
 Quebra de linha indicando o fim cabeçalho HTTP
 Conteúdo (opcional)

POST /mensagem HTTP/1.1↵


User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) …↵
Content-Type: application/json↵
Content-Length: 21↵

{“nome”: “olá mundo”}

Cabeçalho HTTP

O cabeçalho HTTP contêm diversas informações que serão usadas pelo


software receptor da mensagem. Com essas informações serão tomadas as
melhores decisões em relação ao conteúdo da mensagem. Lembre-se sempre
da analogia com um envelope.

Cada informação esta presente em uma linha em texto ASCII.

A primeira linha contêm informações especiais sobre a mensagem, mais


especificamente a ação e a identificação do conteúdo sendo trabalhado
bem como a versão do protocolo HTTP.

Em seguida vem o cabeçalho HTTP propriamente dito, que são pares de


chave e valor e contêm diversas informações sobre o conteúdo e sobre o
software que esta enviando a mensagem. O cabeçalho termina, então, com
uma quebra de linha simples.

Requisição

No HTTP a ponta cliente faz uma requisição para a ponta servidora


utilizando o seguinte protocolo:

13 de 40
Criando Web Services de Alto Desempenho com
Delphi

GET /index.html HTTP/1.1↵


Host: www.exemplo.com.br↵

Na primeira linha temos:

 O método HTTP: GET


 O caminho do recurso a ser trabalhado: /index.html
 A versão do protocolo HTTP: HTTP/1.1
 Quebra de linha

Da segunda linha em diante temos o cabeçalho HTTP. São pares de


chave e valor delimitados por dois pontos.

No exemplo temos apenas uma informação adicional que é o host do


servidor em que o recurso está hospedado.

Resposta

Após o processamento da solicitação a ponta servidora responde à


ponta cliente utilizando o seguinte protocolo:

HTTP/1.1 200 OK↵


Server: Apache↵
Content-Length: 23↵

<html>Olá mundo!</html>

Na primeira linha temos:

 A versão do protocolo HTTP: HTTP/1.1


 O status da resposta: 200
 Uma descrição do status da resposta: OK

Em seguida temos o cabeçalho HTTP. Chamo a atenção para o


content-length que encerra justamente o tamanho do conteúdo que esta
sendo trafegado. Este tamanho é em bytes.

Após o fim do cabeçalho (com a devida quebra de linha final) temos o


conteúdo. No exemplo temos um conteúdo HTML.

URL X URI

Comumente fica a dúvida sobre as diferenças entre os termos URL e URI.


Qual usar?

14 de 40
Criando Web Services de Alto Desempenho com
Delphi

URI Identificador Padrão de Recurso


URL Localizador Padrão de Recursos
URN Nome Padrão de Recurso

Não há uma diferença muito clara. De certa forma a confusão existe,


pois eventualmente ignoramos a existência da URN, que identifica unicamente
um recurso independentemente da localização. Um exemplo é o ISBN de um
livro qualquer: urn:isbn:0451450523

A URL, de um modo geral, identifica um recurso disponível em uma rede.


De um arquivo a uma impressora. Tem a seguinte notação:

[protocolo]://[servidor]:[porta]/[caminho]/[recurso]

Já a URI é uma definição mais abstrata: cadeia de caracteres


compacta usada para identificar ou denominar um recurso. Podendo então
ser ou uma URL ou uma URN.

Finalmente, no contexto HTTP e REST, a utilização do termo URL se mostra


tão correto quanto URI aparecendo ambas na literatura.

Maiores informações em:

 http://pt.wikipedia.org/wiki/URN
 http://pt.wikipedia.org/wiki/URL
 http://pt.wikipedia.org/wiki/URI

Classes de Recurso e Recurso

Como percebemos, a informação que trafega entre as partes


interessadas é denominada “recurso”.

Quando desenvolvemos uma solução sob este paradigma, não é


errado afirmar que estamos desenvolvendo orientado a recursos. Fazendo um
paralelo à OOP, a Classe de Recursos equivale a uma Classe ao passo que um
Recurso equivale a uma Instância. Exemplo:

Classe de Recursos Recursos

Clientes Empresa XYZ


Empresa ABC

15 de 40
Criando Web Services de Alto Desempenho com
Delphi

Recurso Ativado

A princípio o recurso é representado por um arquivo físico, como por


exemplo, empresa_xyz.json ou empresa_abc.json. Obviamente que na vida
real informações deste tipo estarão em um banco de dados.

Mas isso não deixa de ser um recurso, sendo referido então como um
Recurso Ativado, pois é gerado a partir do processamento de informações
dispersas.

Representação do Recurso

Um recurso, obviamente, deve ser representado de alguma forma. Para


uma imagem ou arquivo binário não há dúvidas. Mas como representar um
cliente, por exemplo?

Os formatos mais usuais são o XML, JSON e YAML sendo o JSON o mais
popular nos sistemas REST.

CSV

“João da Silva”;45;

INI

NOME=João da Silva
IDADE=45

XML

<xml>
<nome>João da Silva</nome>
<idade>45</idade>
</xml>

JSON

{
“nome”: “João da Silva”,
“idade”: 45
}

YAML - http://pt.wikipedia.org/wiki/YAML

- nome: João da Silva


Idade: 57

16 de 40
Criando Web Services de Alto Desempenho com
Delphi

HTML

<html>
<body>
<div class=”nome”>João da Silva</div>
<div class=”idade”>45</div>
</body>
</html>

Interface Uniforme

O método HTTP, também chamado de “verbo HTTP” ou “ação HTTP” é


um conjunto bem definido e limitado de palavras chaves que indicam a ação
que o sistema cliente deseja efetuar em relação ao recurso.

As ações mais relevantes em REST são:

Método Ação
GET Recupera um determinado recurso ou lista de recursos
PUT Atualiza um determinado recurso ou cria se inexistente
POST Cria um novo recurso
DELETE Elimina um determinado recurso

Comumente os métodos HTTP são associados às operações CRUD:

CRUD SQL HTTP Ação


Create INSERT POST Criar
Read SELECT GET Recuperar
Update UPDATE PUT Modificar ou Criar
Delete DELETE DELETE Eliminar

Existe uma discussão frequente sobre a real diferença entre os verbos


PUT e POST. Um artigo interessante esta em:

http://gc.blog.br/2007/07/02/post-vs-put-quem-insere-e-quem-altera/

Essa discussão nasce quando fazemos a associação entre comandos


SQL e verbos HTTP – o que é natural no começo.

Status HTTP

Na resposta HTTP provavelmente a informação mais relevante (antes do


conteúdo) é o código de status. Sempre buscamos o “200 OK”, mas existem

17 de 40
Criando Web Services de Alto Desempenho com
Delphi

outros. No “Apêndice A” descreve-se os mais interessantes e o contexto em


que eles aparecem.

Momento mão na massa

Uma necessidade recorrente é de recuperarmos o valor do dólar para


registrarmos em nosso sistema. Afinal muitos cálculos são feitos em cima deste
valor.

Obviamente que a solução mais imediata que podemos desenvolver é


uma tela de cadastro simples. Porém isto esta sujeito às falhas humanas:
esquecimento, erro de digitação e por ai vai.

Porque não, então, recuperar este valor da Internet?

Um site que possui esta informação é o Dolar Hoje:

http://dolarhoje.com/

18 de 40
Criando Web Services de Alto Desempenho com
Delphi

Dominando o JSON

O formato adotado pelos atuais webservices para representação de


informação é o JSON.

JSON é o acrônimo de JavaScript Object Notation. Não à toa tem este


nome, pois surgiu no âmbito do JavaScript, linguagem majoritariamente
utilizada para criar front-ends web.

É uma formatação leve para intercâmbio de dados e uma ótima


alternativa ao XML. Um novo formato que esta criando popularidade é o
YAML, mas ficará de fora do escopo deste treinamento por ainda não ter
aplicabilidade imediata.

Mais a frente nesta apostila falaremos do mongoDB e a “cultura” noSQL,


ou como preferimos nos referir, “não relacional”. O mongoDB guarda as
informações no formato JSON.

Mas afinal, o que caracteriza uma informação JSON?

Estrutura do JSON

As imagens a seguir foram retiradas do site oficial do JSON:

http://www.json.org/json-pt.html

JSON é simples. Tendo isso em mente fica mais fácil absorver os


conceitos. Temos tendência a complicar as coisas e quando nos deparamos
com algo simples estranhamos. Alguns detalhes ficam mais obscuros ainda
para nós, desenvolvedores Delphi, devido às particularidades das linguagens,
no caso Delphi e JavaScript.

JSON String

Uma string, assim como no Delphi, representa uma informação textual.


Porém, por ter vindo de outro contexto, um string JSON possui algumas
peculiaridades em sua formatação.

É caracterizado por uma cadeia de caracteres encerrados por aspas


duplas. Porém devemos ficar atentos aos caracteres escapados como o \n
que representa uma quebra de linha.

19 de 40
Criando Web Services de Alto Desempenho com
Delphi

Exemplos de strings válidos:

“”

“mário.guedes”

“Fernanda\nJúlio”

JSON Number

Um número é representado por uma cadeia de dígitos com o sinal


negativo no começo quando for o caso. A parte decimal é definida pela
presença do ponto.

Importante notar a ausência das aspas duplas nas extremidades, o que


caracterizaria uma string.

Exemplos de números válidos:

-10

30.15

20 de 40
Criando Web Services de Alto Desempenho com
Delphi

JSON True

Para representar o valor booleano verdadeiro usamos a seguinte


notação:

true

Ou seja, a palavra true, com as letras em minúsculo e sem aspas duplas


nas extremidades.

JSON False

Para representar o valor booleano falso usamos a seguinte notação:

false

Ou seja, a palavra false, com as letras em minúsculo e sem aspas


duplas nas extremidades.

JSON Null

Para representar um valor nulo, ou seja, inexistente, usa-se a notação:

null

Ou seja, a palavra null com as letras em minúsculo e sem aspas duplas


nas extremidades.

21 de 40
Criando Web Services de Alto Desempenho com
Delphi

JSON Array

Um array JSON é uma lista desordenada de valores de qualquer tipo.

Um array é caracterizado por vários valores separados por vírgula, todos


eles encerrados por colchetes.

Exemplos de arrays válidos:

[]

[“mario.guedes”, 36, true, false, null, [1, 2, 3]]

JSON Object

Um objeto JSON é um conjunto desordenado de pares de chave e


valor.

Um objeto JSON é caracterizado por um conjunto de pares de chave e


valor, cada par separado por uma vírgula do outro par e por fim todos os
pares encerrados por chaves.

Exemplos válidos:

{}

{“nome” : “mário.guedes”}

{“nome” : “mário.guedes” , “idade” : 36, “filhos” : [“julio”,


fernanda]}

22 de 40
Criando Web Services de Alto Desempenho com
Delphi

Perceba que a chave, por si só, é representado por uma string incluindo,
portanto, as aspas duplas nas extremidades. Já o valor pode ser de qualquer
tipo, até mesmo outro JSON Object.

Interagindo com o JSON pelo Delphi

O Delphi possui classes nativas para interagir com o JSON. Assim como
no XML é necessário criar rotinas recursivas. No dia a dia não parecerá uma
boa ideia por envolver muito código, por isso, seguindo uma filosofia de
trabalho que privilegia a simplicidade, o ideal será criar um esquema de
serialização e deserialização de objetos.

As classes para interagir com JSON estão na unit Data.DBXJSON seguindo


o esquema definido na Figura 2:

Figura 2 - Hierarquia das classes

23 de 40
Criando Web Services de Alto Desempenho com
Delphi

Momento mão na massa: Recuperando o aniversário e as fotos dos seus


amigos do Facebook

Grandes serviços web optam pelo JSON por vários motivos:

 Legibilidade;
 Diminuição de tráfego de rede;
o Aumento de vazão e consequentemente da escalabilidade
 Aderência às linguagens modernas – JavaScript, Python e Ruby por
exemplo;

Um exemplo de um grande serviço web é o Facebook. Tem a parte


social que todos conhecem e a parte “programática”, ou seja, uma área em
que usamos uma API REST e fazemos uma integração com o aplicativo.

Outros exemplos, para citar os mais conhecidos são: Twitter, Google e


seus serviços, LinkedIN entre diversos outros.

Vamos explorar alguns aspectos relacionados à nossa conta pessoal no


Facebook.

O objetivo deste exercício não é o de nos aprofundarmos na API do


Facebook, mas sim de captar o “espírito da coisa”, pois no fim é o que
construiremos com o nosso aplicativo: uma API REST

Imaginemos então um aplicativo que liste nossos amigos e nos dê a


data de aniversário.

Logado no Facebook vamos acessar esta URL:

https://developers.facebook.com/

Entre diversas ferramentas temos o Graph Explorer e é este recurso que


iremos utilizar.

Figura 3 - Tela inicial da área para desenvolvedores

24 de 40
Criando Web Services de Alto Desempenho com
Delphi

Este recurso não permite uma integração total com Facebook mas já é
o suficiente. Basicamente permite interagir com as informações relacionadas à
nossa conta pessoal.

Para isso precisamos de um TOKEN de acesso, que é um código


especial que nos identifica no sistema bem como os recursos que queremos ter
acesso. Este TOKEN tem validade de uma hora:

Figura 4 - Botão para a obtenção do TOKEN

Para a geração do TOKEN é necessário especificar os recursos com os


quais se deseja interagir.

Figura 5 - Especificando os recursos com os quais se deseja interagir

25 de 40
Criando Web Services de Alto Desempenho com
Delphi

Serialização de objetos

26 de 40
Criando Web Services de Alto Desempenho com
Delphi

ORM – Mapeamento Objeto – Relacional

O ORM é uma técnica de desenvolvimento muito importante na


construção de um software de alto desempenho.

Devemos deixar de encarar o banco relacional, seja ele o SQL Server,


Oracle ou o MariaDB, como um “deus” que tudo pode.

 Precisa armazenar imagens? Joga no banco de dados!


 Precisa armazenar os XMLs da NFe? Joga no banco de dados!
 Precisa fazer comunicação inter-processos? Um programa grava e
outro lê... no banco de dados!

Enfim: Banco de dados é para armazenar dados. Delegar ao banco de


dados tarefas outras que não tem haver com dados é um contra senso.

Por outro lado, devemos evitar ao máximo fixar as instruções SQL em


nosso sistema. O ideal é tornar o processo o mais dinâmico possível. E utilizar
técnicas de ORM nos trás esta flexibilidade.

Obviamente que uma escolha implica em renúncias. E esta seção tenta


mensurar os ganhos e as perdas.

27 de 40
Criando Web Services de Alto Desempenho com
Delphi

DataSnap

O DataSnap é a tecnologia padrão do Delphi para a criação de


soluções multicamada. Há todo um histórico sobre esta tecnologia que não
vamos discutir nesta apostila.

Vamos simplesmente esquecer o passado, ao menos no que tange à


proposta do treinamento e focar no momento atual.

A proposta do DataSnap, de uma maneira geral, é o de publicar classes


e métodos para uso remoto. A Figura 6 tenta ilustrar este conceito.

SERVIDOR DATASNAP

Cliente Servidor TCP


(Indy)

TCP/IP

Cliente #2
Thread Thread Thread
#1 #2 #3

Cliente #3

Figura 6 - Esquematização geral do funcionamento do DataSnap

Com isto estamos saindo do modelo cliente/servidor para o modelo


multi camadas.

Obviamente que esta afirmação embute na verdade um tremendo


desafio no que tange à arquitetura da solução. Antes tínhamos que
desenvolver, em linhas gerais, um único software. Agora teremos que, ainda
em linhas gerais, desenvolver dois softwares – o cliente e o servidor.

28 de 40
Criando Web Services de Alto Desempenho com
Delphi

No que o DataSnap se apoia?

O DataSnap é um agregado de tecnologias que tem por objetivo


facilitar a construção de um sistema multicamada. Não precisando se
preocupar com essas tecnologias você se concentra rapidamente no motivo
de ser do seu sistema.

Utilizando o DataSnap estamos deixando um pouco de lado as


seguintes preocupações:

 Comunicação TCP/IP: Toda a complexidade de fazer dois softwares


“conversarem” entre si já esta resolvida. E isto não é pouca coisa.

 Meta-programação: O cliente enviará mensagens e o servidor


“magicamente” irá instanciar e executar o método da classe
correspondente. Por serem dois softwares diferentes, rodando em
máquinas diferentes isso seria extremamente desafiador de se fazer por
conta própria.

Mas...

Infelizmente o DataSnap é bastante criticado por aqueles que o


compara com outras soluções e há um post muito popular do Roberto
Schneiders que faz uma criteriosa análise de desempenho e em vários
aspectos.

Os grandes vilões são a biblioteca Indy (comunicação TCP/IP) e o


dbExpress (acesso a banco de dados).

Isso ressalta o mantra da Ortogonalidade. Nunca devemos depender


100% de uma tecnologia. É óbvio que um nível de dependência é inevitável.

http://robertocschneiders.wordpress.com/2012/11/22/datasnap-analysis-
based-on-speed-stability-tests/

http://robertocschneiders.wordpress.com/2013/01/09/datasnap-analysis-
based-on-speed-stability-tests-part-2/

A “Clube Delphi” possui o post traduzido pelo próprio autor:

http://www.devmedia.com.br/colocando-um-servidor-datasnap-a-prova-
revista-clubedelphi-magazine-151/28228

Apesar disto o DataSnap é uma tecnologia viável e é a arquitetura de


toda a solução é que ditará o sucesso ou não da empreitada.

29 de 40
Criando Web Services de Alto Desempenho com
Delphi

Existe alternativas ao DataSnap?

Sim e algumas bem conceituadas. Não temos conhecimento prático


nestas alternativas, mas talvez valha a pena analisa-las antes de efetivamente
iniciar um novo projeto:

Biblioteca Link
mORMt http://synopse.info/fossil/wiki/Synopse+OpenSource
Delphi On Rails https://code.google.com/p/delphionrails/
TMS RemoteDB http://www.tmssoftware.com/site/remotedb.asp
Brook framework http://silvioprog.github.io/brookframework/

Mas repete-se o conselho: evite criar um vínculo extremo com o


framework adotado.

O propósito do nosso treinamento é justamente o de apontar o


caminho para criar esta tal ortogonalidade, tornando assim a sua solução
perene.

DataSnap TCP/IP X DataSnap REST

Como nosso foco é o DataSnap vamos concentrar os esforços nele. A


primeira grande escolha que se deve fazer é quanto ao protocolo de
comunicação. Hoje nós temos duas opções: TCP/IP e REST.

Mas o que significa esta escolha?

TCP/IP HTTP
Aderente apenas a clientes Delphi Aderente a qualquer cliente HTTP
Possibilidade de trabalhar RAD Potencialmente exige mais código
Conexão persistente: Conexão não persistente:
 Maior velocidade  Menor velocidade (?)
 Menor escalabilidade  Maior escalabilidade

Nosso treinamento irá focar na comunicação HTTP apesar da


possibilidade de um único servidor poder ter os dois modos de comunicação.

Esta escolha se deve às exigências do mercado que pede maior


interoperabilidade. E este objetivo só pode ser alcançado com o HTTP: O
mundo fala em HTTP.

Com esta escolha, o sistema estará apto a atender qualquer cliente


HTTP:

 Outros webservices;

30 de 40
Criando Web Services de Alto Desempenho com
Delphi

 Softwares desenvolvidos em diversas linguagens rodando em qualquer


plataforma;
 Aplicativos web, em especial o JavaScript;
 Aplicativos mobile (que exigem uma arquitetura mais leve);

Momento mão na massa: Nosso “Olá Mundo” em três camadas!

A fim de quebrarmos o gelo vamos desenvolver o nosso primeiro


exemplo sem maiores explicações.

31 de 40
Criando Web Services de Alto Desempenho com
Delphi

Componentes envolvidos em um servidor DataSnap

TDSServer: Componente que efetivamente é o servidor


DataSnap. Interage com todos os outros componentes do
framework.

TDSTCPServerTransport: É o componente responsável pelo


transporte das informações entre o servidor e os clientes,
neste caso através de um protocolo proprietário.

TDSHTTPService: É o componente responsável pelo


transporte das informações, porém via protocolo HTTP.

TDSServerClass: É o componente que interage com as


classes que serão disponibilizadas pelo servidor.

32 de 40
Criando Web Services de Alto Desempenho com
Delphi

Funcionamento geral de um servidor DataSnap/REST

É muito importante separar claramente as classes de negócios do seu


sistema com as classes e componentes do framework DataSnap, tanto no lado
cliente quanto no lado servidor.

As justificativas são muitas que se resumem em uma palavra:


ortogonalidade.

Classe
TDSHTTPService TDSServer TDSServerClass Classe de Negócio
Manipuladora

Manipulando as requisições e respostas HTTP

Para explorar mais o assunto pode-se consultar a seguinte URL:

http://docwiki.embarcadero.com/RADStudio/XE6/en/DataSnap_REST_Messagi
ng_Protocol

Diferentemente de outros frameworks, não temos a possibilidade de


determinarmos as URLs que serão utilizados para acessar os recursos
disponibilizados pelo nosso sistema.

As URLs serão, então, determinadas por justaposição, no seguinte


esquema:

TDSHTTPService Classe Manipuladora


Contexto Contexto
PROTOCOLO SERVIDOR Classe Método Parâmetro
DataSnap REST
http:// localhost:8080 /arrayof /usuario /TUsuario /Usuario /João da Silva
Tabela 1 - URL por justaposição

O que será feito com o usuário “João da Silva” é determinado pelo


verbo HTTP utilizado no pedido: GET, POST, PUT ou DELETE. Ou seja, a URL será a
mesma para qualquer uma das operações CRUD.

Então, para tratar as solicitações dos clientes, é necessário criar uma


classe manipuladora de requisições HTTP. E para que esta classe seja aderente
ao DataSnap\REST é necessário atender à algumas premissas:

33 de 40
Criando Web Services de Alto Desempenho com
Delphi

DSServerClass e a Classe manipuladora de requisições HTTP

A classe que será utilizada para atender a requisição HTTP não deve ser
a mesma que efetuará os procedimentos solicitados. O ideal é que sejam duas
classes distintas.

A primeira, que será explicada nesta seção, é para atender os requisitos


do DataSnap. A outra faz parte das regras de negócio. Se um dia mudarmos
de DataSnap para mORMt por exemplo, a classe manipuladora tem grandes
chances de não servir. Porém a classe de negócio tem que continuar
existindo.

Nos concentrando agora na classe manipuladora, para uma situação


simples de CRUD, temos que prever 4 métodos nesta classe:

Consulta Alteração Inclusão Exclusão


Verbo HTTP: GET POST PUT DELETE
Prefixo no método: - Update Accept Cancel

Uma classe possível seria:

{$METHODINFO ON}
TUsuario = class
private
// ...
public

function Usuario(const AID: Integer): TJSONValue;

function AcceptUsuario(AUsuario: TJSONValue): Boolean;

function CancelUsuario(AID: Integer): Boolean;

function UpdateUsuario(const AID: Integer; AUsuario: TJSONValue):


Boolean;

end;
{$METHODINFO OFF}
Listagem 1 - Exemplo de uma classe manipuladora

Ao publicar a classe TUsuario com o componente TDSServerClass será


feito o seguinte mapeamento:

Verbo HTTP Método


Recuperar GET Usuario()
Inserir PUT AcceptUsuario()
Excluir DELETE CancelUsuario()
Alterar POST UpdateUsuario()

34 de 40
Criando Web Services de Alto Desempenho com
Delphi

Conteúdo JSON

Perceba na Listagem 1 que ora retornarmos um JSONValue, ora


recebemos como parâmetro.

O DataSnap/REST sempre trafegará JSON. Mesmo que se retorne um


valor de tipo primitivo, como uma string ou boolean, por exemplo, o cliente
receberá um JSON.

Isso denota uma dificuldade em se trafegar arquivos, o que será


contornado um pouco mais à frente desta apostila.

Quando o método receber um JSON, o parâmetro correspondente


deve ser declarado por último, uma vez que não virá na URL, mas sim no corpo
da requisição HTTP.

Hackeando a resposta de um servidor DataSnap/REST

Quando se trabalha com um servidor DataSnap servindo a softwares


desenvolvidos em outras tecnologias, a estrutura do JSON disponibilizado pelo
DataSnap pode se mostrar inconveniente.

Além disso, pode haver a necessidade de se trafegar outros formatos,


como por exemplo uma imagem.

Para estas necessidades podemos manipular o conteúdo da resposta. A


classe manipuladora, em algum momento deve invocar o método
GetInvocationMetadata que retorna a instância de TDSInvocationMetadata que
está atrelado à comunicação em andamento, lembrando que estamos em
um contexto de uma thread.

Um algoritmo possível seria:

procedure TClasseQualquer.Responder(AObjeto: TObject);


var
oRetorno: TDSInvocationMetadata;
begin
oRetorno := GetInvocationMetadata;

oRetorno.ResponseCode := 200;
oRetorno.ResponseMessage := 'OK';
oRetorno.ResponseContentType := 'application/json';
oRetorno.ResponseContent := Self.Serializar(AObjeto);

end;
Listagem 2 - Exemplo de utilização do TDSInvocationMetadata

35 de 40
Criando Web Services de Alto Desempenho com
Delphi

Na Listagem 2 temos um exemplo claro de utilização do


TDSInvocationMetadata. No caso estamos manipulando as partes mais
relevantes da resposta.

Manipulando a QueryString da URL

No que tange especificamente ao DataSnap não há utilização de


QueryString.

Porém este recurso pode ser muito útil para influenciar na resposta, e um
exemplo imediato seria a paginação do resultado.

Em uma URL a QueryString se inicia após um sinal de interrogação,


sendo uma lista de chave e valor separados por &.

Exemplo:

http://localhost/ds/rest/TClasse/Metodo/Param1?inicio=10&limite=10

Mais uma vez tiramos proveito do objeto TDSInvocationMetadata


corrente, como no exemplo a seguir:

var
oHTTP: TDSInvocationMetadata;
begin
oHTTP := GetInvocationMetadata;

//...

Self.FInicio := StrToIntDef(oHTTP.QueryParams.Values['inicio'], -1);


Self.FLimite := StrToIntDef(oHTTP.QueryParams.Values['limite'], -1);

//...
end;

Explorando algumas possibilidades

Vamos explorar algumas alternativas interessantes que o DataSnap nos


oferece.

Cache: Evitando armazenamento das informações pelos browsers e proxies

Uma situação na qual devemos ficar atentos é o armazenamento das


informações JSON que o browser, ou proxies reversos, tendem a guardar e
reutilizar. O cacheamento de informações.

36 de 40
Criando Web Services de Alto Desempenho com
Delphi

Devemos então, mais uma vez, interferir na resposta adicionando os


parâmetros necessários para evitar esta situação. O local mais adequado
para se atingir este objetivo é no evento Trace do componente
TDSHTTPService, como no exemplo a seguir:

procedure TDataModule1.DSHTTPService1Trace (Sender: TObject; AContext:


TDSHTTPContext; ARequest: TDSHTTPRequest; AResponse: TDSHTTPResponse);
var
_hacker: TDSHTTPResponseIndy;
begin
_hacker := TDSHTTPResponseIndy(AResponse);
_hacker.ResponseInfo.CustomHeaders.Values['Cache-Control'] := 'no-
store, no-cache, must-revalidate, max-age=0';
end;

O objetivo de um framework, como o DataSnap é justamente abstrair


certos problemas. E isso faz com que fique relativamente difícil, quando não
impossível, contornar esses problemas.

Por isso que foi necessário efetuar o typecast para a classe


TDSHTTPResponseIndy. E isso só foi possível “descobrir” analisando os fontes do
DataSnap. Este exemplo funciona muito bem no Delphi XE2 mas pode deixar
de funcionar em versões posteriores. Pois no futuro a equipe de
desenvolvimento do DataSnap pode deixar de usar o Indy para a
comunicação HTTP.

37 de 40
Criando Web Services de Alto Desempenho com
Delphi

Modularização de um servidor DataSnap

Para um melhor rendimento da equipe em relação ao desenvolvimento


de um servidor DataSnap é altamente conveniente trabalharmos com BPLs ao
invés de grandes executáveis. A ideia básica é termos BPLs especializadas,
que por sua vez tiram proveito de outras BPLs.

Procurando manter o baixo acoplamento entre as soluções os impactos


das eventuais mudanças serão localizadas, não contaminando todo o
sistema.

O primeiro desafio então é desenvolvermos a aplicação servidora, ou


seja, o executável que carregará as BPLs.

38 de 40
Criando Web Services de Alto Desempenho com
Delphi

Pool de Conexões com o Banco de Dados

39 de 40
Criando Web Services de Alto Desempenho com
Delphi

Para aprender mais

Nesta seção lista-se uma série de referências que julgamos pertinentes.


Há também sugestões de livros e cursos.

Como um verdadeiro sistema REST funciona: arquitetura e desempenho na


Abril
por Luis Cipriani em 24/10/2012

http://www.infoq.com/br/presentations/rest-arquitetura-abril

http://www.slideshare.net/lfcipriani/como-um-verdadeiro-sistema-rest-
funciona-arquitetura-e-performance-na-abril

Guru-SP - Abusando nas requisições HTTP sem medo


Luis Cipriani

http://blip.tv/agaelebe/26_11_2011_gurusp_http_cipriani-720-5879314

https://speakerdeck.com/lfcipriani/abusando-nas-requisicoes-http-sem-
medo

O que é ser idempotente em REST? O debate continua


por Mark Little , traduzido por Marcelo Cenerino em 24 Mai 2013

http://www.infoq.com/br/news/2013/05/idempotent?utm_source=twitterfeed
&utm_medium=twitter&utm_content=infoqbr

Livros recomendados

RESTful Serviços Web


Web Services para o Mundo Real
Leonard Richardson & Sam Ruby
http://www.livrariacultura.com.br/scripts/cultura/externo/index.asp?id
_link=8954&destino=/scripts/resenha/resenha.asp?nitem=2292748&

40 de 40

Você também pode gostar