Quando usar @QueryParam vs @PathParam


276

Não estou fazendo a pergunta que já foi feita aqui: Qual é a diferença entre @PathParam e @QueryParam

Esta é uma questão de "melhores práticas" ou convenções.

Quando você usaria @PathParamvs @QueryParam.

O que posso pensar é que a decisão pode estar usando os dois para diferenciar o padrão de informação. Deixe-me ilustrar abaixo do meu LTPO - menos que perfeita observação.

O uso do PathParam pode ser reservado para a categoria de informações, que se encaixaria perfeitamente em um ramo de uma árvore de informações. PathParam pode ser usado para detalhar a hierarquia de classes da entidade.

Visto que QueryParam pode ser reservado para especificar atributos para localizar a instância de uma classe.

Por exemplo,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Eu não acho que exista uma convenção padrão de fazê-lo. Existe? No entanto, gostaria de saber como as pessoas usam o PathParam vs o QueryParam para diferenciar suas informações, como exemplifiquei acima. Eu também adoraria ouvir a razão por trás da prática.


Respostas:


245

O REST pode não ser um padrão, mas ler a documentação geral do REST e as postagens do blog deve fornecer algumas diretrizes para uma boa maneira de estruturar os URLs da API. A maioria das APIs de descanso tendem a ter apenas nomes e IDs de recurso no caminho. Tal como:

/departments/{dept}/employees/{id}

Algumas APIs REST usam seqüências de caracteres de consulta para filtragem, paginação e classificação, mas Como o REST não é um padrão rigoroso, recomendo verificar algumas APIs REST disponíveis no mercado, como github e stackoverflow, e ver o que poderia funcionar bem no seu caso de uso.

Eu recomendo colocar quaisquer parâmetros necessários no caminho, e quaisquer parâmetros opcionais certamente devem ser parâmetros de string de consulta. Colocar parâmetros opcionais no caminho acabará ficando muito confuso ao tentar escrever manipuladores de URL que correspondam a diferentes combinações.


73
" Eu recomendo colocar quaisquer parâmetros necessários no caminho, e quaisquer parâmetros opcionais deve certamente ser de consulta parâmetros de cadeia. " - polegares para cima +1 sim def
smeeb

1
se essa convenção também for usada para a solicitação Put, digamos que queremos atualizar uma versão específica da entidade db, se o URI PUT /depatments/{dept}/employees/{id}/{version}e a versão forem opcionais ou se a PUT /depatments/{dept}/employees/{id}?version=12versão for opcional
felicidades em

Nesse caso, eu recomendaria: - PUT /depatments/{dept}/employees/{id}/versions/{version}criar um funcionário com uma versão escolhida - POST /depatments/{dept}/employees/{id}/versionscriar um funcionário com uma versão determinada pelo back
Guillaume Vauvert

90

Isto é o que eu faço.

Se houver um cenário para recuperar um registro com base no ID, por exemplo, você precisará obter os detalhes do funcionário cujo ID é 15, poderá ter recursos com @PathParam.

GET /employee/{id}

Se houver um cenário em que você precise obter os detalhes de todos os funcionários, mas apenas 10 por vez, use os parâmetros de consulta

GET /employee?start=1&size=10

Isso indica que a identificação inicial do funcionário 1 obtém dez registros.

Para resumir, use @PathParam para recuperação com base no ID. Usuário @QueryParam para filtro ou se você tiver alguma lista fixa de opções que o usuário possa passar.


'@PathParam' e '@QueryParam' fornecem a mesma funcionalidade? '@QueryParam' é apenas outra maneira de escrever a mesma coisa?
Rishabh Agarwal 23/01

1
@RishabhAgarwal mesmo que ambos forneçam a mesma funcionalidade, a prática do código limpo é que, é recomendável colocar um parâmetro necessário como variável de caminho e qualquer parâmetro opcional como parâmetro de consulta.
Akhil Ghatiki

@RishabhAgarwal Para obter mais informações, consulte o artigo Práticas recomendadas da API de repouso
Arun B Chandrasekaran

43

