Posts Tagged ‘rails’

Efeitos colaterais, programação funcional e ruby

20 de outubro de 2010

Durante a última turma de formação Rails, surgiu uma dúvida relativa a algumas idéias do mundo funcional que Ruby utiliza. É comum o uso do método returning em Rails para dar uma mão e permitir acessar um objeto, além de retorná-lo:

É uma idéia comum no mundo funcional, podendo ser pensada da seguinte maneira: precisamos executar diversos processos com efeito colateral mas estamos interessados em um único retorno.

Uma implementação comum nesse mundo seria:

Implementação de k_comb em uma linguagem funcional qualquer

Ao invocarmos k_comb com uma série de funções, somente a primeira possuirá seu valor retornado: todas as outras são executadas e seu retorno é ignorado. Por isso uma consequência direta é que ao usar tal padrão, estamos fazendo uso de efeitos colaterais.

O Ruby 1.9 já fazia:

Implementação usando o exemplo tap do Ruby 1.9

Com o tappie o ruído da variável extra pode ser removido, indo além da implementação do Ruby e do Rails, de uma maneira bem simples:

Implementação usando Tappie

Usar tais recursos de linguagens funcionais no mundo orientado a objetos de Ruby ajuda a diminuir o ruído semântico da linguagem, mas ao mesmo tempo é possível ir ainda além do que a linguagem Ruby nos fornece. Esse exemplo de implementação de k_combinator é uma possível extensão para o próprio Ruby.

Outras bibliotecas fornecem exemplos de funções como operadores.

Anúncios

REST a partir do zero

29 de abril de 2010

Esse é o primeiro post em uma série mostrando como usar Rails e Restfulie no servidor e Restfulie e Mikyung no cliente para criar uma arquitetura REST.

Nesse primeiro vídeo de 10 minutos você aprende a implementar em uma linha de código do Restfulie diversas representações (xml, json, atom) no servidor e também com uma linha, a enviar, receber, atualizar etc dados a partir do cliente.

Nos próximos vídeos sairemos do nível 1 do modelo de maturidade de uma arquitetura REST e passaremos para sistemas completamente REST.

Quaisquer dúvidas, junte-se ao nosso mailing list ou fale comigo no twitter.

Filtros REST em Rails e Java

18 de março de 2010

Para aqueles que gostariam de ver somente o conteúdo relativo as notícias de gerenciamento ágil, assinem o feed da categoria agile.

Para quem gostaria de assinar o feed completo, utilize o feed principal.

Muitas aplicações web possuem páginas de relatórios com campos para filtragem. O exemplo mais famoso é o caso onde o usuário pode configurar a data inicial e final para filtragem de dados.

FIltragem de dados

Mas o que acontece quando o usuário clica em qualquer link desse relatório, ou de relatórios consecutivos que aparecem após o mesmo? A data se perde. Em situações genéricas, o filtro se perde.

Vou exemplificar três maneiras de implementar tal funcionalidade.

Armazenar na sessão

É muito comum ver aplicações onde na primeira tela somos responsáveis por escolher, por exemplo, com qual unidade, centro de custo ou contrato desejamos trabalhar e, a partir de então, com tal valor armazenado na sessão no lado do servidor, temos acesso a URIs como http://www.projeto.com.br/clientes que retornaria a lista de clientes de uma unidade.

O que acontece se desejo trabalhar com clientes de duas unidades ao mesmo tempo, em abas distintas? Tenho que mudar de unidade a cada clique que executo com clientes de unidades diferentes.

Além disso, caches públicos como proxies entre o servidor e o cliente não terão o mesmo ganho de desempenho com URIs identificadoras de recursos reais.

O load-balancing também se torna custoso pois a sessão fica presa a uma máquina ou deve ser replicada em determinados momentos.

Tudo isso acontece pois sua aplicação é stateful, quebrando uma das regras da arquitetura REST.

O escopo flash é uma solução que cai nessa categoria.

Parâmetros do request

Outra solução é quando as características do filtro são passadas por parâmetros em uma URI do acessada através de GET.

parametros get

Nesse caso, podemos sobrescrever o método utilizado para definição de links para sempre adicionar os parâmetros de filtagem (url-rewriting):


  # remembers the starting and end date on all links
  def url_for(options = {})
    options[:start_date] = params[:start_date]
    options[:end_date] = params[:end_date]
    super(options)
  end

  public String urlFor(Class resource, String method) {
     return "/" + resource.getName() + "&start_date=" + params("start_date") + ...;
  }

Note que em ambos os casos é possível criar um componente que decide se o parâmetro de filtragem deve ou não ser adicionado.

Com um único método (monkey patch no Rails ou definição de tag no Java) somos capazes de resolver o problema em todos os links de um sistema.

Note que com essa abordagem, não existem os problemas de sessão apresentados anteriormente.

Armazenar um cookie no client

Aqui, como na solução baseada em sessões, existe o problema do trabalho em unidades distintas em diversas abas.

Uma vez que o cookie registrou informações relativas ao estado do cliente no processo definido no servidor, as próximas requisições irão levar em consideração tal informação, em todas as abas.

Novamente perdemos escalabilidade e, se usado em conjunto com sessões, temos um fator a mais negativo no load balancing.

REST

A segunda solução é a única que se aproxima mais de uma arquitetura REST: o servidor não mantém estado e a URI identifica um recurso, onde, por exemplo, open search pode ser utilizado para o sistema de filtragem.

O segredo está em deixar o cliente através de recursos identificados por URIs, ser guiado pelo servidor, e nenhum dos dois armazenem informações relativas ao estado atual de um processo. Os recursos e seus links ditam o processo (HATEOAS).

Note que de todas as soluções, ela foi a mais simples de trabalhar e com mais vantagens.

Além disso, não foram usados cookies que quebram a transparência para layers intermediários.

Fuja de cookies e de sessões, viva uma vida mais rest.