@QueryParam과 @PathParam을 사용하는 경우


276

: 난 이미 여기에 요청합니다 질문 요구 하진 않았어 @PathParam과 @QueryParam의 차이점은 무엇입니까

이것은 "모범 사례"또는 컨벤션 질문입니다.

당신은 언제 사용하는 것이 @PathParam@QueryParam.

결정이 정보 패턴을 차별화하기 위해 두 가지를 사용하고 있다고 생각할 수 있습니다. LTPO 아래에서 완벽하게 관찰하는 것보다 덜 설명하겠습니다.

PathParam 사용은 정보 카테고리를 위해 예약 될 수 있는데, 이는 정보 트리의 분기에 잘 들어 맞습니다. PathParam을 사용하여 엔티티 클래스 계층으로 드릴 다운 할 수 있습니다.

반면, QueryParam은 클래스의 인스턴스를 찾기 위해 속성을 지정하기 위해 예약 될 수 있습니다.

예를 들어

  • /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) ;

나는 그것을하는 표준 규칙이 없다고 생각합니다. 있습니까? 그러나 사람들이 PathParam과 QueryParam을 사용하여 위에서 설명한 것처럼 정보를 차별화하는 방법에 대해 듣고 싶습니다. 또한 연습의 이유를 듣고 싶습니다.


답변:


245

REST는 표준이 아니지만 일반적인 REST 문서 및 블로그 게시물을 읽으면 API URL을 구성하는 좋은 방법에 대한 지침을 제공해야합니다. 대부분의 나머지 API는 경로에 리소스 이름과 리소스 ID 만있는 경향이 있습니다. 같은 :

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

일부 REST API는 필터링, 페이지 매김 및 정렬을 위해 쿼리 문자열을 사용하지만 REST는 엄격한 표준이 아니므로 githubstackoverflow 와 같은 일부 REST API를 확인하고 사용 사례에 적합한 것이 무엇인지 확인하는 것이 좋습니다 .

경로에 필요한 매개 변수를 넣는 것이 좋습니다. 선택적 매개 변수는 반드시 쿼리 문자열 매개 변수 여야합니다. 경로에 선택적 매개 변수를 넣으면 다른 조합과 일치하는 URL 처리기를 작성하려고 할 때 실제로 혼란스러워집니다.


73
" 필요한 매개 변수를 경로에 넣는 것이 좋으며, 선택적 매개 변수는 반드시 쿼리 문자열 매개 변수 여야합니다. "
Thumbs

1
이 협약은 넣고 요청에 사용뿐만 아니라, 우리는 DB 엔티티의 특정 버전을 업데이트 할 말할 수해야한다, URI를해야합니다 PUT /depatments/{dept}/employees/{id}/{version}및 버전은 선택 사항 인 또는 그것이 있어야 PUT /depatments/{dept}/employees/{id}?version=12및 버전은 선택 사항 인
최고의 소원을

이 경우에는 다음 PUT /depatments/{dept}/employees/{id}/versions/{version}과 같이 명령합니다.-선택한 버전 POST /depatments/{dept}/employees/{id}/versions의 직원을 만들려면
Guillaume Vauvert

90

이것이 제가하는 것입니다.

id를 기준으로 레코드를 검색하는 시나리오가있는 경우, 예를 들어 id가 15 인 직원의 세부 사항을 가져와야하는 경우 @PathParam을 사용하여 자원을 가질 수 있습니다.

GET /employee/{id}

한 번에 10 명만 모든 직원의 세부 정보를 가져와야하는 시나리오가있는 경우 쿼리 매개 변수를 사용할 수 있습니다

GET /employee?start=1&size=10

이것은 직원 ID 1을 시작하면 10 개의 레코드를 얻습니다.

요약하면 id를 기반으로 검색 할 때 @PathParam을 사용하십시오. 필터에 대한 사용자 @QueryParam 또는 사용자가 전달할 수있는 고정 옵션 목록이있는 경우


'@PathParam'과 '@QueryParam'모두 동일한 기능을 제공합니까? '@QueryParam'은 같은 것을 쓰는 또 다른 방법입니까?
Rishabh Agarwal

1
@RishabhAgarwal 둘 다 동일한 기능을 제공하지만 깨끗한 코드 관행은 필수 매개 변수를 경로 변수로, 선택적 매개 변수를 쿼리 매개 변수로 사용하는 것이 좋습니다.
Akhil Ghatiki 5

@RishabhAgarwal 자세한 내용은, 당신은 내 문서를 참조 할 수 있습니다 나머지 API 모범 사례
아룬 B Chandrasekaran

43

매개 변수가 특정 엔티티를 식별하면 경로 변수를 사용해야한다고 생각합니다. 예를 들어, 내 블로그의 모든 게시물을 얻으려면 요청합니다.