Eu acho que se o parâmetro identifica uma entidade específica, você deve usar uma variável de caminho. Por exemplo, para obter todas as postagens no meu blog, solicito

GET: myserver.com/myblog/posts

para obter a postagem com id = 123, eu solicitaria

GET: myserver.com/myblog/posts/123

mas para filtrar minha lista de postagens e obter todas as postagens desde 1º de janeiro de 2013, solicitei

GET: myserver.com/myblog/posts?since=2013-01-01

No primeiro exemplo, "postagens" identifica uma entidade específica (toda a coleção de postagens do blog). No segundo exemplo, "123" também representa uma entidade específica (uma única postagem no blog). Mas no último exemplo, o parâmetro "since = 2013-01-01" é uma solicitação para filtrar a coleção de postagens, não uma entidade específica. Paginação e ordenação seriam outro bom exemplo, ou seja,

GET: myserver.com/myblog/posts?page=2&order=backward

Espero que ajude. :-)


8

Eu pessoalmente usei a abordagem de "se faz sentido para o usuário marcar um URL que inclua esses parâmetros, use o PathParam".

Por exemplo, se a URL para um perfil de usuário incluir algum parâmetro de identificação de perfil, já que isso pode ser marcado pelo usuário e / ou enviado por e-mail, eu incluiria essa identificação de perfil como parâmetro de caminho. Além disso, outro fator a considerar é que a página indicada pelo URL que inclui o caminho param não muda - o usuário configurará seu perfil, salvará e, provavelmente, mudará muito a partir daí; isso significa que webcrawlers / mecanismos de pesquisa / navegadores / etc podem armazenar em cache esta página com base no caminho.

Se um parâmetro passado no URL provavelmente alterar o layout / conteúdo da página, eu o usaria como um parâmetro de consulta. Por exemplo, se o URL do perfil oferecer suporte a um parâmetro que especifique se o email do usuário deve ser exibido ou não, consideraria esse um parâmetro de consulta. (Eu sei, sem dúvida, você poderia dizer que o &noemail=1parâmetro ou qualquer que seja ele pode ser usado como um parâmetro de caminho e gera 2 páginas separadas - uma com o email, outra sem ela - mas logicamente não é esse o caso: ainda é a mesma página com ou sem determinados atributos mostrados.

Espero que isso ajude - eu aprecio a explicação pode ser um pouco confusa :)


Eu acho que isso responde confunde recursos com rotas. A pergunta é sobre os recursos de uma API REST, normalmente retornando JSON ou XML, não sobre as rotas de um aplicativo da Web, que ajudam a navegar no aplicativo.
Hampus


5

É 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 do URI tem algumas vantagens:

  • Cache : a maioria dos serviços de cache da Web na Internet não solicita GET em cache quando contém parâmetros de consulta. Eles fazem isso porque existem muitos sistemas RPC usando solicitações GET para alterar dados no servidor (falha !! Get deve ser um método seguro)

Mas se você usar variáveis ​​de caminho, todos esses serviços poderão armazenar em cache suas solicitações GET.

  • Hierarquia : As variáveis ​​de caminho podem representar a hierarquia: / Cidade / Rua / Local

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:

  • Quando você precisa que o navegador coloque automaticamente variáveis ​​de formulário HTML no URI
  • Quando você está lidando com algoritmo. Por exemplo, o mecanismo do Google usa cadeias de consulta:

http: // www.google.com/search?q=rest

Para resumir, não há motivo forte para usar um desses métodos, mas sempre que possível, use variáveis ​​URI.


2

Como observado anteriormente, o REST não é um padrão. No entanto, se você deseja implementar uma convenção de URI baseada em padrões, considere a convenção de URI oData . A versão 4 foi aprovada como padrão OASIS e existem bibliotecas para oData para vários idiomas, incluindo Java via Apache Olingo . Não deixe que o fato de ser uma criação da Microsoft o desencoraje, já que também ganhou suporte de outros players do setor , incluindo Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook e SAP

Mais usuários estão listados aqui


2

Origem: Wikipedia: Uniform Resource Locator

