criando web services de alto desempenho com delphi

40
Criando Web Services de Alto Desempenho com Delphi 1 de 40 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.

Upload: bbecalli

Post on 09-Jul-2016

165 views

Category:

Documents


11 download

TRANSCRIPT

Criando Web Services de Alto Desempenho com

Delphi

1 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

2 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

3 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

4 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

5 de 40

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;

Criando Web Services de Alto Desempenho com

Delphi

6 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

7 de 40

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á.

Criando Web Services de Alto Desempenho com

Delphi

8 de 40

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.

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”.

CONSUMIDOR PROVEDOR COMUNICAÇÃO

Criando Web Services de Alto Desempenho com

Delphi

9 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

10 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

11 de 40

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?

Criando Web Services de Alto Desempenho com

Delphi

12 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

13 de 40

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:

Criando Web Services de Alto Desempenho com

Delphi

14 de 40

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?

Criando Web Services de Alto Desempenho com

Delphi

15 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

16 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

17 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

18 de 40

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/

Criando Web Services de Alto Desempenho com

Delphi

19 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

20 de 40

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:

0

-10

30.15

Criando Web Services de Alto Desempenho com

Delphi

21 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

22 de 40

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]}

Criando Web Services de Alto Desempenho com

Delphi

23 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

24 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

25 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

26 de 40

Serialização de objetos

Criando Web Services de Alto Desempenho com

Delphi

27 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

28 de 40

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.

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.

TCP/IP

SERVIDOR DATASNAP

Servidor TCP

(Indy)

Thread

#1

Thread

#3

Thread

#2

Cliente

Cliente #2

Cliente #3

Criando Web Services de Alto Desempenho com

Delphi

29 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

30 de 40

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:

Maior velocidade

Menor escalabilidade

Conexão não persistente:

Menor velocidade (?)

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;

Criando Web Services de Alto Desempenho com

Delphi

31 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

32 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

33 de 40

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.

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

PROTOCOLO SERVIDOR Contexto

DataSnap

Contexto

REST Classe Método Parâmetro

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:

TDSHTTPService TDSServer TDSServerClassClasse

ManipuladoraClasse de Negócio

Criando Web Services de Alto Desempenho com

Delphi

34 de 40

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()

Criando Web Services de Alto Desempenho com

Delphi

35 de 40

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

Criando Web Services de Alto Desempenho com

Delphi

36 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

37 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

38 de 40

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.

Criando Web Services de Alto Desempenho com

Delphi

39 de 40

Pool de Conexões com o Banco de Dados

Criando Web Services de Alto Desempenho com

Delphi

40 de 40

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&