Skip to content


Precisamos de um descritor de serviços REST?

Me perguntaram sobre isso na minha apresentação de REST na Globo.com e isso foi assunto de uma discussão interessante hoje no CEJUG. Como é um assunto que pode interessar a bastante gente e eu me interesso muito por web services, resolvi falar mais sobre isso aqui no blog.

Os web services WS-* possuem o WSDL (Web Services Description Language), um artefato amplamente aceito que descreve de forma padrão os serviços da aplicação. Ao especificar no WSDL quais são os schemas XML dos documentos que serão trocados e a cardinalidade precisa de cada elemento, conseguimos garantir que qualquer cliente que entenda o padrão estabelecido será capaz de interpretar os documentos e comunicar-se corretamente com os serviços. Além disto, a maturidade deste padrão traz a vantagem de que já existem geradores de clientes em várias linguagens a partir de um documento WSDL.

Entretanto, WSDL (bem como muita coisa em WS-*) é complexo. Um ser humano que tenha que analisar um WSDL grande perderá um bom tempo para entender o que está descrito no documento. Já REST não tem uma forma padrão de especificar os contratos dos serviços.

Embora a versão 2.0 da especificação WSDL permita descrever web services REST, os principais projetos open source da área como o Apache Abdera, Google Data API, Jersey e o Mule não utilizam esta forma de publicação. Não tenho conhecimento de nenhum projeto publicamente divulgado que faça uso do WSDL 2.0 para descrever serviços REST, e a adoção desta capacidade é baixíssima (se é que existe).

O projeto Jersey oferece opcionalmente o WADL, que é uma forma de descrever serviços REST. Confesso que ainda não olhei o WADL para ver se seria interessante usá-lo. Pelo que sei, entretanto, a adoção dele também é muito baixa.

Existe também o documento de serviços do AtomPub, que é bem interessante. Ele é um documento simples que lista quais são as coleções disponíveis e a localização das mesmas. O documento informa também quais são os MIME types aceitos em cada coleção.

Eu considero interessante que a aplicação ofereça uma interface simples de consulta dos serviços disponíveis. Não é obrigatório, mas quando a aplicação tem uma certa quantidade de clientes é bem legal ter isso para facilitar.

Em dois projetos que eu trabalhei, eu implementei um Servlet simples que listava todas as URIs disponíveis na aplicação, quais métodos HTTP são aceitos em cada uma das URIs e além disso um exemplo de XML manipulado em cada uma das URIs. Isso foi algo que eu achei bom o suficiente, e não tão custoso. Normalmente a documentação de verdade dos serviços fica em algum lugar como uma Wiki, ou uma página qualquer com a descrição detalhada de como interagir com os serviços.

A questão principal é que quando você segue as boas práticas de desenvolvimento REST, os seus serviços ficam muito mais claros para quem precisa se integrar. Por exemplo, eu trabalhei em um projeto crítico de integração com o Google esse ano. Tive que usar várias funcionalidades da Google Data API. A API deles é REST, e encapsula os dados com o formato Atom. Eles não oferecem nenhuma interface semelhante ao WSDL, eles simplesmente têm uma página com a documentação dos serviços.

Como eles seguiram as boas práticas de implementação REST, eu rapidamente aprendi a utilizar a API deles. Os protocolos de comunicação REST são bem semelhantes, e mais simples de entender do que qualquer coisa com WS-*. Pouco mais de 1 hora depois de olhar a documentação deles, eu já estava conseguindo me integrar com eles, com os primeiros exemplos.

O Guilherme fez uma observação interessante durante a discussão disso na minha apresentação no Tech Talk. Quando você segue as boas práticas e implementa um protocolo conciso e claro, de certa forma podemos dizer que a implementação se “auto-documenta”. É algo que podemos traçar um paralelo ao que acontece ao utilizarmos Domain Driven Design. Aproximando a linguagem do código do domínio de negócio, facilitamos a compreensão da aplicação por pessoas que nunca a tinham visto antes. Uma boa arquitetura de web services declarativos (REST) fica muito mais clara do que uma arquitetura de web services imperativos (WS-*). Isto acontece porque com REST o que fica em destaque são os Recursos (que representam conceitos claros do domínio), em vez de Operações.

É claro que as pessoas ainda terão que ler um pouco da documentação, mas como os conceitos em sua maioria já estarão “no sangue”, as dificuldades iniciais são menores do que com WS-*.

O Felipe Gaúcho comentou no CEJUG sobre a capacidade de gerar clientes automatizados com WSDL. Embora isso seja verdade, no meu ponto de vista isso é meio que um mito. Não conheço ninguém que faça integrações automatizadas sem depender de seres humanos. A motivação disso é clara. Integrações envolvem regras de negócio, e ninguém que eu conheço faz negócios automáticos, sem definir as regras :)

Existia o mito de que as aplicações “descobririam” serviços automaticamente com UDDI e se virariam para fazer as integrações, gerando os clientes automaticamente. Embora isso seja tecnicamente possível, na prática isso pra mim é uma viagem que serviria mais para desenvolvimento de inteligência artificial do que para web services propriamente :)

Embora esta precisão do WSDL seja um ponto positivo, eu tenho a convicção de que a clareza que temos ao usar REST supera e muito as vantagens de termos geradores de clientes automatizados. Quanto a WS-* x REST de uma maneira mais geral, tem uma frase que eu gosto de utilizar. WS-* é apenas overhead a não ser que você tenha informações relevantes nos seus cabeçalhos SOAP. Se você nunca se preocupou MUITO (veja bem, MUITO) com o que está indo nos seu cabeçalhos SOAP, provavelmente um protocolo REST seria mais interessante.

Tem uma opinião a respeito disso? Estou ansioso para conhecê-la! :)

Posted in posts em português.

Tagged with , , , , , , , , .


21 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Rafael Ponte says

    Excelente post Bruno!

    É muito interessante como REST está “ganhando terreno” a frente de WS-* em muitas aplicações hoje em dia, pelo que vejo a maioria dos projetos fornecem recursos/operações simples, na qual WS-* seria um “overhead” como você mesmo diz.

    Acredito que um Wiki com informações sobre os serviços é algo realmente simples para um desenvolvedor que está acostumado a ler dezenas de papers, how-tos e documentações para poder utilizar decentemente algum framework hoje em dia :)

    Enfim, parabéns pelo post, muito bom mesmo.

  2. Luca Bastos says

    Bruno

    Belo post. Concordo muito contigo

    Em um tutorial que dei sobre WS no ConexãoJava de 2006, disse que quanto mais estudava WS, mais acreditava em REST. Concordo também com o Dare Obasanjo quando disse que os maiores defensores de WS-* são aqueles cujos empregos ou clientes dependem disto.

    Discordo um pouco do Felipe Gaucho sobre o uso da palavra automatizado na capacidade de gerar clientes com WSDL. O chamado modelo de desenvolvimento “Start from WSDL” simplifica alguma coisa mas normalmente ainda dá bastante trabalho para implementar as interfaces e incluir lógica de negócio dentro das classes wrappers geradas. O uso da palavra “automatizado” dá a falsa impressão de que a vida é sempre simples como nos exemplos do tipo Hello World que aparecem por aí. Com WS-*as coisas nunca são simples.

    O WADL não é novo, ainda não pegou e nem sei se pegará, mas os autores do livro RESTful WS, que você já citou em outro post, defendem o uso de WADL como a solução mais simples e elegante para descrever os serviços(página 25). No capítulo 9 (que ainda não li) mostram um cliente para o del.icio.us usando WADL.

    Sobre a observação do GC sobre boas práticas acho que isto ainda não é muito comum com muita salada por aí e RPC demais para o meu gosto. Não é que ache que se deva banir totalmente o RPC mas acho que é uma coisa a ser evitada.

    PS: eitcha letrinha pequena aqui nos comentários do seu blog!

  3. Rafael Carneiro says

    Bruno,

    você já teve alguma experiência com WS-*?

    Seria interessante você elaborar um comparativo entre os graus de dificuldades das duas tecnologias, como transação, segurança, anexos, etc.

    Valeu pelo post! :)

  4. Felipe Gaúcho says

    Pontos em aberto sobre o REST:

    - validação de tipos e intervalos de dados
    - operações transacionais
    - interoperabilidade
    - número de chamadas ao serviço para simular transações e multiplos uploads (performance), e eventualmente descrição do serviço

    Procuro evitar sempre afirmações como “ganhando terreno”, ou outro tipo de expressão emocional que remete a um fetiche tecnológico.. isso diminui a qualidade da discussão.

    Já trabalhei em projetos REST e SOAP, e também já usei WSDL-Firts, Code-First ou REST definido em documento texto. No geral, o WSDL “defende” melhor a equipe de desenvolvimento, enquanto o REST joga toda a responsabilidade sobre os desenvolvedores e acaba gerando stress na equipe…. um escreve no documento, outro não lê ou entende errado e dê-lhe reuniões e brigas pra assumir o problema depois…

    Confesso que o WSDL exige um conhecimento sofisticado em XML para valer a pena. Discordo que o cabeçalho seja o grande trunfo do SOAP, na verdade o cabeçalho é mais usado para autenticação do cliente do que outra coisa. Na minha opinião, o grande conforto fica na validação embutida no contrato, e a capacidade de gerar serviço e proxy a partir de um único documento. Geralmente eu forneço aos desenvolvedores o WSDL e os testes de aceitação, e fico tranquilo que independente do que o desenvolvedor invente, o resultado final vai ser válido segundo o contrato. (ok, não existe esta pureza toda, mas o caos em torno de serviços definidos pelo WSDL tem sido menor que o caos de serviços desenvolvidos a partir de descrições em documentos texto)

    Atualmente trabalho com SOAP no emprego (WCF + CXF + Groovy), e desenvolvo meu protótipo open-source no CEJUG usando JAXWS. Sinto mais conforto usando JAXWS do que qualquer outra coisa que já tenha tentado ou forçado a tentar :)

    Quem quiser conferir o que estamos fazendo com JAXWS, todo o código fonte e a pouca documentação estão disponíveis no site do Cejug-Classifieds: https://cejug-classifieds.dev.java.net/

    Bom post, boa discussão, parabéns ao Bruno pelo tempo de escrever o bom texto..

    valeu,

    Felipe Gaúcho
    Coordenador CEJUG

  5. Felipe Gaúcho says

    um ultimo detalhe:

    O JAXWS provê o binding em SOAP e REST, (dual binding, semelhante ao AXIS). Estou planejando usar isso no classifieds, a partir da seguinte estratégia:

    - REST: operações de somente leitura e não transacionais (algumas)
    - SOAP: operações de escrita e/u transacionais (todas)

    Ou seja, o serviço vai ser soap 1.2 por default, mas algumas operações como leitura de RSS ou ATOM e que podem ser consumidas por agregadores já existentes e baseados em HTTP requests, eu pretendo liberar uma segunda forma de acesso..

    Não tive tempo de tentar ainda, mas acho que se for possível a custo baixa, seria uma ótima opção para os consumidores…

  6. blpsilva says

    @Rafael Ponte

    Realmente REST tem ganho bastante adesão ultimamente, pois as implementações estão amadurecendo e as pessoas estão percebendo o poder que esta linha de serviços traz.

    Para alguns serviços com requisitos bem especiais, temos que utilizar alguns recursos do WS-*, pois implementar de forma customizada com REST seria inviável. Entretanto, estes casos são bem poucos, e de uma maneira geral hoje em dia eu só utilizaria WS-* se precisasse me comunicar com algum serviço existente implementado desta forma. Tendo a liberdade de definir qual é a forma de integração, REST all the way.

  7. blpsilva says

    @Luca

    Realmente é difícil querer seguir com WS-* depois de conhecermos verdadeiramente o que pode ser feito com REST. Como você bem citou, a maioria das pessoas lá fora que defende ferrenhamente a continuidade de WS-* está fazendo isso por uma questão de preservar os investimentos já feitos, em vez de mérito técnico.

    Sobre o WSDL first, alguns comentários. Escrever um WSDL grande na mão é uma tarefa custosa. Eu já fiz isso em um projeto, e me tomou um bom tempo até acertar todos os detalhes que eu fui revisando. Você consegue gerar os esqueletos dos serviços e dos clientes depois, mas ainda tem que customizar a parte de negócio, e isso é que costuma ser o mais importante para qualquer projeto.

    Uma abordagem que eu utilizei em outras vezes foi começar “Bottom-Up”(escrever as classes e gerar o WSDL a partir delas), e aí adaptar o WSDL gerado e usar a forma “Top-Down” (gerar as classes a partir do WSDL). Isto foi bem mais prático, e seria a forma que eu utilizaria em novos projetos.

    Sobre o WADL, eu lembro que já o olhei rapidamente um tempo atrás, não gostei e não cheguei a ver mais detalhes. Eu tinha desgostado o suficiente para nem querer ver mais detalhes. Entretanto, o Jersey está oferecendo suporte a WADL (provavelmente porque o líder do projeto Jersey é o criador do WADL) e eu preciso olhar com calma depois para conhecer melhor os detalhes e ter uma opinião melhor formada sobre o assunto.

    Realmente ainda temos muita “salada” por aí, como você bem falou. Mas aos poucos as implementações REST vão evoluindo e as boas práticas ficarão mais comuns.

    OBS. a fonte dos comentários estava muito pequena mesmo, mas consegui ajustar no CSS aqui do blog ;)

  8. blpsilva says

    @Rafael Carneiro

    Eu tenho experiência com WS-* sim. Já trabalhei com isso em 3 projetos e além disso já estudei bastante sobre o assunto, fazendo alguns experimentos.

    Já utilizei o Axis 2, o XFire e olhei um pouco o JAX-WS. Só recentemente estou conseguindo usar Java 5 no trabalho, e então o JAX-WS não era uma opção para mim nos projetos que usei o Axis 2 e o XFire. Entre o XFire e o Axis 2, o XFire é mais fácil, mas te dá menos controle. O Axis 2 permite que você gere bastante coisa, mas te deixa manipular tudo que ele gera. O XFire esconde bem mais as coisas. O JAX-WS é bem legal e produtivo, e considero a melhor opção se você pode usar Java 5.

    Sobre o comparativo que você falou, seria interessante mesmo. Só não creio que terei tempo para preparar algo assim tão cedo. Estou penando para ter tempo de escrever os últimos artigos da JM, e esse comparativo tomaria um tempo bem grande. Vou considerar isso pro futuro de médio prazo :)

  9. blpsilva says

    @Felipe

    Bom, sobre as suas considerações:

    * Com REST você consegue validar qualquer coisa, não tem nenhuma restrição quanto a isso. Se vier qualquer coisa inválida, retorne um HTTP 400 (Bad Request) e indique qual foi o erro.

    * Não entendi bem as suas considerações quanto ao número de chamadas ao serviço, mas eu fiz testes de carga nos meus serviços REST que falam com o Google e com 150 threads fazendo requisições simultâneas aos serviços, tudo estava se mantendo sem problemas. E os serviços estavam rodando em uma máquina desktop nada parruda. A escalabilidade horizontal com REST é bem alta, de uma maneira geral.

    * Quanto a interoperabilidade, se você precisa se comunicar com um serviço WS-*, use WS-* e ponto final. Não tem margem pra escolha. Agora se você pode definir os contratos e o protocolo, REST te garante comunicação com mais clientes. Quase qualquer coisa sabe falar HTTP, mas não é tão fácil falar SOAP.

    Sobre a questão transacional, depende do que você quer. Se você está falando da transação que ocorre dentro do servidor onde rodam os serviços REST, você tem inúmeras maneiras de controlar a transação DENTRO deste servidor. Agora, se você quer que a transação da aplicação cliente e da aplicação servidora seja uma só, realmente será complicado.

    Se você precisar ter um controle transacional na linha de “Business Activity”, do WS-Transaction, use WS-*, sem dúvida. Implementar este tratamento em um protocolo REST ainda é feito de forma customizada, e eu não encararia uma encrenca dessas. Se sua aplicação tiver esses requisitos, use WS-Transaction, com as comunicações coordenadas com WS-Coordination, e Deus te abençoe! :)

    Eu particularmente nunca peguei requisitos transacionais assim. Sempre tive requisitos transacionais isolados no cliente e no servidor. O que eu faço é controlar a transação da aplicação cliente de acordo com o resultado enviado pelo servidor remoto. Se o servidor remoto disse que a operação nele foi OK, você pode prosseguir com a transação no cliente. Se o servidor remoto indicou uma falha, você precisa tratar na aplicação cliente, da forma que for mais correta.

    Sobre os cabeçalhos SOAP, não é que eles sejam um trunfo. A questão é que quando você tem requisitos complexos como WS-Transaction, WS-Security ou logs de auditoria obrigatórios, você será obrigado a acompanhar esses cabeçalhos. Se você gosta de SOAP principalmente pela validação dos XMLs, acho que você deveria olhar REST com muito carinho, pois ele fará bem para a sua vida, seu humor, sua alegria em trabalhar.. :)

    Quanto ao duplo binding de JAX-WS, ele até existe, mas é muito limitado para serviços REST. É por isso que existe a JSR-311, que trata especificamente de serviços REST.

    Com JAX-WS, como você definiria que um serviço aceita somente HTTP PUT ou HTTP DELETE por exemplo? Como você conseguiria que os seus serviços recebessem JSON além de XML? Como você faria para gerar JSON e outros formatos além de XML? Como você conseguiria mapear os resultados das suas operações no servidor em diferentes status HTTP na resposta?

    Importante lembrar que WS-* é independente de transporte, embora use HTTP quase sempre. Sendo assim, os recursos do HTTP não são bem explorados com WS-*. Já REST é HTTP por definição, e explora muito bem os recursos do protocolo. Usar extensamente HTTP te dá mais poder. Se você pode usar HTTP, porque você precisaria de qualquer outro protocolo de transporte. WS-* tenta ser genérico demais, e por isso ficou tão complexo.

    Você pode utilizar JAX-WS para serviços REST, mas de uma forma muito limitada. Recomendo demais que você use JAX-RS (JSR-311) em vez de JAX-WS para REST.

    []s

    Bruno

  10. Felipe Gaúcho says

    * Com REST você consegue validar qualquer coisa, não tem nenhuma restrição quanto a isso. Se vier qualquer coisa inválida, retorne um HTTP 400 (Bad Request) e indique qual foi o erro.

    No SOAP nunca virá algo inválido porque os dados sao definidos num XML Schema.. Você nao perde tempo validando no servidor.

    * Não entendi bem as suas considerações quanto ao número de chamadas ao serviço, mas eu fiz testes de carga

    Num dos nosso projetos, depois de algum tempo curtindo a agilidade do rest, precisamos de transações.. entao simulamos transações usando uma mensagem para o serviço e uma segunda mensagem para confirmar a execução, e algumas outras mensagens para fechar todo o pacote de requisitos da operação.. ficou uma bagunça com baixíssimo desempenho.. acredite, os caras que inventaram a gambiarra eram REST fanáticos, os mesmos que convenceram a gente a usar REST desde o início.. :)

  11. Alexandre Lages says

    Bruno, na minha opinião os serviços Rest devem possuir algum tipo de descritor. Tanto o Atom e o WSDL possuem a vantagem em relação ao WADL por serem padronizados, embora padrões muitas vezes não pegam. A documentação do serviço em formato Wiki também é bom (e necessário).

    Eu penso que no futuro nós teremos ferramentas que auxiliarão a composição de serviços, utilizando algo do tipo como BPEL, só que utilizando os descritores de Serviços Rest armazenados em algum tipo de Registro, como o Mule Galaxy ou WSO2 Registry. Desta forma, os descritores podem passar a ser fundamentais.

    []s

  12. blpsilva says

    @Felipe

    Sobre a validação, de fato com WS-* você pode validar diretamente pelo Schema XML. Com REST você também pode fazer isso, mas terá que ser explicitamente.

    Sobre a questão transacional, não posso falar tão bem sobre o seu exemplo sem conhecer os detalhes. Mas basicamente continuo com a minha opinião mencionada no comentário anterior. Se você precisar de transações “de longa duração”, que transcedam o escopo transacional de um único servidor (algo na linha do WS-Transaction Business Activity), então use WS-*. Eu não sou xiita, minha opinião é de resolver o problema da melhor forma. Se WS-* é mais indicado para o problema, go ahead and use it.

    Agora, minha opinião: os casos em que você de fato precisa dos recursos altamente sofisticados do WS-* são uma pequena minoria. E se por acaso os fanáticos por REST que você mencionou não tinham conhecimento suficiente para modelar bem uma solução complexa com REST, não condene a abordagem por causa disso.

    Aplicações mal implementadas existem com qualquer coisa que você use. E se você continua achando que WS-* é melhor para você, siga utilizando-o. Felizmente os middlewares WS-* estão caminhando para mais simplicidade e aumentando a produtividade. Se você se sente mais confortável com WS-* e implementa soluções melhores com essa abordagem, seja pragmático, e a mantenha como sua preferência mesmo.

    Minhas preferências são bem diferentes das suas, mas respeito a sua opinião. O mais importante é entregarmos softwares de qualidade, com qualquer escolha tecnológica que seja feita.

  13. blpsilva says

    @Alexandre

    Também estou aguardando a chegada de produtos mais interessantes para REST. Tenho acompanhado os produtos da Mulesource e da WSO2, mas infelizmente não estou tendo tempo para avaliá-los adequadamente.

    Como eu falei, acho muito interessante um descritor sim, mas ainda não estou decidido por nenhum formato específico. Nas 2 vezes que implementei um descritor, este foi customizado e sem nenhuma preocupação em automação. O objetivo foi oferecer um descritor compreensível por seres humanos mesmo.

    []s

  14. Sócrates, o desenvolvedor-filósofo. says

    “Olhem quantas coisas o ateniense precisa para viver!”

  15. Emerson Macedo says

    Tem um post muito bom de um cara que eu li uma vez para complementar isso que você disse. Ele participou muito evangelizando WS-* e depois percebeu REST como uma alternativa mais leve.
    http://www.25hoursaday.com/weblog/2007/11/15/WSIsToRESTAsTheoryIsToPractice.aspx

  16. blpsilva says

    @Emerson

    Bem interessante o post do Dare Obasanjo mesmo. É interessante acompanhar caras que já estiveram muito envolvidos com WS-* e passaram a adotar REST depois de acumular frustrações com WS-*. Aprendemos muito com a experiência desses caras também.

    Exemplos de caras nessa situação que eu acompanho são o próprio Dare Obasanjo e mais:
    James Snell – http://snellspace.com/wp/
    Dan Diephouse – http://netzooid.com/blog/

  17. Christiano Milfont says

    Bruno, vai ter mais matéria na JM sobre REST?

  18. blpsilva says

    Oi Milfont, vai ter sim. Na edição 57 (Maio) saem 2 artigos meus sobre Atom e AtomPub, que são relacionados com REST. E estou escrevendo para a edição 59 (Julho) um artigo sobre a JSR-311 e o projeto Jersey. Provavelmente virá mais coisa por aí no futuro, mas por enquanto tem esses que falei.

    []s

  19. Thiago says

    Eu sei que to meio atrasado na discussão, mas encontrei um artigo relevante, que explica como descrever serviços RESTful usando WSDL 2.0.

    http://www.ibm.com/developerworks/webservices/library/ws-restwsdl/

    Eu acho que a descrição não eh tão boa, ele poderia ter invertido a ordem (começado com os dados e indo ateh o serviço), mas dah uma idéia do que eh necessário pra descrever o serviço. Sem duvida ferramentas vão ser importantes se isso pegar.

    BTW, Bruno, voce disponibilizou os slides da sua apresentação sobre REST? Eu tinha comentado no outro blog, mas acho que voce tava em transição pro novo…