Um caminho , que contém dados, geralmente organizados em forma hierárquica , que aparece como uma sequência de segmentos separados por barras.

Uma consulta opcional , separada da parte anterior por um ponto de interrogação (?), Contendo uma sequência de consulta de dados não hierárquicos .

- De acordo com o design conceitual da URL, podemos implementar um PathParam para componentes hierárquicos de dados / diretivas / localizadores ou implementar um QueryParam quando os dados não são hierárquicos. Isso faz sentido porque os caminhos são naturalmente ordenados, enquanto as consultas contêm variáveis ​​que podem ser ordenadas arbitrariamente (pares de variáveis ​​/ valores não ordenados).

Um comentarista anterior escreveu:

Eu acho que se o parâmetro identifica uma entidade específica, você deve usar uma variável de caminho.

Outro escreveu,

Use @PathParam para recuperação com base no ID. Usuário @QueryParam para filtro ou se você tiver alguma lista fixa de opções que o usuário possa passar.

Outro,

Eu recomendo colocar quaisquer parâmetros necessários no caminho, e quaisquer parâmetros opcionais certamente devem ser parâmetros de string de consulta.

- No entanto, pode-se implementar um sistema flexível e não hierárquico para identificar entidades específicas! Pode-se ter vários índices exclusivos em uma tabela SQL e permitir que as entidades sejam identificadas usando qualquer combinação de campos que compõem um índice exclusivo! Diferentes combinações (talvez também ordenadas de forma diferente) podem ser usadas para links de várias entidades relacionadas (referenciadores). Nesse caso, podemos estar lidando com dados não hierárquicos, usados ​​para identificar entidades individuais - ou em outros casos, apenas especificar determinadas variáveis ​​/ campos - certos componentes de índices exclusivos - e recuperar uma lista / conjunto de registros. Nesses casos, pode ser mais fácil, mais lógico e razoável implementar os URLs como QueryParams!

Uma string hexadecimal longa poderia diluir / diminuir o valor das palavras-chave no restante do caminho? Pode valer a pena considerar as possíveis implicações de SEO da colocação de variáveis ​​/ valores no caminho ou na consulta, e as implicações da interface humana para que os usuários possam atravessar / explorar a hierarquia de URLs editando o conteúdo da barra de endereço. Minha página 404 não encontrada usa variáveis ​​SSI para redirecionar automaticamente URLs quebrados para seus pais! Os robôs de pesquisa também podem atravessar a hierarquia do caminho. Por outro lado, pessoalmente, quando compartilho URLs nas mídias sociais, retiro manualmente quaisquer identificadores exclusivos privados - normalmente truncando a consulta a partir da URL, deixando apenas o caminho: nesse caso, existe alguma utilidade na colocação de identificadores exclusivos no caminho e não na consulta. Se queremos facilitar o uso de componentes de caminho como uma interface de usuário grosseira, talvez dependa se os dados / componentes são legíveis por humanos ou não. A questão da legibilidade humana relaciona-se um pouco à questão da hierarquia: freqüentemente, os dados que podem ser expressos como palavras-chave legíveis por humanos também são hierárquicos; enquanto os dados hierárquicos geralmente podem ser expressos como palavras-chave legíveis por humanos. (Os próprios mecanismos de pesquisa podem ser definidos como aumentando o uso de URLs como uma interface do usuário.) Hierarquias de palavras-chave ou diretivas podem não ser estritamente ordenadas, mas geralmente são próximas o suficiente para cobrir casos alternativos no caminho, erotule uma opção como o caso "canônico" .

Existem basicamente vários tipos de perguntas que poderíamos responder com o URL para cada solicitação:

  1. Que tipo de registro / coisa estamos solicitando / servindo?
  2. Em qual (s) interessado (s)?
  3. Como queremos apresentar as informações / registros?

Q1 é quase certamente melhor coberto pelo caminho ou pelo PathParams. Q3 (provavelmente controlado por meio de um conjunto de parâmetros opcionais e valores padrão ordenados arbitrariamente); é quase certamente melhor coberto por QueryParams. P2: Depende ...


