Plataforma Nuvem

Aplicativos baseados na Internet

RIA com Azure

leave a comment »

Aplicativos na nuvem, com a praticidade da web e a usabilidade do desktop. Esta é a proposta do conceito RIARich Internet application. Este modelo consiste em um aplicativo com interface rica executando no cliente comunicando-se com um web service executando em servidores na nuvem. O estado da sessão fica armazenado no cliente e os dados persistentes ficam armazenados em um banco de dados na nuvem (relacional ou não).

Em 2008 eu publiquei uma série de artigos descrevendo um projeto com esta arquitetura, utilizando Flex para o cliente com interface rica, Google App Engine como plataforma de nuvem, linguagem Python para o web service, o Datastore do App Engine para armazenar os dados, e o formato AMF para serialização de dados entre cliente e servidor.

Há muitas alternativas de ferramentas e tecnologias para implementar RIA. Uma combinação interessante seria JavaScript para o cliente com interface rica, Windows Azure como plataforma de nuvem, framework .NET para o web service, o Table Service do Azure para armazenamento, e o formato JSON para transferência de dados.

Arquitetura RIA com Windows Azure

Um web service no estilo REST pode ser implementado de diversas maneiras no Azure. Talvez a mais simples seja não implementá-lo: simplesmente publicar diretamente o Table Service para o cliente RIA. O Table  Service possui uma interface REST e permite acesso seguro utilizando autenticação. Os recursos disponíveis podem ser suficientes para várias aplicações, mas há limitações. Em primeiro lugar, o formato JSON não é suportado, o que vai exigir processamento adicional no cliente JavaScript para converter dados. Adicionalmente, para aplicações que necessitam de regras de negócio, validação, autorização granular, bilhetagem e, de modo geral, uma lógica de negócio e acesso a dados mais complexa no servidor, o acesso direto do aplicativo cliente não é o modelo mais eficaz.

Outra alternativa interessante seria o WCF Data Services, que já foi conhecido como “ADO.NET Data Services”, que já foi conhecido como “Astoria”. Esse é um framework muito interessante, que expõe dados na forma de entidades através de web services modelo REST, e que suporta o formato JSON. Muito promissor, e muito prático de usar em conjunto com o ADO.NET Entity Framework. Porém o Entity Framework não possui um provider para o Table Service do Azure. Também não existe um provider para o WCF Data Services compatível com o Table Service. Isto significa que seria necessário escrever um Data Service Provider.

CustomDataServiceProvider

O artigo sobre o assunto singelamente informa que “uma espiada na figura deveria convencê-lo que implementar um data service provider completo é um investimento significativo”. Se a advertência não for suficiente para abandonar a idéia, o fato é que implementar um WCF Data Service provider que use o Windows Azure Table Service é ainda mais complexo, porque o Table Service implementa apenas um subconjunto das funcionalidades necessárias. Investigações adicionais trarão informações como esta:

You’re asking for something we internally call “Astoria over Astoria” (Astoria was the code name for WCF Data Services). This doesn’t work out of the box, not even close. There are some really hard problems to solve and as of now it doesn’t seem to be 100% possible (the WCF Data Services client has different set of abilities than the server and some queries the server uses are not expressible in the OData protocol). [1]

This approach we call Astoria over Astoria, and it’s really hard to make it work correctly. You can see a sample code of how one could go about it in the OData Provider Toolkit. It’s under Experimental/AstoriaOverAstoria. But please do not use this in a production environment, it’s really meant as a sample only. [2]

Se o WCF Data Services não ajuda neste cenário, o WCF puro pode ser a solução. Certamente é possível criar um serviço WCF no modelo REST, e o WCF suporta o formato JSON. Por outro lado, WCF é uma solução grande, multi-tudo: multi-modelo de programação, multi-protocolo, multi-transporte, multi-formato…

WCF_Architecture

Sem dúvida é a forma mais recomendada para criar uma camada de serviços para aplicativos corporativos que precisam ser acessados das mais diversas maneiras, desde SOAP/XML sobre HTTP até TCP com serialização binária, passando por OData. Por outro lado é um framework complexo, com muitos conceitos, e algumas particularidades quando usado com formato JSON que dificultam a vida.

Se os requisitos forem mais simples, a solução também pode ser mais simples. Para um aplicativo RIA como o proposto aqui, o que é necessário é protocolo HTTP, formato JSON e um mecanismo de roteamento de URLs para implementar o modelo REST.

