Vários conceitos relacionados ao REST entram em conflito na minha cabeça quando tento implementá-lo.
Eu tenho um sistema de API de back-end completo que contém a lógica de negócios e um aplicativo da web que fornece a interface do usuário. De vários recursos sobre o REST (particularmente, REST na Prática: Hipermídia e Arquitetura de Sistemas ), eu sei que não devo expor identificadores brutos de minhas entidades, mas devolver os hiperlinks com rel="self"
.
Considere o exemplo. A API REST possui um recurso que retorna uma pessoa:
<Person>
<Links>
<Link rel="self" href="http://my.rest.api/api/person/1234"/>
</Links>
<Pets>
<Link rel="pet" href="http://my.rest.api/api/pet/678"/>
</Pets>
</Person>
O problema surge com o aplicativo da web. Vamos supor que ele retorne uma página que contenha um hiperlink para os navegadores:
<body class="person">
<p>
<a href="http://my.web.app/pet/???????" />
</p>
</body>
O que devo colocar no href
atributo? Como mantenho o URL da entidade da API no aplicativo Web para poder obter a entidade quando um usuário abre a página de destino?
Os requisitos parecem conflitantes:
- O hiperlink
href
deve levar ao aplicativo Web, porque é o sistema que hospeda a interface do usuário - Ele
href
deve ter algum ID da entidade porque o aplicativo Web deve poder endereçar a entidade quando a página de destino é aberta - O aplicativo Web não deve analisar / construir URLs REST porque não é totalmente REST, diz o livro mencionado
URIs devem ser opacos para os consumidores. Somente o emissor do URI sabe como interpretá-lo e mapeá-lo para um recurso.
Portanto, não posso usar apenas 1234
o URL de resposta da API porque, como cliente RESTful, devo tratá-lo como se fosse algo parecido http://my.rest.api/api/AGRIDd~ryPQZ^$RjEL0j
. Por outro lado, devo fornecer uma URL que leve ao meu aplicativo Web e é suficiente para que o aplicativo, de alguma forma, restaure o URL original da API e use esse URL para acessar os recursos da API.
A maneira mais simples é provavelmente usar apenas os URLs da API dos recursos como identificadores de string. Mas URLs de páginas da web como http://my.web.app/person/http%3A%2F%2Fmy.rest.api%2Fapi%2Fperson%2F1234
são feios.
Tudo parece bastante fácil para um aplicativo de desktop ou um aplicativo javascript de página única. Como eles vivem continuamente, eles podem simplesmente manter os URLs na memória juntamente com os objetos de serviço durante a vida útil do aplicativo e usá-los quando necessário.
Com um aplicativo da web, posso imaginar várias abordagens, mas todas parecem estranhas:
- Substitua o host nos URLs da API e mantenha apenas o resultado. A grande desvantagem é que ele requer que o aplicativo da Web manipule qualquer URL que a API gere, significando um acoplamento monstruoso. Além disso, não é RESTful novamente, porque meu aplicativo Web começa a interpretar os URLs.
- Exponha os IDs brutos na API REST junto com os links, use-os para criar URLs do Web App e, em seguida, use os IDs no servidor de aplicativos Web para encontrar os recursos necessários na API. Isso é melhor, mas afetará o desempenho do servidor de aplicativos da web porque o aplicativo da web precisará passar pela navegação do serviço REST emitindo uma cadeia de solicitações de obtenção por ID de alguma forma para lidar com qualquer solicitação de um navegador. Para um recurso um pouco aninhado, isso pode ser caro.
- Armazene todos os
self
URLs retornados pela API em um mapeamento persistente (DB?) No servidor de aplicativos da web. Gere alguns IDs para eles, use-os para criar os URLs da página do aplicativo Web e obter os URLs dos recursos do serviço REST. Ou seja, mantenho ohttp://my.rest.api/pet/678
URL em algum lugar com uma nova chave, digamos3
, e giro o URL da página da web comohttp://my.web.app/pet/3
. Parece uma implementação de cache HTTP de algum tipo. Não sei por que, mas me parece estranho.
Ou isso significa que as APIs RESTful não podem servir como back-end para aplicativos da web?