Se existem práticas recomendadas documentadas, ainda não as encontrei. No entanto, aqui estão algumas diretrizes que eu uso ao determinar onde colocar parâmetros em um URL:
Parâmetros opcionais tendem a ser mais fáceis de inserir na string de consulta.
Se você deseja retornar um erro 404 quando o valor do parâmetro não corresponde a um recurso existente, eu tenderia para um parâmetro de segmento de caminho. por exemplo, /customer/232
onde 232 não é um ID de cliente válido.
Se, no entanto, você quiser retornar uma lista vazia, quando o parâmetro não for encontrado, sugiro o uso de parâmetros de string de consulta. por exemplo/contacts?name=dave
Se um parâmetro afetar uma subárvore inteira do seu espaço de URI, use um segmento de caminho. por exemplo, um parâmetro de linguagem /en/document/foo.txt
versus/document/foo.txt?language=en
Prefiro identificadores únicos a estar em um segmento de caminho em vez de um parâmetro de consulta.
As regras oficiais para URIs são encontradas nesta especificação RFC aqui . Também há outra especificação RFC muito útil aqui que define regras para parametrizar URIs.
Resposta tardia, mas adicionarei algumas informações adicionais ao que foi compartilhado, a saber, que existem vários tipos de "parâmetros" para uma solicitação, e você deve levar isso em consideração.
Agora, vamos olhar para os diferentes lugares onde esses parâmetros podem ir.
Geralmente, você deseja que o Estado seja definido em cabeçalhos ou cookies, dependendo do tipo de informação do estado. Acho que todos podemos concordar com isso. Use cabeçalhos http personalizados (X-My-Header), se necessário.
Da mesma forma, o Conteúdo possui apenas um lugar para pertencer, que está no corpo da solicitação, como cadeias de consulta ou como conteúdo http multipart e / ou JSON. Isso é consistente com o que você recebe do servidor quando ele envia conteúdo. Portanto, você não deve ser rude e fazê-lo de maneira diferente.
Localizadores como "id = 5" ou "action = refresh" ou "page = 2" faria sentido ter um caminho de URL, como
mysite.com/article/5/page=2
onde você sabe em parte o que cada parte deve significar (o básico, como artigo e 5 obviamente significa obter os dados do tipo article com o id 5) e parâmetros adicionais são especificados como parte do URI. Eles podem estar na forma depage=2
, oupage/2
se você souber que após um certo ponto no URI, as "pastas" são valores-chave emparelhados.Os filtros sempre entram na cadeia de consulta, porque, embora façam parte da localização dos dados corretos, eles estão lá apenas para retornar um subconjunto ou modificação do que os Localizadores retornam sozinhos. A pesquisa em
mysite.com/article/?query=Obama
(subconjunto) é um filtro e também/article/5?order=backwards
(modificação). Pense no que faz, não apenas no que é chamado!Se "view" determina o formato de saída, é um filtro (
mysite.com/article/5?view=pdf
) porque retorna uma modificação do recurso encontrado, em vez de localizar o recurso desejado. Se, em vez disso, decidir qual parte específica do artigo veremos (mysite.com/article/5/view=summary
), será um localizador.Lembre-se, restringir um conjunto de recursos é filtrar. Localizar algo específico dentro de um recurso é localizar ... duh. A filtragem de subconjunto pode retornar qualquer número de resultados (até 0). A localização sempre encontrará essa instância específica de algo (se existir). A filtragem de modificação retornará os mesmos dados que o localizador, exceto modificados (se tal modificação for permitida).
Espero que isso ajude a dar às pessoas alguns momentos eureka, caso estejam perdidos sobre onde colocar as coisas!
fonte
id
um filtro então? Ele retorna um subconjunto do recurso(page-1)*perpage
e mostrarperpage
itens". Usá-lo como filtro está correto, mas por razões diferentes. Chamar isso de "página" está tecnicamente errado. Mais semanticamente correto seria chamá-lo de "from" ou "startAt"perpage
para 50 em vez de 20.Depende de um design. Não há regras para URIs no REST sobre HTTP (o principal é que elas sejam únicas). Muitas vezes, trata-se de questão de gosto e intuição ...
Eu adotei a seguinte abordagem:
fonte
Na IMO, os parâmetros devem ser melhores como argumentos de consulta. O URL é usado para identificar o recurso, enquanto os parâmetros de consulta adicionados para especificar qual parte do recurso você deseja, qualquer estado que o recurso deve ter etc.
fonte
http://labs.apache.org/webarch/uri/rfc/rfc3986.html#query
De acordo com a implementação REST,
1) As variáveis de caminho são usadas para a ação direta nos recursos, como um contato ou uma música ex.
GET etc / api / resource / {songid} ou
GET etc / api / resource / {contactid} retornará os respectivos dados.
2) Permissões / argumentos de consulta são usados para recursos diretos, como metadados de uma música ex .., GET / api / resource / {songid}? Metadata = genres, ele retornará os dados dos gêneros para essa música em particular.
fonte
"Empacote" e POSTE seus dados no "contexto" fornecido pelo localizador de recursos do universo, o que significa o número 1 em prol do localizador.
Observe as limitações com o item 2. Prefiro POSTs a # 1.
nota: limitações são discutidas para
Postar em Existe um tamanho máximo para o conteúdo do parâmetro POST?
Entrar Existe um limite para a duração de uma solicitação GET? e tamanho máximo dos parâmetros de URL em _GET
ps esses limites são baseados nos recursos do cliente (navegador) e servidor (configuração).
fonte
De acordo com o padrão URI o caminho é para parâmetros hierárquicos e a consulta é para parâmetros não hierárquicos. Claro. pode ser muito subjetivo o que é hierárquico para você.
Nas situações em que vários URIs são atribuídos ao mesmo recurso, gosto de colocar os parâmetros - necessários para a identificação - no caminho e os parâmetros - necessários para construir a representação - na consulta. (Para mim, dessa maneira, é mais fácil rotear.)
Por exemplo:
/users/123
e/users/123?fields="name, age"
/users
e/users?name="John"&age=30
Para reduzir o mapa, eu gosto de usar as seguintes abordagens:
/users?name="John"&age=30
/users/name:John/age:30
Portanto, depende de você (e do seu roteador do lado do servidor) como você constrói seus URIs.
Nota: Apenas para mencionar esses parâmetros são parâmetros de consulta. Então, o que você está realmente fazendo é definir uma linguagem de consulta simples. Por consultas complexas (que contêm operadores como e, ou, maior que etc.), sugiro que você use uma linguagem de consulta já existente. Os recursos dos modelos de URI são muito limitados ...
fonte
Como programador frequentemente no cliente, prefiro o argumento de consulta. Além disso, para mim, ele separa o caminho da URL dos parâmetros, aumenta a clareza e oferece mais extensibilidade. Também me permite ter uma lógica separada entre a criação de URL / URI e o construtor de parâmetros.
Gosto do que Manuel Aldana disse sobre a outra opção, se houver algum tipo de árvore envolvida. Eu posso ver peças específicas do usuário sendo cortadas dessa maneira.
fonte
Não há regras rígidas e rápidas, mas a regra prática, do ponto de vista puramente conceitual que eu gosto de usar, pode ser resumida da seguinte forma: um caminho URI (por definição) representa um recurso e os parâmetros de consulta são essencialmente modificadores nesse recurso . Até o momento que provavelmente não ajuda ... Com uma API REST você tem os principais métodos de agir sobre um único recurso usando
GET
,PUT
eDELETE
. Portanto, se algo deve ser representado no caminho ou como um parâmetro, pode ser reduzido se esses métodos fazem sentido para a representação em questão. Você fariaPUT
algo razoavelmente nesse caminho e seria semanticamente correto fazê-lo? Você poderia, é claro,PUT
algo em qualquer lugar e dobrar o back-end para lidar com isso, mas você devePUT
o que equivale a uma representação do recurso real e não a uma versão dele desnecessariamente contextualizada. Para coleções, o mesmo pode ser feitoPOST
. Se você deseja adicionar a uma coleção específica, qual seria um URL que faz sentidoPOST
?Isso ainda deixa algumas áreas cinzentas, pois alguns caminhos podem apontar para a quantidade de filhos dos recursos dos pais, o que é um tanto discricionário e depende do uso deles. A única linha difícil que isso desenha é que qualquer tipo de representação transitiva deve ser feita usando um parâmetro de consulta, pois não teria um recurso subjacente.
Em resposta ao exemplo do mundo real fornecido na pergunta original (API do Twitter), os parâmetros representam uma consulta transitiva que filtra o estado dos recursos (em vez de uma hierarquia). Nesse exemplo em particular, seria totalmente irracional adicionar à coleção representada por essas restrições e, além disso, essa consulta não seria capaz de ser representada como um caminho que faria algum sentido nos termos de um gráfico de objetos.
A adoção desse tipo de perspectiva orientada a recursos pode facilmente mapear diretamente para o gráfico de objeto do seu modelo de domínio e direcionar a lógica da sua API ao ponto em que tudo funciona de maneira muito limpa e de uma maneira bastante auto-documentável, uma vez que se encaixa na clareza. O conceito também pode ser esclarecido afastando-se dos sistemas que usam o roteamento de URL tradicional mapeado para um modelo de dados normalmente inadequado (ou seja, um RDBMS). O Apache Sling certamente seria um bom lugar para começar. O conceito de envio de objetos em um sistema como o Zope também fornece um analógico mais claro.
fonte
Aqui está a minha opinião.
Os parâmetros de consulta são usados como metadados para uma solicitação. Eles atuam como filtro ou modificador para uma chamada de recurso existente.
Exemplo:
/calendar/2014-08-08/events
deve fornecer eventos do calendário para esse dia.
Se você deseja eventos para uma categoria específica
/calendar/2014-08-08/events?category=appointments
ou se você precisar de eventos com mais de 30 minutos
/calendar/2014-08-08/events?duration=30
Um teste decisivo seria verificar se a solicitação ainda pode ser atendida sem parâmetros de consulta.
fonte
Eu geralmente tendem a # 2, como um argumento de consulta (ou seja, / api / resource? Parameter = value).
Uma terceira opção é realmente postar o parâmetro = valor no corpo.
Isso ocorre porque funciona melhor para recursos com vários parâmetros e é mais extensível para uso futuro.
Não importa qual você escolher, certifique-se de escolher apenas um, não misture e combine. Isso leva a uma API confusa.
fonte
Uma "dimensão" deste tópico foi deixada de fora, mas é muito importante: há momentos em que as "melhores práticas" precisam entrar em acordo com a plataforma que estamos implementando ou aprimorando com os recursos REST.
Exemplo prático:
Atualmente, muitos aplicativos da web implementam a arquitetura MVC (Model, View, Controller). Eles assumem que um determinado caminho padrão é fornecido, ainda mais quando esses aplicativos da Web vêm com a opção "Ativar URLs de SEO".
Apenas para mencionar um aplicativo da Web bastante famoso: uma loja de comércio eletrônico OpenCart. Quando o administrador ativa os "URLs de SEO", espera que esses URLs cheguem em um formato MVC bastante padrão, como:
Onde
special-offers
é o controlador MVC que deve processar o URL (mostrando a página de ofertas especiais)list-all
é o nome da ação ou função do controlador a ser chamado. (*)limite = 25 é uma opção, informando que 25 itens serão mostrados por página.
(*)
list-all
é um nome de função fictício que usei para maior clareza. Na realidade, o OpenCart e a maioria das estruturas MVC têm uma função implícita (e geralmente omitida na URL)index
padrão que é chamada quando o usuário deseja que uma ação padrão seja executada. Portanto, o URL do mundo real seria:Com um aplicativo agora bastante padrão ou uma estrutura de estrutura semelhante à acima, você geralmente obtém um servidor da Web otimizado para isso, que reescreve os URLs para ele (o verdadeiro "URL sem SEO" seria:)
http://www.domain.tld/index.php?route=special-offers/list-all&limit=25
.Portanto, como desenvolvedor, você deve lidar com a infraestrutura existente e adaptar suas "melhores práticas", a menos que seja o administrador do sistema, saiba exatamente como ajustar uma configuração de reescrita do Apache / NGinx (a última pode ser desagradável!) E assim em.
Portanto, sua API REST geralmente seria muito melhor seguindo os padrões do aplicativo da Web de referência, tanto para consistência com ele quanto para facilidade / velocidade (e, portanto, economia de orçamento).
Para voltar ao exemplo prático acima, uma API REST consistente seria algo com URLs como:
ou (URLs não SEO)
com uma mistura de argumentos "caminhos formados" e argumentos "formados por consulta".
fonte
Vejo muitas APIs REST que não lidam bem com parâmetros. Um exemplo que surge com frequência é quando o URI inclui informações de identificação pessoal.
http://software.danielwatrous.com/design-principles-for-rest-apis/
Penso que uma pergunta corolária é quando um parâmetro não deve ser um parâmetro, mas deve ser movido para o HEADER ou BODY da solicitação.
fonte
É uma pergunta muito interessante.
Você pode usar os dois, não há nenhuma regra estrita sobre esse assunto, mas o uso de variáveis de caminho URI tem algumas vantagens:
Mas se você usar variáveis de caminho, todos esses serviços poderão armazenar em cache suas solicitações GET.
Dá ao usuário mais informações sobre a estrutura dos dados.
Mas se seus dados não tiverem nenhuma relação hierárquica, você ainda poderá usar as variáveis Path, usando vírgula ou ponto e vírgula:
/ Cidade / longitude, latitude
Como regra, use vírgula quando a ordem dos parâmetros for importante, use ponto-e-vírgula quando a ordem não for importante:
/ IconGenerator / vermelho; azul; verde
Além desses motivos, há alguns casos em que é muito comum usar variáveis de string de consulta:
http: // www.google.com/search?q=rest
Para resumir, não há nenhum motivo forte para usar um desses métodos, mas sempre que possível, use variáveis de URI.
fonte