O ASP.NET MVC atende estes requisitos e oferece funcionalidades úteis como autenticação e modelo de programação MVC, sem cobrar um preço muito alto em termos de conceitos, complexidade, configuração e rigidez. É simples, flexível e compatível com mecanismos de testes unitários e inversão de controle.

O projeto RestfulMvcExample é uma prova de conceito minimalista que exemplifica a criação de um serviço no modelo REST usando formato JSON no ASP.NET MVC 3. Não é implementado um cliente RIA, mas há um teste integrado que simula chamadas ao serviço e exibe as respostas recebidas.

O núcleo do projeto é a classe ContactsController.cs, que é um controller, ou seja, é a classe que processa as requisições recebidas. Esta classe implementa 5 métodos no modelo REST:

  1. // Obtém todos contratos
  2. public ActionResult Index()
  3. {
  4.         var data = _repository.GetAll();
  5.         return Json(data, JsonRequestBehavior.AllowGet);
  6. }
  7.  
  8. // Obtém um contrato
  9. public ActionResult Get(int id)
  10. {
  11.         var data = _repository.Get(id);
  12.         return Json(data, JsonRequestBehavior.AllowGet);
  13. }
  14.  
  15. // Inclui um contrato
  16. public ActionResult Post(Contact contact)
  17. {
  18.         _repository.Add(contact);
  19.         return Json(contact);
  20. }
  21.  
  22. // Atualiza um contrato
  23. public ActionResult Put(int id, Contact contact)
  24. {
  25.         _repository.Update(id, contact);
  26.         return Json(contact);
  27. }
  28.  
  29. // Exclui um contrato
  30. public ActionResult Delete(int id)
  31. {
  32.         _repository.Delete(id);
  33.         var data = new { message = “Contact deleted.” };
  34.         return Json(data);
  35. }

O roteamento, ou seja, a chamada do método correto na classe correta com base na URL solicitada pelo aplicativo cliente, é feito pelo ASP.NET MVC com base nesta definição genérica no arquivo Global.asax.cs:

  1. routes.MapRoute(
  2.         “get-index”,
  3.         “{controller}”,
  4.         new { controller = “Home”, action = “Index” },
  5.         new { httpMethod = new HttpMethodConstraint(“GET”) }
  6. );
  7. routes.MapRoute(
  8.         “get-object”,
  9.         “{controller}/{id}”,
  10.         new { action = “Get” },
  11.         new { httpMethod = new HttpMethodConstraint(“GET”) }
  12. );
  13. routes.MapRoute(
  14.         “post-object”,
  15.         “{controller}”,
  16.         new { action = “Post” },
  17.         new { httpMethod = new HttpMethodConstraint(“POST”) }
  18. );
  19. routes.MapRoute(
  20.         “put-object”,
  21.         “{controller}/{id}”,
  22.         new { action = “Put” },
  23.         new { httpMethod = new HttpMethodConstraint(“PUT”) }
  24. );
  25. routes.MapRoute(
  26.         “delete-object”,
  27.         “{controller}/{id}”,
  28.         new { action = “Delete” },
  29.         new { httpMethod = new HttpMethodConstraint(“DELETE”) }
  30. );

A partir destas definições, mais a classe Model e seu respectivo repositório para gerenciar o acesso a dados, o serviço consegue responder a solicitações REST gerando dados no formato JSON como neste exemplo:

GET http://localhost:62983/contacts

  1. [{“Id”:1,“Name”:“Contact one”,“Email”:“one@example.com”,“Phone”:“555-1111”,“Href
  2. :“/contacts/1”},{“Id”:2,“Name”:“Contact two”,“Email”:“two@example.com”,“Phone”:
  3. “555-2222”,“Href”:“/contacts/2”},{“Id”:3,“Name”:“Contact three”,“Email”:“three@e
  4. xample.com”,“Phone”:“555-3333”,“Href”:“/contacts/3”}]

Esta prova de conceito demonstra que o ASP.NET MVC pode ser utilizado para criar web services REST/JSON com uma arquitetura simples e flexível. Funcionalidades como autorização e regras de negócio podem ser implementadas com código nas classes Controller e Model. Um maior controle da formatação das respostas pode ser obtido com a utilização de classes ViewModel nos controllers.

Os fontes estão disponíveis para download no site do projeto RestfulMvcExample.

Written by Fernando Correia

7/maio/2011 às 14:31

Publicado em Geral

Tagged with , , , , ,

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s