WebService do tipo REST

Alguem aqui já fez algum webservice do tipo REST ?

Em java… por onde comecar ?

Olá

REST = Representational State Transfer e o conceito surgiu em 2000 com a tese de doutorado do Roy Fielding.

Se pode entender como REST qualquer Web Service que pode ser acessado com uma requisição simples HTTP GET.

Basicamente você pode criar um cliente com Swing enviando um request via URLConnection e receber de volta um xml resultado que deverá parsear. Diretamente do browser se pode também acessar o serviço mas como a resposta costuma vir em xml, fica meio difícil fazer algo com ela.

Googlando se pode achar muitos tutoriais sobre o que é e como usar REST. Que eu me lembre, no XML.com tem um monte de textos do Joe Gregorio (criador do ATOM) e tem um tutorial do Roger Costello no xfront.com.

Muitas empresas servem web services com REST. A Amazon diz a partir de estatísticas de tráfego, que 90% do uso dos seus web services são baseados em REST

O Google baseou seus WS em SOAP porém o Yahoo oferece uma API para busca baseada em REST. Veja http://developer.yahoo.net/.

E experimente o Yahoo:
http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid=00000000&query=GUJ+chun

Na verdade o conceito inicial da tese do Roy Fielding não usava a query string do GET. Ele se baseava apenas na URL e no uso do HTTP

Assim, para acessar um serviço que retornasse todos os posts do Chun no GUJ se escreveria algo como:
http://www.guj.com.br/posts/Chun

Para ler um post_especifico seria:
http://www.guj.com.br/posts/Chun/post_especifico

Para apagar se usaria o HTTP DELETE e para incluir ou atualizar o HTTP PUT.

Na prática ninguém usa o conceito do Roy exatamente como ele criou porque significaria projetar todo o site já deste jeito. E isto foge do conceito de reaproveitar código fornecendo WS a partir de aplicações prontas que é uma das vantagens de web services.

[]s
Luca

Valeu :wink:

Ressuscitando este tópico, como ficaria uma chamada usando REST para mais de um parametro, por exemplo:

http://www.exemplo.org/rest/tickets*****(tickets com status igual a aberto e direcionados para o usuário ‘abcs’)*****

Assim:

http://www.exemplo.org/rest/usuario/abcs/ticket/aberto

Você vai encadeando os parâmetros, sendo que cada item que separa a barra limita a consulta anterior.

Ou usando query string:

http://www.u-érre-éle.com/rest?query=tickets&status=aberto&usuario=abcs

caraka Luca, que aula!!!
Parabéns pela clara explicação. Vou aprender REST agora, fiquei super curioso.

Abraços

O REST seria trocar toda a parafernália de RPC, RMI e WebServices por simples chamadas HTTP a um web server?

Eu sempre dei preferencia a simplicidade de uma chamada HTTP ao invés de optar pela parafernália de uma requisição remota. Dizem que xFire resolve esse problema, mas já em 2004 eu sugeria o seguinte:

Fonte: http://www.guj.com.br/posts/list/15760.java

Bem, vou seguir a ideia do Leonardo3001…
Estou montando um framework para um cliente onde eu pretendo disponibilizar tudo em REST… está ficando legal! Em breve estarei colocando exemplos aqui no GUJ pra galera…
Só pra dar gostinho, eu posso fazer coisas deste tipo:

http://www.exemplo.org/usuario (Lista todos os usuários)
http://www.exemplo.org/usuario.login/rodrigoallemand (detalha o usuário)
http://www.exemplo.org/usuario.login/*allemand (lista todos os usuários onde o login termine com allemand)
http://www.exemplo.org/venda.status/finalizada/venda.produto.precocusto/>10 (lista todas as vendas finalizadas onde o preço de custo do produto é maior que 10)

DETALHE: Sem nada de ficar configurando um monte de URIs pra lá e pra cá…

Rodrigo, por que você adotou essa separação por resource na URI(/usuario/, /venda.status/) e não query String do método GET?

[quote=saoj]
O REST seria trocar toda a parafernália de RPC, RMI e WebServices por simples chamadas HTTP a um web server?

Eu sempre dei preferencia a simplicidade de uma chamada HTTP ao invés de optar pela parafernália de uma requisição remota. Dizem que xFire resolve esse problema, mas já em 2004 eu sugeria o seguinte:

Fonte: http://www.guj.com.br/posts/list/15760.java[/quote]

Legal! É por isso que eu gosto do REST.
Mas tem 2 coisas legais no REST que ninguém falou:
1- A variedade de formato de representação: o cliente sempre manda os mime types que ele é capaz de processar, pode ser text/plain, application/xml ou outros. Quem tá servindo REST pode responder em vários formatos diferentes, dependendo do que o cliente está mandando. Assim, posso responder com uma imagem (image/gif), um xml (application/xml), um json (application/json) ou um objeto Java serializável (application/x-java-serializable), é só o cliente escolher.

2- O uso de links como referências: se o cliente quer buscar um pedido, só que o pedido sempre é feito por um comprador, o objeto possui uma referência para um comprador. Ok. Mas na hora de serializar, eu não preciso colocar toda a representação do comprador, basta uma referência URL como por exemplo http://www.exemplo.org/comprador/425 . Se depois disso, o cliente quiser ver o comprador, basta chamar a URL que recebeu quando viu o pedido.