GET: myserver.com/myblog/posts

id = 123 인 게시물을 얻으려면 요청합니다.

GET: myserver.com/myblog/posts/123

하지만 내 게시물 목록을 필터링하고 2013 년 1 월 1 일 이후 모든 게시물을 받으려면 요청합니다.

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

첫 번째 예에서 "게시물"은 특정 엔티티 (블로그 게시물의 전체 모음)를 식별합니다. 두 번째 예에서 "123"은 특정 엔티티 (단일 블로그 게시물)도 나타냅니다. 그러나 마지막 예에서 "since = 2013-01-01"매개 변수는 특정 엔티티가 아닌 게시물 콜렉션을 필터링하는 요청입니다. 페이지 매김 및 순서는 또 다른 좋은 예입니다.

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

희망이 도움이됩니다. :-)


8

필자는 개인적으로 "사용자가 이러한 매개 변수가 포함 된 URL을 책갈피에 추가 한 다음 PathParam을 사용하는 것이 합리적"인 방법을 사용했습니다.

예를 들어, 사용자 프로필의 URL에 일부 프로필 ID 매개 변수가 포함되어 있으면 사용자가 북마크하거나 전자 메일을 보낼 수 있으므로 해당 프로필 ID를 경로 매개 변수로 포함시킵니다. 또한 이것에 대한 또 다른 중요한 점은 경로 매개 변수를 포함하는 URL로 표시된 페이지가 변경되지 않는다는 것입니다. 사용자는 자신의 프로필을 설정하고 저장 한 다음 그 위치에서 많이 변경하지 않을 것입니다. 이는 웹 크롤러 / 검색 엔진 / 브라우저 / 등이 경로를 기반으로이 페이지를 멋지게 캐시 할 수 있음을 의미합니다.

