Esta é uma pergunta boa e complicada. O tópico de design de URI é ao mesmo tempo a parte mais importante de uma API REST e , portanto, um compromisso potencialmente de longo prazo para os usuários dessa API .
Desde a evolução de um aplicativo e, em menor grau, sua API é um fato da vida e é ainda semelhante à evolução de um produto aparentemente complexo como uma linguagem de programação, o design do URI deve ter menos restrições naturais e deve ser preservado ao longo do tempo . Quanto maior a vida útil do aplicativo e da API, maior o comprometimento com os usuários do aplicativo e da API.
Por outro lado, outro fato da vida é que é difícil prever todos os recursos e seus aspectos que seriam consumidos por meio da API. Felizmente, não é necessário projetar toda a API que será usada até o Apocalypse . É suficiente definir corretamente todos os pontos finais de recursos e o esquema de endereçamento de cada recurso e instância de recurso.
Com o tempo, pode ser necessário adicionar novos recursos e novos atributos a cada recurso específico, mas o método que os usuários da API seguem para acessar determinados recursos não deve mudar assim que um esquema de endereçamento de recursos se tornar público e, portanto, final.
Esse método se aplica à semântica de verbos HTTP (por exemplo, a PUT sempre deve atualizar / substituir) e aos códigos de status HTTP suportados nas versões anteriores da API (eles devem continuar a funcionar para que os clientes da API que trabalharam sem intervenção humana possam continuar trabalhando) Curtiu isso).
Além disso, como a incorporação da versão da API no URI interromperia o conceito de hipermídia como o mecanismo do estado do aplicativo (declarado na dissertação de doutorado de Roy T. Fieldings) por ter um endereço de recurso / URI que mudaria ao longo do tempo, eu concluiria que a API as versões não devem ser mantidas nos URIs de recursos por um longo período de tempo, o que significa que os URIs de recursos dos quais os usuários da API podem confiar devem ter links permanentes .
Claro, é possível incorporar a versão da API no URI base, mas apenas para usos razoáveis e restritos, como depurar um cliente da API que funcione com a nova versão da API. Essas APIs com versão devem ter um tempo limitado e estar disponíveis apenas para grupos limitados de usuários da API (como durante betas fechados). Caso contrário, você se compromete onde não deveria.
Algumas reflexões sobre a manutenção de versões da API com data de validade. Todas as plataformas / linguagens de programação comumente usadas para implementar serviços da Web (Java, .NET, PHP, Perl, Rails, etc.) permitem a ligação fácil dos pontos finais dos serviços da Web a um URI base. Dessa forma, é fácil reunir e manter uma coleção de arquivos / classes / métodos separados em diferentes versões da API .
No POV dos usuários da API, também é mais fácil trabalhar e vincular-se a uma versão específica da API quando isso é óbvio, mas apenas por tempo limitado, ou seja, durante o desenvolvimento.
No ponto de vista do mantenedor da API, é mais fácil manter versões diferentes da API em paralelo, usando sistemas de controle de origem que funcionam predominantemente em arquivos como a menor unidade de versão (código fonte).
No entanto, com as versões da API claramente visíveis no URI, há uma ressalva: também é possível objetar essa abordagem, pois o histórico da API se torna visível / aparente no design do URI e, portanto, está sujeito a alterações ao longo do tempo, o que contraria as diretrizes do REST. Concordo!
A maneira de contornar essa objeção razoável é implementar a versão mais recente da API no URI base da API sem versão. Nesse caso, os desenvolvedores de clientes da API podem optar por:
desenvolva contra o mais recente (comprometendo-se a manter o aplicativo protegendo-o de eventuais alterações na API que possam interromper seu cliente de API mal projetado ).
vincular a uma versão específica da API (que se torna aparente), mas apenas por um tempo limitado
Por exemplo, se a API v3.0 é a versão mais recente da API, os dois seguintes devem ter aliases (ou seja, comportar-se de forma idêntica a todas as solicitações de API):
http: // shonzilla / api / customers / 1234
http: // shonzilla / api / v3.0 / customers / 1234
http: // shonzilla / api / v3 / customers / 1234
Além disso, os clientes da API que ainda tentam apontar para a API antiga devem ser informados a usar a versão anterior mais recente da API, se a versão da API que eles estão usando estiver obsoleta ou não for mais suportada . Portanto, acesse qualquer um dos URIs obsoletos como estes:
http: // shonzilla / api /v2.2 / customers / 1234
http: // shonzilla / api /v2.0 / customers / 1234
http: // shonzilla / api / v2 / customers / 1234
http: // shonzilla / api /v1.1 / customers / 1234
http: // shonzilla / api / v1 / customers / 1234
deve retornar qualquer um dos códigos de status HTTP 30x que indicam o redirecionamento usado em conjunto com o Location
cabeçalho HTTP que redireciona para a versão apropriada do URI do recurso que permanece como este:
http: // shonzilla / api / customers / 1234
Há pelo menos dois códigos de status HTTP de redirecionamento apropriados para cenários de versão da API:
301 Movido permanentemente, indicando que o recurso com um URI solicitado é movido permanentemente para outro URI (que deve ser um link permanente de instância de recurso que não contém informações da versão da API). Esse código de status pode ser usado para indicar uma versão obsoleta / não suportada da API, informando ao cliente da API que um URI de recurso com versão foi substituído por um link permanente de recurso .
302 encontrado indicando que o recurso solicitado está temporariamente localizado em outro local, enquanto o URI solicitado ainda pode ser suportado. Esse código de status pode ser útil quando os URIs sem versão estão temporariamente indisponíveis e que uma solicitação deve ser repetida usando o endereço de redirecionamento (por exemplo, apontando para o URI com a versão APi incorporada) e queremos dizer aos clientes para continuar usando (ou seja, o permalinks).
outros cenários podem ser encontrados no capítulo Redirection 3xx da especificação HTTP 1.1
410 Gone
, pois um redirecionamento pode indicar que o novo local é compatível quando não é. Se a API for apenas obsoleta, mas ainda existir, umWarning
cabeçalho HTTP na resposta pode ser uma opção.O URL NÃO deve conter as versões. A versão não tem nada a ver com a "idéia" do recurso que você está solicitando. Você deve tentar pensar no URL como um caminho para o conceito que deseja - não como deseja que o item seja devolvido. A versão determina a representação do objeto, não o conceito do objeto. Como outros pôsteres disseram, você deve especificar o formato (incluindo a versão) no cabeçalho da solicitação.
Se você olhar para a solicitação HTTP completa dos URLs que possuem versões, será semelhante a este:
O cabeçalho contém a linha que contém a representação que você está solicitando ("Accept: application / xml"). É para onde a versão deve ir. Todo mundo parece encobrir o fato de que você pode querer a mesma coisa em diferentes formatos e que o cliente deve poder pedir o que deseja. No exemplo acima, o cliente está solicitando QUALQUER representação XML do recurso - e não a verdadeira representação do que deseja. O servidor poderia, em teoria, retornar algo completamente não relacionado à solicitação, desde que fosse XML e precisaria ser analisado para perceber que está errado.
Uma maneira melhor é:
Além disso, digamos que os clientes pensem que o XML é muito detalhado e agora desejam o JSON. Nos outros exemplos, você precisaria ter um novo URL para o mesmo cliente, para acabar com:
(ou algo semelhante). Na verdade, todas as solicitações HTTP contêm o formato que você está procurando:
Usando esse método, você tem muito mais liberdade no design e está realmente aderindo à ideia original do REST. Você pode alterar as versões sem interromper os clientes ou alterar gradualmente os clientes à medida que as APIs são alteradas. Se você optar por parar de oferecer suporte a uma representação, poderá responder às solicitações com código de status HTTP ou códigos personalizados. O cliente também pode verificar se a resposta está no formato correto e validar o XML.
Há muitas outras vantagens e discuto algumas delas aqui no meu blog: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html
Um último exemplo para mostrar como colocar a versão na URL é ruim. Digamos que você queira alguma informação dentro do objeto e você fez a versão de vários objetos (os clientes são v3.0, os pedidos são v2.0 e o objeto shipto é v4.2). Aqui está o URL desagradável que você deve fornecer no cliente:
fonte
-x
, pois está obsoleto pelo RFC6648 .Achamos prático e útil colocar a versão no URL. Torna fácil dizer rapidamente o que você está usando. Fazemos o alias / foo a / foo / (versões mais recentes) para facilitar o uso, URLs mais curtos / limpos, etc., como sugere a resposta aceita.
Manter a compatibilidade com versões anteriores para sempre é muitas vezes proibitivo em termos de custos e / ou muito difícil. Preferimos avisar com antecedência sobre reprovação, redirecionamentos, como sugerido aqui, documentos e outros mecanismos.
fonte
Concordo que o controle de versão da representação de recursos segue melhor a abordagem REST ... mas um grande problema com os tipos MIME personalizados (ou tipos MIME que acrescentam um parâmetro de versão) é o pouco suporte para gravar nos cabeçalhos Accept e Content-Type em HTML e JavaScript.
Por exemplo, não é possível que o IMO POST com os seguintes cabeçalhos nos formulários HTML5, para criar um recurso:
Isso ocorre porque o
enctype
atributo HTML5 é uma enumeração, portanto, qualquer coisa que não seja o habitualapplication/x-www-formurlencoded
,multipart/form-data
etext/plain
é inválido.... nem tenho certeza de que ele é suportado em todos os navegadores em HTML4 (que possui um atributo de encytpe mais frouxo, mas seria um problema de implementação do navegador se o tipo MIME foi encaminhado)
Por causa disso, agora sinto que a maneira mais apropriada de versão é via URI, mas aceito que não seja a maneira 'correta'.
fonte
Coloque sua versão no URI. Uma versão de uma API nem sempre suporta os tipos de outra, portanto, o argumento de que os recursos são apenas migrados de uma versão para outra é simplesmente errado. Não é o mesmo que mudar de formato de XML para JSON. Os tipos podem não existir ou podem ter sido alterados semanticamente.
As versões fazem parte do endereço do recurso. Você está roteando de uma API para outra. Não é RESTful ocultar o endereçamento no cabeçalho.
fonte
Existem alguns lugares em que você pode fazer controle de versão em uma API REST:
Como observado, no URI. Isso pode ser tratável e até esteticamente agradável se redirecionamentos e similares forem bem utilizados.
No cabeçalho Aceita:, portanto, a versão está no tipo de arquivo. Como 'mp3' vs 'mp4'. Isso também funcionará, embora o IMO funcione um pouco menos do que ...
No próprio recurso. Muitos formatos de arquivo têm seus números de versão incorporados, normalmente no cabeçalho; isso permite que o software mais novo 'apenas funcione' entendendo todas as versões existentes do tipo de arquivo, enquanto o software mais antigo pode funcionar se uma versão não suportada (mais recente) for especificada. No contexto de uma API REST, isso significa que seus URIs nunca precisam ser alterados, apenas sua resposta à versão específica dos dados que você recebeu.
Eu posso ver razões para usar todas as três abordagens:
fonte
A versão da API REST é análoga à versão de qualquer outra API. Pequenas alterações podem ser feitas, grandes mudanças podem exigir uma API totalmente nova. O mais fácil para você é começar do zero toda vez, ou seja, colocar a versão no URL faz mais sentido. Se você deseja facilitar a vida do cliente, tente manter a compatibilidade com versões anteriores, o que pode ser feito com a descontinuação (redirecionamento permanente), recursos em várias versões etc. Isso é mais complicado e exige mais esforço. Mas é também o que o REST incentiva em "URIs legais não mudam".
No final, é como qualquer outro design de API. Pesar esforços contra a conveniência do cliente. Considere adotar versões semânticas para sua API, o que deixa claro para seus clientes como a sua nova versão é compatível com versões anteriores.
fonte