Legal, mas na prática seria melhor se todo mundo optasse por um formato só. Eu gosto muito de objeto serializado em base64 zipado. Mas aí seria só para clientes Java. JSON/XML pode ser melhor para suportar qualquer tipo de cliente.

Não entendi. Vc diz se eu tenho um objeto que contem usuário, eu mando o link do usuário ao invés do objeto usuário inteiro? Explica melhor… :slight_smile:

É um tipo de coisa que só se consegue explicar em código. Vamos lá!
Imagine que eu tenha a classe Pedido:

public class Pedido {
	
	private Long id;
	private String nomeProduto;
	private BigDecimal valor;
	private Comprador comprador;
	
	// getters, setters e tudo mais 

}

e eu tenha a classe Comprador:

public class Comprador {
	
	public Long id;
	public String nome;
	public String sobrenome;
	
	public Collection<Pedido> pedidos;
	
	// getters, setters e tudo mais

}

Podemos ver que um pedido é feito por um comprador e que um comprador possui vários pedidos.

Imagine que eu faça um GET no endereço http://www.exemplo.org/pedido/5, e que me retornaria um JSON, que seria a deserialização pura do objeto:

{"pedido":
    {"id":5,
     "nomeProduto": "Nintendo Wii",
     "valor": "2000,00",
     "comprador":
         {"id": 12,
	      "nome": "Beltrano",
	      "sobrenome": "Silva",
	      "pedido" : ### hummmmm.... começou a complicar!  ###
	     }
    }
}

Vai ficar muito grande se eu resolver devolver o pedido e todos os objetos que os referenciam, ia correr até risco de uma referência circular.

Por isso, eu só devolveria a referência do comprador:

{"pedido":
    {"id":5,
     "nomeProduto": "Nintendo Wii",
     "valor": "2000,00",
     "comprador": "http://www.exemplo.org/comprador/12"
    }
}

Repare, a referência é uma URL! Se eu não quiser saber do comprador, tudo bem, eu não carreguei essa informação do servidor. Mas se eu quiser saber, basta pegar essa URL que está dentro de pedido e fazer uma nova requisição GET.

Seria um lazy-loading via http? :slight_smile:

[quote=saoj]
Seria um lazy-loading via http? :-)[/quote]

Pensei na mesma coisa.

O Leonardo esta mostrando a maneira bonita e ideal de implementar rest, parabens! é assim mesmo.

Mas, se voce for ver por ai, ate mesmo as grandes empresas que o Luca cita na assinatura dele não usam rest dessa maneira. O Flickr da yahoo, por exemplo, se diz restful, mas usa a mesmissima URL para todos os servicos, nao tendo a ideia de aproveitar a URI:
http://www.flickr.com/services/api/

E cada um usa sua propria ideia de REST da maneira que o convem.

A JSR de Rest da Sun da suporte a implementar da maneira “correta” (que esta muito interessante alias, e o glassfish tem ela implementada beta no jersey):
http://www.jcp.org/en/jsr/detail?id=311

Fortemente baseada em anotacoes. Bem legal.

Po, sei lá… achei que ficaria melhor a visualização do que aquelas montagens de query string… mas no final ficou legal que a DSL já entende o que foi mandado, de qualquer forma… se fosse query string, eu teria que fazer uma procura especializada… ou não… sei lá…

Bem, respondendo, foi por uma melhor visualização e pra entendimento automativo da DSL…

[quote=Paulo Silveira] Mas, se voce for ver por ai, ate mesmo as grandes empresas que o Luca cita na assinatura dele não usam rest dessa maneira. O Flickr da yahoo, por exemplo, se diz restful, mas usa a mesmissima URL para todos os servicos, nao tendo a ideia de aproveitar a URI:
http://www.flickr.com/services/api/
[/quote]

Até agora, REST está me parecendo simplesmente RMI em cima de HTTP. Só que invês de objeto serializado, vc usa XML ou JSON para não ficar atrelado ao Java.

[quote=saoj]Até agora, REST está me parecendo simplesmente RMI em cima de HTTP. Só que invês de objeto serializado, vc usa XML ou JSON para não ficar atrelado ao Java.
[/quote]

Po, é uma comparação meio trivial… se for assim, qualquer coisa que vc faça uma chamada padronizada (URI) e ele responda de qualquer maneira que seja, é parecido com RMI, REST, EJB, CORBA, JMS, etc.

Acho que o legal do REST (e pelo que eu to vendo no levante desse topico) é a possibilidade de tornar simples um conceito que pra muitos era complicado…
Afinal, WebService nas vias “normais” (SOAP) é tranquilo tambem, mas eu sentia que causava medo em certas pessoas… JMS então, nem se fala… Já REST o pessoal entende que é HTTP e Servlet puro e aplicado…

Verdade, mas o grosso da idéia é isso. É aquela velha história: “Pra que simplificar quando se pode complicar?”

Fonte: http://www.manageability.org/blog/stuff/rest-explained-in-code

Acabei de descobrir uma diferença em relação a RMI. REST, diferentemente de RMI, só pode fazer chamada STATELESS. Isso é para facilitar o cache, simplicidade e escalabilidade.