Quero tornar minha API RESTful muito previsível. Qual é a melhor prática para decidir quando fazer uma segmentação de dados usando o URI em vez de usar parâmetros de consulta.
Faz sentido para mim que os parâmetros do sistema que suportam paginação, classificação e agrupamento estejam após o '?' Mas e os campos como 'status' e 'region' ou outros atributos que segmentam sua coleção? Se esses também devem ser parâmetros de consulta, qual é a regra geral em saber quando usar parâmetros de caminho?
Respostas:
A melhor prática para o design da API RESTful é que os parâmetros de caminho são usados para identificar um recurso ou recursos específicos, enquanto os parâmetros de consulta são usados para classificar / filtrar esses recursos.
Aqui está um exemplo. Suponha que você esteja implementando pontos de extremidade da API RESTful para uma entidade chamada Car. Você estruturaria seus terminais assim:
GET
/cars
GET
/cars/:id
POST
/cars
PUT
/cars/:id
EXCLUIR
/cars/:id
Dessa forma, você só está usando parâmetros de caminho ao especificar qual recurso buscar, mas isso não classifica / filtra os recursos de nenhuma maneira.
Agora, suponha que você queira adicionar a capacidade de filtrar os carros por cor em suas solicitações GET. Como a cor não é um recurso (é propriedade de um recurso), você pode adicionar um parâmetro de consulta que faça isso. Você adicionaria esse parâmetro de consulta à sua solicitação GET
/cars
assim:OBTER
/cars?color=blue
Esse terminal seria implementado para que apenas carros azuis fossem devolvidos.
No que diz respeito à sintaxe, seus nomes de URL devem estar em letras minúsculas. Se você tiver um nome de entidade que geralmente possui duas palavras em inglês, use um hífen para separar as palavras, não para maiúsculas e minúsculas.
Ex.
/two-words
fonte
A maneira fundamental de pensar sobre esse assunto é a seguinte:
Um URI é um identificador de recurso que identifica exclusivamente uma instância específica de um recurso TYPE. Como tudo na vida, todo objeto (que é algum tipo de instância), possui um conjunto de atributos que são invariantes ou temporais no tempo.
No exemplo acima, um carro é um objeto muito tangível que possui atributos como marca, modelo e VIN - que nunca mudam, e cor, suspensão etc. que podem mudar ao longo do tempo. Portanto, se codificarmos o URI com atributos que podem mudar ao longo do tempo (temporal), podemos acabar com vários URIs para o mesmo objeto:
E anos depois, se a cor desse mesmo carro for alterada para preto:
Observe que a instância do carro em si (o objeto) não mudou - é apenas a cor que mudou. Ter vários URIs apontando para a mesma instância de objeto forçará você a criar vários manipuladores de URI - esse não é um design eficiente e, é claro, não é intuitivo.
Portanto, o URI deve consistir apenas em partes que nunca serão alteradas e continuarão a identificar exclusivamente esse recurso durante toda a sua vida útil. Tudo o que pode mudar deve ser reservado para parâmetros de consulta, como:
Conclusão - pense no polimorfismo.
fonte
Em uma API REST, você não deve se preocupar muito com URIs previsíveis. A própria sugestão de previsibilidade de URI alude a um mal-entendido da arquitetura RESTful. Ele pressupõe que um cliente deva construir URIs, o que realmente não deveria.
No entanto, suponho que você não esteja criando uma API REST verdadeira, mas uma API 'inspirada em REST' (como a do Google Drive). Nesses casos, a regra geral é 'caminho params = identificação de recurso' e 'consulta params = classificação de recurso'. Então, a pergunta se torna: você pode identificar exclusivamente seu recurso SEM status / região? Se sim, então talvez seja um parâmetro de consulta. Se não, então é um caminho param.
HTH.
fonte
Uma vez eu projetei uma API que recurso principal era
people
. Normalmente, os usuários solicitavam filtragempeople
, para impedir que os usuários ligassem para algo como/people?settlement=urban
sempre, implementei o/people/urban
que mais tarde me permitiu adicionar facilmente/people/rural
. Isso também permite acessar a/people
lista completa, se for de alguma utilidade posteriormente. Em resumo, meu raciocínio era adicionar um caminho para subconjuntos comunsA partir daqui :
fonte
De um modo geral, costumo usar parâmetros de caminho quando há uma 'hierarquia' óbvia no recurso, como:
Se esse recurso único tiver um status, pode-se:
No entanto, se 'região' não for realmente parte do recurso exposto, provavelmente pertencerá a um dos parâmetros de consulta - semelhante à paginação (como você mencionou).
fonte
A segmentação é mais hierárquica e "bonita", mas pode ser limitativa.
Por exemplo, se você tiver um URL com três segmentos, cada um passando parâmetros diferentes para procurar um carro por marca, modelo e cor:
Este é um URL muito bonito e mais facilmente lembrado pelo usuário final, mas agora você fica preso nessa estrutura. Digamos que você queira fazê-lo para que, na pesquisa, o usuário possa procurar TODOS os carros azuis ou TODOS os Honda Civics? Um parâmetro de consulta resolve isso porque fornece um par de valores-chave. Então você pode passar:
Agora você tem uma maneira de referenciar o valor por meio de sua chave - "color" ou "make" no seu código de consulta.
Você pode contornar isso possivelmente usando mais segmentos para criar um tipo de estrutura de valor-chave como:
Espero que faça sentido ..
fonte
URL de exemplo:
/rest/{keyword}
Este URL é um exemplo para parâmetros de caminho. Podemos obter esses dados de URL usando
@PathParam
.URL de exemplo:
/rest?keyword=java&limit=10
Este URL é um exemplo para parâmetros de consulta. Podemos obter esses dados de URL usando
@Queryparam
.fonte