URL에 전달 된 매개 변수가 페이지 레이아웃 / 컨텐츠를 변경할 가능성이있는 경우이를 queryparam으로 사용합니다. 예를 들어 프로필 URL이 사용자 전자 메일을 표시할지 여부를 지정하는 매개 변수를 지원하는 경우 쿼리 매개 변수로 간주합니다. (물론 &noemail=1매개 변수 매개 변수를 경로 매개 변수로 사용할 수 있으며 전자 메일 이 있거나 하나가없는 두 개의 별도 페이지를 생성하지만 논리적으로는 그렇지 않습니다. 특정 속성이 있거나없는 동일한 페이지입니다.

이것이 도움이되기를 바랍니다-설명이 약간 희미 할 수 있음을 이해합니다


이 답변이 리소스를 경로와 혼동한다고 생각합니다. 문제는 웹 애플리케이션의 경로가 아니라 일반적으로 JSON 또는 XML을 리턴하는 REST API의 자원에 관한 것으로 애플리케이션 내에서 탐색하는 데 도움이됩니다.
Hampus


5

매우 흥미로운 질문입니다.

두 가지를 모두 사용할 수 있지만이 주제에 대한 엄격한 규칙은 없지만 URI 경로 변수를 사용하면 몇 가지 장점이 있습니다.

  • 캐시 : 인터넷상의 대부분의 웹 캐시 서비스는 쿼리 매개 변수가 포함되어있을 때 GET 요청을 캐시하지 않습니다. 서버에서 데이터를 변경하기 위해 GET 요청을 사용하는 RPC 시스템이 많기 때문에 (실패해야합니다! Get은 안전한 방법이어야합니다)

그러나 경로 변수를 사용하면이 모든 서비스가 GET 요청을 캐시 할 수 있습니다.

  • 계층 : 경로 변수는 계층을 나타낼 수 있습니다 : / City / Street / Place

사용자에게 데이터 구조에 대한 추가 정보를 제공합니다.

그러나 데이터에 계층 관계가 없으면 쉼표 또는 세미콜론을 사용하여 여전히 경로 변수를 사용할 수 있습니다.

/ 도시 / 경도, 위도

일반적으로 매개 변수의 순서가 중요 할 때는 쉼표를 사용하고 순서가 중요하지 않은 경우 세미콜론을 사용하십시오.

/ IconGenerator / 빨강; 파랑; 녹색

이러한 이유 외에도 쿼리 문자열 변수를 사용하는 것이 매우 일반적인 경우가 있습니다.

  • HTML 양식 변수를 URI에 자동으로 넣으려면 브라우저가 필요할 때
  • 알고리즘을 다룰 때. 예를 들어 Google 엔진은 쿼리 문자열을 사용합니다.

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

요약하자면,이 방법 중 하나를 사용해야 할 강력한 이유는 없지만 가능하면 URI 변수를 사용하십시오.


2

앞서 언급했듯이 REST는 표준이 아닙니다. 그러나 표준 기반 URI 규칙을 구현하려는 경우 oData URI 규칙을 고려할 수 있습니다 . Ver 4는 OASIS 표준 으로 승인되었으며 Apache Olingo를 통한 Java를 포함한 다양한 언어의 oData 라이브러리가 있습니다 . 레드햇, 시트릭스, IBM, 블랙 베리, 드루팔, 넷플릭스 페이스 북, SAP 등 다른 업계의 지원을 받기 때문에 Microsoft의 산란 사실을 잊지 마십시오.

더 많은 채택자가 여기에 나열됩니다


2

Wikipedia에서 : Uniform Resource Locator

일반적으로 계층 적 형식으로 구성된 데이터가 포함 된 경로 는 슬래시로 구분 된 일련의 세그먼트로 나타납니다.

비 계층 적 데이터 의 쿼리 문자열을 포함하는 물음표 (?)로 앞 부분과 구분 된 선택적 쿼리 입니다.

— URL의 개념 설계에 따라 계층 적 데이터 / 지시문 / 로케이터 구성 요소에 대한 PathParam을 구현하거나 데이터가 계층 적이 아닌 경우 QueryParam을 구현할 수 있습니다. 이것은 경로가 자연스럽게 정렬되기 때문에 의미가있는 반면 쿼리에는 임의로 정렬 될 수있는 변수가 있습니다 (정렬되지 않은 변수 / 값 쌍).

이전 주석가는 다음과 같이 썼다.

매개 변수가 특정 엔티티를 식별하면 경로 변수를 사용해야한다고 생각합니다.

또 다른 사람은

ID를 기반으로 검색하려면 @PathParam을 사용하십시오. 필터에 대한 사용자 @QueryParam 또는 사용자가 전달할 수있는 고정 옵션 목록이있는 경우

다른,

경로에 필요한 매개 변수를 넣는 것이 좋습니다. 선택적 매개 변수는 반드시 쿼리 문자열 매개 변수 여야합니다.

— 그러나 특정 엔티티를 식별하기 위해 유연하고 비 계층적인 시스템을 구현할 수 있습니다! 하나는 SQL 테이블에 여러 개의 고유 인덱스가있을 수 있으며 고유 인덱스를 구성하는 필드 조합을 사용하여 엔티티를 식별 할 수 있습니다! 다양한 조합 (아마도 다르게 주문 됨)은 다양한 관련 엔티티 (참조 자)의 링크에 사용될 수 있습니다. 이 경우 개별 엔티티를 식별하는 데 사용되는 비 계층 적 데이터를 처리하거나 특정 변수 / 필드 (고유 인덱스의 특정 구성 요소) 만 지정하고 레코드 목록 / 세트를 검색 할 수 있습니다. 이러한 경우 URL을 QueryParams로 구현하는 것이 더 쉽고 논리적이며 합리적 일 수 있습니다!

긴 16 진 문자열이 경로의 나머지 부분에서 키워드 값을 희석 / 축소 할 수 있습니까? 경로 또는 쿼리에 변수 / 값을 배치 할 때 SEO에 미치는 잠재적 영향을 고려할 가치가 있습니다.주소 표시 줄의 내용을 수정하여 사용자가 URL의 계층 구조를 탐색 / 탐색 할 수 있는지 여부에 대한 휴먼 인터페이스 영향. 내 404 찾을 수 없음 페이지는 SSI 변수를 사용하여 깨진 URL을 상위로 자동 리디렉션합니다! 검색 로봇은 경로 계층 구조를 통과 할 수도 있습니다. 반면에 개인적으로 소셜 미디어에서 URL을 공유 할 때는 개인 고유 식별자를 수동으로 제거합니다. 일반적으로 URL에서 쿼리를 잘라 내고 경로 만 남겨두면됩니다.이 경우 고유 식별자를 배치하는 데 유용한 유틸리티가 있습니다. 쿼리가 아닌 경로에 있습니다. 조잡한 사용자 인터페이스로 경로 구성 요소를 쉽게 사용할 수 있는지 여부는 데이터 / 구성 요소를 사람이 읽을 수 있는지 여부에 따라 결정됩니다. 인간의 가독성 문제는 계층 구조의 문제와 관련이 있습니다. 사람이 읽을 수있는 키워드로 표현 될 수있는 데이터도 계층 적입니다. 계층 적 데이터는 종종 사람이 읽을 수있는 키워드로 표현 될 수 있습니다. 검색 엔진 자체는 URL을 사용자 인터페이스로 사용하는 기능을 보강하는 것으로 정의 될 수 있습니다. 키워드 또는 지시문의 계층 구조는 엄격하게 정렬되어 있지는 않지만 대체 경로를 대체 할 수있을 정도로 일반적으로 가깝습니다.하나의 옵션에 "표준"사례로 레이블을 지정하십시오 .

기본적으로 각 요청에 대한 URL로 답변 할 수있는 몇 가지 질문이 있습니다.

  1. 어떤 종류의 기록 / 물건을 요청 / 서빙하고 있습니까?
  2. 우리는 어느 것에 관심이 있습니까?
  3. 정보 / 기록을 어떻게 제시하고 싶습니까?

Q1은 경로 또는 PathParams에 의해 가장 잘 커버됩니다. Q3 (아마도 순서대로 정렬 된 선택적 매개 변수 및 기본값을 통해 제어 됨); 거의 확실히 QueryParams에 의해 커버됩니다. Q2 : 그것은…


2

하위 리소스 수집이 자체적으로 적합한 경우 리소스를 집계하는 경우와 같이 쿼리 매개 변수와 경로 매개 변수를 모두 지원할 수 있습니다.

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

쿼리 매개 변수는 계층 적 및 비 계층 적 하위 설정을 지원할 수 있습니다. 경로 매개 변수는 계층 적입니다.

리소스는 여러 계층을 나타낼 수 있습니다. 계층 적 경계를 넘는 광범위한 하위 컬렉션을 쿼리 할 경우 짧은 경로를 지원하십시오.

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

직교 계층 구조를 결합하려면 쿼리 매개 변수를 사용하십시오.

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

컴포지션의 경우 리소스가 부모와 이혼 할 수없고 모든 자식의 전역 컬렉션이 유용한 리소스가 아닌 경우 경로 매개 변수 만 사용하십시오.

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

1

그 이유는 실제로 매우 간단합니다. 쿼리 매개 변수를 사용할 때 "/"와 같은 문자를 사용할 수 있으며 클라이언트는 HTML 인코딩 할 필요가 없습니다. 다른 이유가 있지만 간단한 예입니다. 경로 변수를 사용하는시기에 관해서. ID를 처리 할 때마다 또는 경로 변수가 쿼리의 방향인지 말할 것입니다.


1

우리가 언제 사용 @Queryparam하고 있는지에 대한 하나의 기회를 해저에주고 있습니다.@pathparam

예를 들어 나는 1 Resouce의이 복용하고 carResource클래스

resouce 메소드의 입력을 필수로 설정하려면 param 유형을로 사용 @pathaparam하십시오. 자원 메소드의 입력이 선택적이어야하는 경우 해당 param 유형을 @QueryParamparam 으로 유지하십시오

@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
    }
}

