REST com Lazy Loading

Sei que o título é meio estranho, mas não tive uma idéia melhor. rs…

Contextualizando:

Acabei de criar um serviço REST utilizando: Spring-MVC e o Jackson-JSON.
Estou consumindo este serviço com uma interface gráfica EXT-JS.

A biblioteca EXT-JS resolveu indiretamente, com algumas particularidades, um problema de leitura das associações entre os objetos (Agregações e Composições), coisa que o Hibernate ou qualquer outro JPA provider resolve com Lazy Loading.

Hoje surgiu a necessidade de uma aplicação Java consumir o serviço que eu criei.

Como meu serviço é implementado em java, já tenho boa parte da infra criada, teoricamente seria simples criar um cliente com JSON marshalling automático.

A abstração do cliente seria com a mesma interface que eu abstraio a persitência dos dados, isso mesmo, um Repositório. Afinal quais são as operações de um repositório? Create, Retrieve, Update e Delete fazendo um paralelo com REST POST, GET, UPDATE e DELETE. Falando nisso quais são mesmo as operações disponíveis em um EntityManager? São paralelas também né? Pelo menos ao meu ver são, o que vocês acham? Qual seria a diferença entre acessar um repositório JPA ou REST?

Decidi fazer a implementação do repositório REST com a biblioteca HttpClient da Apache. Tudo ia de vento em poupa até que me dei conta das associações entre os objetos. Meu Deus! Como vou lidar com isso? Vou ter que implementar algo como o lazy loading do hibernate? FFFuuu$%#%%.

Alguém conhece alguma implementação pronta que faz isso? Ou tem uma sujestão de implementação? Ou queira debater minha visão?

Já dei uma olhada por alto no Jersey Client API e me pareceu que ele faz marshalling, mas como cuida das associações entre os objetos? Será que cuida?

Mais uma vez conto com a ajuda de vocês!

Dependendo do nível de maturidade dos teus servicos hipermidia pode lhe ajudar.

Nossa! Há um tempo atrás já tinha visto uma dicussão sobre a utilização de hipermidia para representar relacionamentos na WADL, porém nem me lembrava. No meu serviço há uma relação Tipo de Recurso e URI, por causa disso não me surgiu a necessidade de mapear os relacionamentos com hipermedia, mas provavelmente irei faze-lo.

Mas meu problema não é esse! Meu problema é: Como controlar o load de objetos, como fazer um lazy loading?

Exemplo:

  • Usuário tem um único endereço.
  • Eu recebo um json de usuário que tem os dados de usuário, mas não tem o endereço.
    {
    nome: “brunohansen”,
    endereco: “/endereco” (Se tratando de path relativo ficaria absoluto assim /usuarios/brunohansen/endereco)
    }
  • Eu materializo este json em um objeto Java, mas o endereço não esta presente, como posso criar um mecanismo para interceptar a chamada do método usuarioX.getEndereco() e fazer o load do recurso? (Como se fosse um lazyloading do hibernate).

Esse é o meu problema, não existe algo que faça isso pra mim? Ou como seria uma boa forma de implementar isso?

Já dei uma olhada no Restfulie, mas quero algo mais transparente. Denovo, quero usar um serviço Rest como se estivesse usando um repositório qualquer!

[]s e Valew pela força!

Não faço idéia do que isso significa em um contexto REST. Sabe porque, a comunicação entre sistemas REST usa o protocolo HTTP e formatos hipermidia, não objetos, se o servidor é feito em java ou brainfuck não importa, por definição não se deve assumir nada a respeito de qual tecnologia é usada no servidor para implementar um cliente REST. Se esta pensando em alguma solução de ligar objetos distribuídos para implementar algum mecanismo automatico por debaixo dos panos, como fazem projetos como Restufulie, isso é o mesmo que dar meia volta e ir ao oposto do que é REST. Repito, REST não é sobre distribuir objetos.

Estranha sua justificativas, mas, enfim, dependendo do nível do REST ele pode usar HTTP como:

1- Protocolo de transporte, só para fazer um túnel HTTP ou
2- Protocolo de aplicação, usa-se os verbos GET, PUT, POST e DELETE, e seu mecanismo de erro.

O segundo é o mais desejado. Você pode saber mais sobre isso aqui: http://martinfowler.com/articles/richardsonMaturityModel.html

A respeito da hipermedia, é simplesmente uma forma de relacionar recursos.

Por que, necessariamente, não objetos? Até onde eu sei posso representar qualquer coisa como objeto, até um documento HTML pode representado por um objeto, é só você escolher usar a abstração com objetos!

[quote=Renato Machado]
se o servidor é feito em java ou brainfuck não importa, por definição não se deve assumir nada a respeito de qual tecnologia é usada no servidor para implementar um cliente REST.[/quote]

Realmente a tecnologia usada no servidor não importa, o que importa mesmo é o formato que os resources são trocados: XML, HTML, JSOM etc…

Porém, se meu servidor usa uma classe java para representar cada Resource, nada mais simples que utiliza-las no lado do cliente para facilitar a minha vida na hora de manipular os dados recebidos do servidor.

Nada me impede de consumir o serviço com Ruby, porém seria elegante eu criar uma classe Ruby para cada Resource que eu vou consumir.

Restufulie esta indo ao oposto do que é REST?

Acho que o pessoal da Caelum tem experiência e algum crédito, para dizermos que não ficariam tanto tempo em cima de um erro conceitual!

Mas, se eles estiverem com um erro e conceito nós, a maioria, excluindo você, estamos com o mesmo erro conceitual! Tomara que alguém do Restufulie exponha sua opinião.