2

Você pode suportar parâmetros de consulta e parâmetros de caminho, por exemplo, no caso de agregação de recursos - quando a coleção de sub-recursos faz sentido por si só.

/departments/{id}/employees
/employees?dept=id

Os parâmetros de consulta podem suportar subconjuntos hierárquicos e não hierárquicos; Os parâmetros do caminho são apenas hierárquicos.

Os recursos podem exibir várias hierarquias. Ofereça suporte a caminhos curtos se você estiver consultando subcoleções amplas que cruzam os limites hierárquicos.

/inventory?make=toyota&model=corolla
/inventory?year=2014

Use parâmetros de consulta para combinar hierarquias ortogonais.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

Use apenas parâmetros de caminho no caso de composição - quando um recurso não faz sentido divorciado de seu pai, e a coleção global de todos os filhos não é um recurso útil por si só.

/words/{id}/definitions
/definitions?word=id   // not useful

1

A razão é realmente muito simples. Ao usar um parâmetro de consulta, você pode inserir caracteres como "/" e seu cliente não precisa codificá-los em html. Existem outras razões, mas esse é um exemplo simples. Quanto a quando usar uma variável de caminho. Eu diria sempre que você estiver lidando com IDs ou se a variável path for uma direção para uma consulta.


1

Estou dando um exemplo para entender quando usamos @Queryparame@pathparam

Por exemplo, estou tendo um recurso é carResourceclasse

Se você quiser fazer as entradas do seu método de recurso manadatório, use o tipo de parâmetro como @pathaparam, se as entradas do método de recurso forem opcionais, mantenha esse tipo de @QueryParamparâmetro como param

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Para esse recurso, passe a solicitação

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Se você fornecer uma solicitação como essa, o recurso fornecerá o modelo e a cor do carro

 req uri://address:2020/carWeb/car/search/swift

Se você der uma solicitação como essa, o método ressoce exibirá apenas carros baseados em modelos rápidos

req://address:2020/carWeb/car/search?carcolor=red

Se você der assim, obteremos a exceção ResourceNotFound, porque na classe de recurso de carro declarei o modelo de carro como @pathPramvocê deve e deve dar o modelo de carro como reQ uri, caso contrário, ele não passará o req para o recurso, mas se você não passar a cor também passará o req ao recurso porque, porque a cor @quetyParamé opcional no req.


0
  1. @QueryParam pode ser convenientemente usado com a anotação Valor Padrão para evitar uma exceção de ponteiro nulo se nenhum parâmetro de consulta for passado.

Quando você deseja analisar parâmetros de consulta de uma solicitação GET, pode simplesmente definir o respectivo parâmetro para o método que manipulará a solicitação GET e anotá-los com @QueryParamanotação

  1. @PathParamextrai os valores de URI e corresponde a @Path. E, portanto, obtém o parâmetro de entrada. 2.1 @PathParampode ser mais de um e está definido para argumentos de métodos

    @Path("/rest")
    public class Abc {
    
        @GET
        @Path("/msg/{p0}/{p1}")
        @Produces("text/plain")
        public String add(@PathParam("p0") Integer param1, @PathParam("p1")  Integer param2 )
        {
            return String.valueOf(param1+param2);
        }
    } 

No exemplo acima
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0correspondências param1e p1correspondências param2. Então, para o URI
http://localhost:8080/Restr/rest/msg/4/6,
obtemos o resultado 10.

No Serviço REST, o JAX-RS fornece @QueryParame @FormParamambos para aceitar dados da solicitação HTTP. Um formulário HTTP pode ser enviado por diferentes métodos, como GET e POST.

@QueryParam : Aceita solicitação GET e lê dados da sequência de consultas.

@FormParam: Aceita a solicitação POST e busca dados do formulário HTML ou qualquer solicitação da mídia


0

Em poucas palavras,

@Pathparam funciona para a passagem de valor pelos Recursos e pela Cadeia de Consulta

  • /user/1
  • /user?id=1

@Queryparam funciona apenas para passagem de valor Query String

  • /user?id=1
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.