MVCBr – Como criar um CRUD com OData

 

Chegar a um CRUD é um grande desafio. Associar um MVC no desenvolvimento e a utilização de RESTful para persistir os dados (com OData) só faz crescer o desafio.

O desafio vem do fato de tudo ser novidade e forçar a quebrar paradigmas antes impensáveis utilizando a ferramenta do dia-a-dia, o Delphi.

Vamos ligar os componentes:

TIdHTTPRestClientTIdHTTPRestClient é responsável em fazer a
comunicação entre o cliente e o servidor RESTful.

É o canal para buscar dados no servidor, bem como enviar dados para o servidor (é um componente de transporte).

ver mais…

 

 

Os preenchimento das propriedades do RestClient pode ser feito manualmente, ou ainda, de forma automática se for utilizado em conjunto com um TODataBuilder.

 

ODataCom o TODataBuilder permite construir a soliciatação GET a ser enviada ao servidor OData.

Ligar ao TODataBuilder a propriedade RestClient com o TIdHTTPRestClient. Com isto o comando construído no Builder será repassado (preenchido automático) no RestClient.  ver mais….

 

 

 

O passo seguinte é ligar o TODataDatasetAdpater.

TODataDatasetAdapterO Adapter recebe os dados do RestClient e liga com o Dataset.

Ligar o Builder, Dataset e o ResponseJSON( RestClient).

Para obter os dados com os servidor, chamar o método execute. ver mais…

Feito estas ligações nos componentes, já é possível chamar o EXECUTE do Adapter que irá preencher o Dataset com a resposta do servidor.

Para enviar um INSERT, DELETE ou UPDATE para o servidor ( ver exemplo).

O código a seguir mostra como montar os dados a serem enviado para o servidor persistir as alterações.

Os seguintes métodos do Adapter são importantes, como no exemplo:

ODataDatasetAdapter1.AddRowSet(rctInserted, DataSet); /// põe na pilha um INSERT;
ODataDatasetAdapter1.AddRowSet(rctModified, DataSet);  /// põe na pilha um UPDATE
ODataDatasetAdapter1.AddRowSet(rctDeleted, DataSet);  /// põe na pilha um DELETE;
ODataDatasetAdapter1.ApplyUpdates(nil, rmPATCH);  /// atualiza o servidor com os dados da pilha;
ODataDatasetAdapter1.Execute;   /// faz um SELECT no banco de dados
ODataDatasetAdapter1.ClearChanges;  /// limpa a pilha

 

Código de exemplo que esta no projeto MVCBr.  no git

[code lang=”pascal”]
{ //************************************************************// }
{ // // }
{ // Código gerado pelo assistente // }
{ // // }
{ // Projeto MVCBr // }
{ // tireideletra.com.br / amarildo lacerda // }
{ //************************************************************// }
{ // Data: 10/03/2017 21:21:54 // }
{ //************************************************************// }
///
/// Uma View representa a camada de apresentação ao usuário
/// deve esta associado a um controller onde ocorrerá
/// a troca de informações e comunicação com os Models

….
DBGrid1: TDBGrid;

DataSource1: TDataSource;
/// Componente de Envio de mensagem HTTP para o servidor OData RESTful
IdHTTPRestClient1: TIdHTTPRestClient;
/// Construção de URL a ser enviado ao servidor
ODataBuilder1: TODataBuilder;
/// Desempacota a resposta do servidor e preenche o Dataset
ODataDatasetAdapter1: TODataDatasetAdapter;

/// Dataset que recebe a resposta do servidor – preenchida com o Adpater
FDMemTable1: TFDMemTable; /// FireDAC
Button1: TButton; /// botão GET
Button2: TButton; /// botão ApplayUpdates
….
private
FLoading: boolean; /// Flag para marcar se esta fazendo carga inicial da tabela.
FState: TDataSetState; /// Guarda o STATE do Dataset a ser usando no AfterPost
protected
public
{ Public declarations }

end;

Implementation

{$R *.DFM}

…..
/// No evento AfterPost do Dataset, armazena na lista de
/// alterações a serem enviadas para o servidor OData RESTful
procedure TRestODataAppView.FDMemTable1AfterPost(DataSet: TDataSet);
begin
if not FLoading then /// trata somente os registros alterados pelo usuário… (para não pegar os dados iniciais na carga da resposta do servidor)
case FState of
dsInsert: /// empilha os dados de INSERT – inserted
ODataDatasetAdapter1.AddRowSet(rctInserted, DataSet);
dsEdit: /// empilha os dados do POST – modified
ODataDatasetAdapter1.AddRowSet(rctModified, DataSet);
end;

end;

/// No ApplyUpdates do Dataset despachar para o servidor
/// as alterações armazenadas para serem notificadas
/// ao servidor
procedure TRestODataAppView.FDMemTable1BeforeApplyUpdates(DataSet: TFDDataSet);
begin
// envia os dados alterados para o servidor OData RESTful
ODataDatasetAdapter1.ApplyUpdates(nil, rmPATCH);
end;

procedure TRestODataAppView.FDMemTable1BeforeDelete(DataSet: TDataSet);
begin
/// empilha os dados a serem de DELETE – deleted a ser enviado ao servidor
ODataDatasetAdapter1.AddRowSet(rctDeleted, DataSet);
end;

procedure TRestODataAppView.FDMemTable1BeforePost(DataSet: TDataSet);
begin
/// guarda o estado da linha (dsEdit, dsInsert) para uso no AfterPost
FState := DataSet.State;
end;

procedure TRestODataAppView.FormCreate(Sender: TObject);
begin
/// um exemplo de como adicionar CustomHeaders a mensagem que será enviada ao servidor
IdHTTPRestClient1.IdHTTP.Request.CustomHeaders.AddValue(‘token’, ‘abcdexz’);
end;

procedure TRestODataAppView.Button1Click(Sender: TObject);
begin
FLoading := true; /// controle para não gerar linhas de alterações na pilhas
try
/// executa um GET no servidor RESTful
/// o servidor fazer um SELECT e devolve o conteúdo as linhas do SELECT
ODataDatasetAdapter1.Execute;
/// limpa alterações que estejam armazenadas
ODataDatasetAdapter1.ClearChanges;
finally
FLoading := false;
end;
end;

procedure TRestODataAppView.Button2Click(Sender: TObject);
begin
FDMemTable1.ApplyUpdates(); /// processa a alteração do Dataset
end;

[/code]

 

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *