O Java e a JVM permanecem como solução geral dominante para muitos desenvolvedores e aplicações. Seja CORBA, Java EE, SOA, REST ou Web Services, o Java tem sido capaz de suportar todos esses padrões. Dada a onipresença do Java e do REST, foi apenas uma questão de tempo até que uma abordagem baseada em padrões surgisse para juntar os dois: a JAX-RS, introduzida no EE 6. Há muitas implementações da especificação JAX-RS, incluindo o Jersey (a implementação de referência) e o RESTeasy, ambos amplamente utilizados.
No entanto, ao longo dos anos surgiram críticas sobre a JAX-RS, particularmente se esta encoraja ou não um design RESTful. Algumas dessas questões estão sendo cuidadas pelo comitê técnico da especificação JAX-RS 2.0, mas mesmo após o JavaOne 2012, ainda havia questões sobre o padrão. Recentemente a Zapthink entrou na discussão com um artigo que mais uma vez questiona se o Java ou mesmo a JAX-RS são apropriados para se construir aplicações RESTful.
O esforço contínuo do Java Community Process (JCP) tem aumentado a capacidade do ecossistema Java a fim de enfrentar uma grande variedade de novos problemas e situações. É possível que esse trabalho no Java continue atendendo suas necessidades por anos futuros. Mas pode ser que não. O peso da arquitetura MVC (model-view-controller) do Java EE, ou simplesmente o contexto orientado a objetos do Java, pode não suportar abordagens arquiteturais alternativas.
Existem, claro, comunidades muito ativas em torno da JVM que não são relacionadas ao Java, como JRuby, Clojure, Scala e JavaScript. Não é preciso nem mesmo tocar no Java EE para obter recursos como transações, segurança etc. Algumas dessas linguagens têm suas próprias abordagens para construção de serviços RESTful. No entanto, a Zapthink acredita que o Java em particular é muito mal servido pela JAX-RS:
Infelizmente, a JAX-RS é um exemplo clássico de algo forçado. A API agrega algumas capacidades RESTful ao Java, mas vai contra o estilo arquitetural RESTful em todos os sentidos; por exemplo, as restrições HATEOAS. A JAX-RS 1.1 não suportava hipermídia em nada, o que essencialmente significa que tivemos que simular as características HATEOAS utilizando recursos do próprio Java. Para tornar a JAX-RS completamente RESTful, seria necessário projetar aplicações que satisfizessem todas as restrições da arquitetura REST, compensando durante o desenvolvimento as características que não contam com suporte adequado. A JAX-RS 1.1 provê suporte adequado para satisfazer algumas restrições da arquitetura REST, mas ainda não suporta o HATEOAS.
A falta de suporte a hipermídia foi uma questão que o comitê técnico da JAX-RS tentou resolver na última versão da especificação, no entanto o artigo cita ainda uma deficiência: embora a JAX-RS utilize fortemente anotações Java, não existe nenhuma anotação para expressar hiperlinks. A ausência dessa anotação leva a abordagens improvisadas, quando na verdade deveria ser uma funcionalidade parte do padrão. De acordo com o artigo, há outras áreas em que até mesmo a nova versão do padrão deixa a desejar, embora seja discutível se os problemas estão na JAX-RS ou em outro padrão:
É importante padronizar a forma de definição de media types sempre que possível, e deve-se também selecionar quais media types padronizados e customizados usar. Além disso, o princípio de design de descoberta de serviços (Service discoverability) exige que os controles de hipermídias estejam no lugar certo, baseado na restrição de design HATEOAS do REST. O princípio de descoberta de serviços oferece uma maneira de fazer o protocolo auto-documentável.
Por fim, há uma restrição significativa imposta na JAX-RS que, de acordo com a Zapthink, impede que ambos JAX-RS e Java sejam apropriados para serviços RESTful. Assim como foi explicado por Arun Gupta durante a discussão sobre o rascunho da JAX-RS 2.0, há dois tipos de links dentro de hipermídia:
A vinculação de recursos é um dos princípios RESTful fundamentais. Existem vínculos estruturais (structural links) que são usados para evitar o envio completo da representação de um recurso e habilitar o carregamento tardio (lazy loading). Os clientes podem seguir esse tipo de vínculo para recuperar as partes que precisam. Um vínculo de transição (transitional link) é usado para atualizar o estado de um recurso e é tipicamente identificado pelo atributo "rel". Vínculos estruturais ficam normalmente nas entidades; vínculos de transição podem estar em cabeçalhos de outros vínculos ou em entidades.
Embora a JAX-RS 2.0 suporte somente vínculos de transição, a Zapthink acredita que nenhum deles são estritamente necessários para serviços RESTful:
Se simplesmente convertermos um objeto Java para hipermídia, obteremos vínculos representando as diversas chamadas de métodos nas instâncias dos objetos associados, o que torna as representações complexas e excessivamente grandes. Em vez disso, a JAX-RS encoraja o uso de vínculos de transição que permitem ao cliente detalhar os dados subjacentes. Mas se não fôssemos algemados pela estrutura de objetos Java, nunca nos preocuparíamos com vínculos de transição e estruturais. Em vez disso, projetaríamos nossas aplicações hipermídias para suportar a descoberta de serviços. Em outras palavras, um padrão essencial do Java torna-se um antipattern hipermídia.
Apesar do fato de que a JAX-RS 2.0 ainda é ineficiente para construção de serviços RESTful, o autor conclui que é necessário se lembrar de que REST não é uma implementação, mas uma abordagem arquitetural:
As pessoas se confundem constantemente quando desenvolvem com a JAX-RS e pensam em REST. JAX-RS não é design REST; na verdade, a JAX-RS deve suportar um bom design RESTful. Além disso, o uso da API JAX-RS não leva à criação de serviços completamente RESTful, a menos que se tenha completado o design RESTful de forma apropriada. O design deve garantir que todas as restrições de uma arquitetura RESTful foram satisfeitas.
Isso já foi dito em relação ao REST e SOA. Mas será que existem problemas fundamentais com a JAX-RS ou com o Java para construção de serviços RESTful como alega o artigo da Zapthink? Um dos comentaristas do artigo pergunta:
Sinceramente, qual linguagem você sugere como substituto ao Java, para construir sistemas com uma abordagem RESTful? Entendo que o Java está ficando "velho", mas acredito muito nos benefícios da tipagem forte e outras práticas de programação que o Java incorpora. Você considera Scala (a próxima evolução lógica do Java) mais adequada? Se não for Scala, então qual sugere?
O autor responde:
Não favoreço uma linguagem sobre outra, porque acredito que qualquer linguagem de programação pode ser vantajosa, desde que forneça suporte adequado para implementar arquiteturas em conformidade com o REST. É claro que a arquitetura sofrerá influências da linguagem escolhida, mas o mais importante é focar em projetar as aplicações para aderir às restrições de design do REST.
Ainda fica a questão: o Java está sendo forçado para o design RESTful, e mais que outras linguagens?