Objetos é só uma abstração para os dados! Se você achar melhor pode chamar de dados, mas eu ainda vou utilizar objetos para manipular esse dados rs…

Que continuemos debatendo nossas idéias!

[]s

Ou seja, não podemos subestimar a importância da hipermidia no REST se o próprio Roy Fielding já alertou sobre sua importância!

[quote=brunohansen]
Por que, necessariamente, não objetos? Até onde eu sei posso representar qualquer coisa como objeto, até um documento HTML pode representado por um objeto, é só você escolher usar a abstração com objetos![/quote]

O lance não é sobre o que objetos são capazes de representar, e sim que objetos não fazem parte da especificação do protocolo HTTP.

Mas sabe qual o problema que eu vejo, é que REST é para sistemas de larga escala como a web, onde não se pode assumir que tecnologia cada computador vai possuir. Se você tem controle do cliente e servidor pra decidir que dois objetos trocando mensagem é a solução mais elegante provavelmente você não precisa de REST. Portanto não se preocupe que você deve estar no caminho certo. rs

Creio que a experiência e creditos da Caelum são independentes da definição do REST. Mas sim, criar objetos e gerar stubs no cliente são uma grande sacada, mas não é REST.

Mas que fique claro uma coisa, não sou contra qualquer framework ou solução que usa objetos, se ela servir para o problema, não importa se é REST ou não.

Uai, se isso é simples então qual o problema? REST não é feito para facilitar sua vida, mas para facilitar a criação de sistemas de escala global onde não se pode assumir que tudo é um objeto java. Cada um com seus problemas. :wink:

Com relação ao lazy loading em arquiteturas verdadeiramente REST, já está embutido na própria arquitetura, é apenas uma questão de estabelecer uma política por parte do cliente sobre como lidar com certos links, por exemplo, um browser não precisaria baixar o resource imagem de uma tag IMG em um documento HTML se aquela parte do documento não estiver sendo exibida na tela, só quando o usuário move a janela de visualização onde é possível ver a imagem.

Isso. A idéia é que REST, em tese, não deveria manter estado entre cliente/servidor (HTTP!). Dado uma resposta, fim daquela relação. Entao com base no que o Renato disse, podemos ter uma idéia de lazy loading se linkarmos a sua representação. Lazy loading é sob demanda, Hipermidia eh sob demanda.

<pessoa id="4"> <filhos rel="http://xpto.com/pessoas/4/filhos" /> </pessoa>

só trará os filhos quando… pessoa(xml|json|whatever).filhos (politica do cliente de como lidar com isso, repetindo as palavras do Renato)

abraços.

Isso. A idéia é que REST, em tese, não deveria manter estado entre cliente/servidor (HTTP!). Dado uma resposta, fim daquela relação. Entao com base no que o Renato disse, podemos ter uma idéia de lazy loading se linkarmos a sua representação. Lazy loading é sob demanda, Hipermidia eh sob demanda.

<pessoa id="4"> <filhos rel="http://xpto.com/pessoas/4/filhos" /> </pessoa>

só trará os filhos quando… pessoa(xml|json|whatever).filhos (politica do cliente de como lidar com isso, repetindo as palavras do Renato)

abraços.

[/quote]

Até ai td bem! Esta não é a questão.

Rs… tenho, realmente, dificuldade em me expressar!

A questão é como fazer um mecanismo que deixe transparente as requisições sob demanda das hipermedias.

Como interceptar uma chamada a pessoa.getFilhos() e fazer o load dos filhos no end “http://xpto.com/pessoas/4/filhos” e assim por diante?

[]s

Então, esta é a parte que entra as “politicas do cliente”, não sei se já existe algo pronto para este teu caso (gerando o objeto provido de interceptacoes nos metodos com links), mas caso não exista, eis uma ótima oportunidade para um projeto open-source! :slight_smile:

Quem sabe um…

response = Ajax.at(pessoas).get(); response.filhos ... ?

Mas da uma pesquisada antes, as vezes já existe… para json/atom

O pessoal da Caelum que está mais ligado nisso (RestFulie) poderia dar uma melhor contribuição.

Abraços.

Edit: (acho que já tem!)

O Restfulie não é tão transparente quanto eu gostaria, porém pode ser usado para ficar no meio de campo, apesar que tenho uma tendência maior a preferir Jersey Client API a Restfulie.

Acho que a resposta para minha dúvida inicial é CGLib!

Depois de tudo, gostaria de pedir desculpas por te dados tantas voltas para fazer você entender minha dúvida. De repente foi útil para discutirmos a respieto de REST.

{}S

[quote=brunohansen]
Até ai td bem! Esta não é a questão.

Rs… tenho, realmente, dificuldade em me expressar!

A questão é como fazer um mecanismo que deixe transparente as requisições sob demanda das hipermedias.

Como interceptar uma chamada a pessoa.getFilhos() e fazer o load dos filhos no end “http://xpto.com/pessoas/4/filhos” e assim por diante?

[]s[/quote]

Isso é trivial em qualquer linguagem de programação, basta associar a ação “conectar com determinada url” à um determinado evento no cliente.

Quer dizer, a menos que esteja novamente distribuindo objetos…


editado: link correto para artigo.

Por favor, me mostre então esta solução tão trivial!

Como o peerless disse acho que cabe até um projeto para fazer o que eu quero. É o que o pessoal ta fazendo com o Restfulie.

Ainda acho que você não entendeu o problema.

[]s

O pessoal tenta distribuir objetos a décadas e nunca chegaram a lugar nenhum. O que mudou em 2011?