Por que eu devo ler este artigo:A utilização do modelo cliente/servidor para o desenvolvimento de software talvez seja o mais largamente utilizado por desenvolvedores. Porém, quando desenvolvemos aplicações mobile, muitas vezes esse modelo não é o mais adequado, pois muitos recursos específicos do servidor precisariam ser desenvolvidos manualmente; fato que pode deixar as aplicações pesadas e difíceis de evoluir. Por isso, é importante o conhecimento sobre como construir arquiteturas multicamadas no Delphi que utilizam os conceitos de REST e tráfego de arquivos JSON pela rede, garantindo maior flexibilidade e escalabilidade às aplicações.

Atualmente, quando se pensa no desenvolvimento de software, dois modelos principais podem ser utilizados: o tradicional modelo cliente/servidor ou o modelo multicamadas. A primeira opção consiste somente de duas camadas: o servidor de banco de dados e a aplicação cliente. Nesse contexto, todas as regras de negócio podem ficar centralizadas tanto na primeira quanto na segunda camada (ou em ambas), e a aplicação cliente acessa diretamente a base de dados. Já no modelo multicamadas existe uma porção de software adicional, que é chamada de servidor de aplicação. Essa camada é responsável por armazenar todas as regras de negócio, e é ela quem interage diretamente com a base de dados, ou seja, nesse modelo a aplicação cliente não tem acesso direto ao servidor de banco de dados. Em suma, a aplicação cliente acessa o servidor de aplicação, enquanto que o servidor de aplicação é quem acessa diretamente a base de dados.

A implementação dessa arquitetura de software possibilita uma série de vantagens, como o balanceamento de carga, que permite definir o número máximo de conexões que um servidor pode suportar, e, quando atingido o limite todo o novo tráfego é automaticamente direcionado para servidores menos ocupados. Algumas outras vantagens desse modelo são: centralização das regras de negócio no servidor (não existem comandos SQL na aplicação cliente); facilidade de redistribuição da aplicação cliente; economia de licenças de acesso a bases de dados; economia de conexões no servidor e escalabilidade.

Uma dúvida muito comum dos desenvolvedores, principalmente na construção de aplicativos móveis, é como definir a arquitetura correta de um app que acessa uma base de dados remota. Nesse contexto, não é uma prática muito comum utilizar o modelo cliente/servidor assim como feito em aplicações desktop, ou seja, fazer uso de componentes de acesso direto a dados conectando em bases de dados remotas. Em aplicativos móveis, deve-se usar componentes de acesso direto aos dados (TFDConnection ou TFDQuery, por exemplo) quando a base de dados é local e está gravada no próprio aparelho, o que normalmente ocorre utilizando o SQLite. Porém, quando há a necessidade de acesso externo, o recomendável é a utilização de um servidor de aplicação.

Baseado nisso, o objetivo do presente artigo é mostrar como construir uma arquitetura multicamadas utilizando o Delphi 10.1 Berlin com o SQL Server como o sistema gerenciador de banco de dados. Será mostrado como construir as três camadas desse modelo, partindo da criação da base de dados e implementando também o servidor e a aplicação cliente. O intuito principal é apresentar como a aplicação cliente acessa dados remotos de datasets e incorpora os registros em um ListView, utilizando para isso componentes TFDMemTable. Serão construídos três exemplos de métodos remotos: um para buscar na base de dados a pessoa com o maior salário e retornar o valor; uma pesquisa de pessoas por nome; e, por fim, como trafegar datasets mestre/detalhe pela rede e visualizar seus dados no ListView. Para isso, será utilizado o conceito REST bem como o tráfego de arquivos JSON.

Criando a base de dados

O primeiro passo é a criação da camada de banco de dados da nossa aplicação e, para isso, a Listagem 1 apresenta os comandos SQL para a criação da base de dados e a definição das tabelas no SQL Server. Na linha 1 encontra-se o comando para a criação do banco, enquanto que entre as linhas 2 e 6 está localizado o comando que define a tabela de funcionários, a qual possui um campo chave primária autoincremento (idfuncionario), um nome e o valor do salário. Em seguida, entre as linhas 7 e 12 está o script para gerar a tabela de endereços dos funcionários, que diz respeito ao relacionamento mestre-detalhe (master-detail) entre ambas. Essa tabela também contém uma chave primária autoincremento (idfuncionario_endereco), a chave estrangeira (idfuncionario), o nome do logradouro e o número.


  create database empresa;
  create table funcionarios (
    idfuncionario int primary key not null identity,
    nome varchar(50) not null,
    salario float not null
  );
  create table funcionario_enderecos (
    idfuncionario_endereco int primary key not null identity,
    idfuncionario int not null foreign key references funcionarios (idfuncionario),
    logradouro varchar(50),
   numero char(10)
  );
Listagem 1. Scripts de criação da base de dados

A seguir, a Listagem 2 apresenta os scripts para inserção de dados nas tabelas: entre as linhas 1 e 4 são inseridos alguns funcionários e entre as linhas 5 e 11 seus respectivos endereços são incluídos. Por exemplo, o funcionário de nome “Ana” (idfuncionario = 3) possui três endereços, enquanto que a “Jaqueline” (idfuncionario = 4) apresenta somente um endereço.


insert into funcionarios (nome, salario) values ('Pedro', 5000);
insert into funcionarios (nome, salario) values ('Marcos', 2000);
insert into funcionarios (nome, salario) values ('Ana', 8000);
insert into funcionarios (nome, salario) values ('Jaqueline', 3000);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(1, 'Rua Joaquim Nabuco', 76);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(1, 'Rua Francisco Pereira', 101);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(2, 'Avenida Central', 205);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(3, 'Rua Pedro Vargas', 540);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(3, 'Avenida Central', 48);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(3, 'Rua Pereira', 2);
insert into funcionario_enderecos (idfuncionario, logradouro, numero) values 
(4, 'Rua Carlos Chag ... 

Quer ler esse conteúdo completo? Tenha acesso completo