이 resouce에 대한 요청을 전달

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

이렇게 req를 주면 resouce는 기반 자동차 모델과 색상을 제공합니다.

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

이와 같이 req를 제공하면 resoce 메소드는 빠른 모델 기반 자동차 만 표시합니다.

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

이렇게하면 자동차 resouce 클래스에서 carmodel을 필요로 선언 @pathPram하고 remodel uri로 자동차 모델을 제공해야 하기 때문에 ResourceNotFound 예외가 발생 합니다. 그렇지 않으면 req를 resou에 전달하지 않지만 색상을 전달하지 않으면 또한 색상이 @quetyParamreq에서 선택 사항 이기 때문에 req를 리소스에 전달합니다 .


0
  1. @QueryParam 쿼리 매개 변수가 전달되지 않은 경우 null 포인터 예외를 피할 수 있도록 기본값 주석과 함께 편리하게 사용할 수 있습니다.

GET 요청에서 쿼리 매개 변수를 구문 분석하려면 GET 요청을 처리하고 @QueryParam어노테이션 으로 주석을 달 수있는 메소드에 각 매개 변수를 정의하면됩니다.

  1. @PathParamURI 값을 추출하고에 일치합니다 @Path. 따라서 입력 매개 변수를 얻습니다. 2.1 @PathParam은 둘 이상일 수 있으며 메소드 인수로 설정됩니다.

    @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);
        }
    } 

위의 예에서
http://localhost:8080/Restr/rest/msg/{p0}/{p1},
p0match param1and p1matches param2. URI에 대한 그래서
http://localhost:8080/Restr/rest/msg/4/6,
우리는 결과를 얻을 10.

REST 서비스에서, JAX-RS가 제공 @QueryParam하고 @FormParamHTTP 요청으로부터의 데이터를 수용하기위한 두. HTTP 양식은 GET 및 POST와 같은 다른 방법으로 제출할 수 있습니다.

@QueryParam : GET 요청을 수락하고 쿼리 문자열에서 데이터를 읽습니다.

@FormParam: POST 요청을 수락하고 HTML 양식 또는 미디어 요청에서 데이터를 가져옵니다.


0

간단히 말해서

@Pathparam 리소스와 쿼리 문자열을 모두 통과하는 값에 사용

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

@Queryparam 쿼리 문자열 만 전달하는 값에서 작동합니다.

  • /user?id=1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.