Continuing the Discussion

  1. cardinalidade.net - precisamos de um descritor de serviços rest? linked to this post on 30/01/2009

    [...] que entenda o padrão estabelecido será capaz de interpretar os … Veja o post completo clicando aqui. Post indexado de: [...]

  2. cardinalidade.net - Bruno Pereira » Blog Archive » Precisamos de um descritor de … linked to this post on 10/02/2009

    [...] que entenda o padrão estabelecido será capaz de interpretar os … Veja o post completo clicando aqui. Post indexado de: [...]



Some HTML is OK

or, reply to this post via trackback.



  • Buy Cheapest brand cialis name Now Top Online Pharmacy. Cheap Online Pharmacy.
  • Buy Cheapest generic clomid Online Best Drugstore. Cheap Online Pharmacy.
  • Buy ultram er Without Prescription Doctor. Best Internet. Best Prices.
  • Buy Cheapest pet health pharmacy Now Cheap Prescription Drugs. Low Prices.
  • Buy Cheap effexor withdrawal symptoms Online Best Online. Buy Medications Online.
  • Buy Cheap proscar generic Online Pharmacy At The Best Price! Best Drugstore.
  • Buy Cheapest generic for lexapro Online Order Cheap Meds Without Rx. Low Prices.
  • Buy Cheap diazepam no prescription needed Online Online Prices For diazepam no prescription needed! Best Drugstore.
  • Buy Cheapest us pharmacies no prescription valium Now Pharmacy Store. Special Prices For us pharmacies no prescription valium!
  • candida diflucan Online Without Prescription WorldWide Shipping. Low Prices.
  • Buy Cheap ultram use Now The Largest Internet Pharmacy. Low Prices.
  • Buy Cheapest cures for gonorrhea Online Drugs, Health And Beauty. Best Online.
  • Buy Cheapest withdrawal from codeine contin Now Pharmacy Store. Guaranteed Shipping.
  • Buy Cheap canadian drug pharmacy Online Cheap Pharmacy Online. Best Drugstore.
  • Buy Cheap zoloft dosage Now Best Drugstore. Drugs, Health And Beauty.
  • Buy Cheap prescription diet pills online Online Guaranteed Shipping. Cheap Pharmacy Online.
  • Buy Cheap ultram and pregnancy Online Best Internet. Internet Prices For ultram and pregnancy!
  • new weight loss pills Online Without Prescription Best Prices. Best Drugstore.
  • Buy Cheap sildenafil citrate viagra Now Internet Prices For sildenafil citrate viagra! Low Prices.
  • Buy Cheap diet pills prescribed by doctors Online Discount Pharmacy Online. Pharmacy Store.
  • Buy Cheapest buspar drug Now No Prescription Needed. Pharmacy Store.
  • Buying Cheap tramadol side effects. Offshore Rx, Good Prices. Top Online Pharmacy.
  • Buy Cheap xanax rx Now Discount Pharmacy Online. Pharmacy Store.
  • Buy Cheap buy benicar online no prescription Online Cheap Online Pharmacy. Pharmacy Store.
  • Buy Cheap ultram medication Now Discount Pharmacy Online. Top Online Pharmacy.
  • Buy using clomid Online Without Prescription. Low Prices. Best Internet.
  • Buy Cheap alprazolam 2mg Now Guaranteed Shipping. No Prescription Needed.
  • Buy Cheap viagra canada Now Online Medical Shop. Cheap Online Pharmacy.
  • Buy wal-mart pharmacy Without Prescription Doctor. Best Online. Best Prices.
  • Buy Cheapest online viagra prescriptions Now Pharmacy Store. Cheap Pharmacy Online.
  • Buy Cheap prescription ambien Online No Prescription Needed. Free Viagra Pills!
  • Buy Cheap lasix on line without a prescription Now Guaranteed Shipping. Cheap Prescription Drugs.
  • Buy Cheapest cialis tadafil order online Now Best Online. Discount Pharmacy Online.
  • Buy Cheapest diet pills that work Now Best Online. Top Online Pharmacy Supplier.
  • Buy Cheap cialis canadian generic Now Discount Pharmacy Online. Best Drugstore.
  • Buy Cheapest atenolol drug Online Best Internet. Top Online Pharmacy.
  • Buy Cheapest propecia online Online Guaranteed Shipping. Free Viagra Pills!
  • Buy Cheapest online pharmacy pain pills in florida Now Best Online. Cheap Prescription Drugs.
  • Buy Cheapest effexor dosage Online Top Online Pharmacy. WorldWide Shipping.
  • Buy Cheap weight loss no prescription Now Online Prices For weight loss no prescription! WorldWide Shipping.
  • Buy Cheap price fluconazole Now Online Medical Shop. 24/Online Pharmacy.
  • Buy Cheap addiction to ambien Online Best Drugstore. Top Online Pharmacy.
  • Buy Cheapest buy generic levitra Online Guaranteed Shipping. WorldWide Shipping.
  • sleep disorder treatments Online Without Prescription Low Prices. Best Drugstore.
  • Buy Cheapest cialis for men and wman Now Internet Prices For cialis for men and wman! Best Drugstore.
  • Buy Cheap viagra next day Online Best Online. Drugs, Health And Beauty.
  • Buy Cheap very cheap tramadol Now Cheap Pharmacy Online. Guaranteed Shipping.
  • Buy Cheapest norvasc online Now Best Online. Online Prices For norvasc online!
  • Buying Cheap cialis for overseas. Offshore Rx, Good Prices. Online Medical Shop.
  • Buy Cheap low cost brand viagra fast Now Guaranteed Shipping. Cheap Online Pharmacy.
  • Buy Cheapest discount lipitor Online Pharmacy Store. Buy Medications Online.
  • Buy Cheap low cost viagra online Now Internet Prices For low cost viagra online! Free Viagra Pills!
  • Buy Cheap generic for cialis Now Best Drugstore. No Prescription Needed.
  • Buy Cheap where to buy valium Now Buy Medications Online. Free Viagra Pills!
  • Buy Cheapest prescription pain relief medication Now Discount Pharmacy Online. Low Prices.
  • Buy Cheap fda approved diet drugs Now Best Online. No Prescription Online Pharmacy.
  • Buy Cheap online lorazepam Online Discount Pharmacy Online. Best Drugstore.
  • Buy Cheapest tramadol medicine online Now Cheap Pharmacy Online. Best Drugstore.
  • Buy Cheap legal cialis Online Buy Medications Online. Pharmacy Store.
  • diazepam no prescription 10mg Online Without Prescription Low Prices. Online Medical Shop.
  • Buy 100mg viagra Without Prescription Doctor. Low Prices. Best Internet.
  • Buy Cheap xanax online cheap Now Free Viagra Pills! Buy Medications Online.
  • Buy Cheap xanax online mexico Online Low Prices. Pharmacy At The Best Price!
  • Buy Cheap drugstores france Online Pharmacy At The Best Price! Best Prices.
  • Buy Cheap weight loss prescription drugs Now Discount Pharmacy Online. Free Viagra Pills!
  • Buy Cheap phentermine on line consultation Now Best Internet. Cheap Prescription Drugs.
  • Buy Cheapest purchase xanax without prescription Online Best Online. Pharmacy At The Best Price!
  • Buy Cheap viagra effect on women Online Best Prices. Cheap Prescription Drugs.
  • Buy Cheapest acetaminophen with codeine Online Online Medical Shop. Best Online.
  • Buy Cheapest supplement vitamins Online Discount Online Pharmacy. Low Prices.
  • Buy Cheapest information on weight loss supplement Now No Prescription Needed. Pharmacy Store.
  • Buy Cheapest pain pills online withouth prescription Online Best Drugstore. Guaranteed Shipping.
  • Buy Cheap intensify effects of levitra Online Low Prices. Discount Pharmacy Online.
  • Buy Cheapest weight loss pills australia Online Special Prices For weight loss pills australia! Low Prices.
  • Buy Cheap genuine viagra Online Best Internet. Drugs, Health And Beauty.
  • Buy Cheap cheapest prescription meds online Now Top Online Pharmacy. Drugs, Health And Beauty.
  • Buy Cheapest tyonal codeine Online Top Online Pharmacy. Best Online.
  • Buy Cheap detox parasites Online Best Internet. Discount Online Pharmacy.
  • Buy Cheapest tramadol information Now 24/Online Pharmacy. Best Drugstore.
  • Buying Cheap buy klonopin without prescription. Offshore Pharmacy, Best Prices. Best Internet.
  • Buy Cheap getting off pain pills Now Internet Prices For getting off pain pills! Best Prices.
  • Buy Cheapest fungus fluconazole Now Pharmacy Store. Buy Medications Online.
  • Buy Cheapest phentermine testimonies Now Special Prices For phentermine testimonies! Low Prices.
  • Find The Latest News And Information About what is lorazepam used for Pills Low Prices.
  • Buy muscle spasms drug Online Without Prescription. Best Internet. Best Prices.
  • rating on weight loss programs Online Without Prescription WorldWide Shipping. Best Online.
  • Buying Cheap viagra cod. Mexican Rx, Best Prices. 24/Online Pharmacy.
  • Buy Cheapest fda approved hair loss products Online 24/Online Pharmacy. Best Internet.
  • Buy Cheap viagra vs viagra professional Now Best Internet. Top Online Pharmacy Supplier.
  • Buy xanax prescribed for Without Prescription Doctor. Best Drugstore. Low Prices.
  • prescription only diet pills Online Without Prescription Pharmacy Store. Best Internet.
  • Buy Cheap nexium take Now Safe And Secure Payment System. Low Prices.
  • Buy Cheap low price cost prescription drugs Online Safe And Secure Payment System. Low Prices.
  • Buy Cheap buy valium without prescription Now Buy Medications Online. 24/Online Pharmacy.
  • Buy Cheapest generic viagra mexico Online Cheap Pharmacy Online. Best Drugstore.
  • Buy Cheap color of phentermine 37.5 caps Now Free Viagra Pills! No Prescription Needed.
  • Buy Cheapest diet pills that really work Now Buy Medications Online. Pharmacy Store.
  • Buy Cheap order cialis online Online WorldWide Shipping. Cheap Pharmacy Online.
  • Buy Cheap levitra experiences Now No Prescription Needed. Best Drugstore.
  • Buy Cheapest buy pain killers with no prescription Online Best Prices. 24/Online Pharmacy.