HATEOAS : 절대 또는 상대 URL?
HATEOAS를 사용하여 RESTful 웹 서비스를 설계 할 때 링크를 완전한 URL ( " http : // server : port / application / customers / 1234 ")로 표시하는 것과 경로 ( "/ application /) 로 표시하는 것의 장단점은 무엇입니까? customers / 1234 ")?
사람들이 "상대적 uri"라고 말할 때 미묘한 개념적 모호성이 있습니다.
으로 RFC3986의 정의 , 일반적인 URI를 포함 :
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
까다로운 것은 체계와 권한이 생략 될 때 "경로"부분 자체가 절대 경로 ( "/"로 시작) 또는 "루트없는"상대 경로가 될 수 있다는 것입니다. 예 :
- 절대 URI 또는 전체 URI :
"http://example.com:8042/over/there?name=ferret" - 그리고 이것은 절대 경로 가있는 상대 URI입니다 . "/ over / there"
- 그리고 이것은 상대 경로가 "here"또는 "./here"또는 "../here"등인 상대 URI입니다 .
따라서 질문이 "서버가 안정된 응답에서 상대 경로 를 생성해야하는지 여부 "인 경우 대답은 "아니오"이며 자세한 이유는 여기에서 확인할 수 있습니다 . 나는 "relative uri"에 반대하는 대부분의 사람들 (나를 포함)이 실제로 "relative path"에 반대한다고 생각합니다.
그리고 실제로 대부분의 서버 측 MVC 프레임 워크는 "/ absolute / path / to / the / controller"와 같은 절대 경로를 사용 하여 상대 URI를 쉽게 생성 할 수 있으며, 질문은 "서버 구현이 scheme : // hostname 접두사를 사용해야하는지 여부"가됩니다. : 절대 경로 앞의 포트 ". OP의 질문처럼. 나는 이것에 대해 잘 모르겠습니다.
한편으로는 여전히 전체 URI를 반환하는 서버를 권장한다고 생각합니다. 그러나 서버는 이와 같이 소스 코드 내에서 hostname : port 항목을 하드 코딩 해서는 안됩니다 (그렇지 않으면 절대 경로가있는 상대 uri로 대체합니다). 해결책은 서버 측에서 항상 HTTP 요청의 "호스트"헤더에서 해당 접두사를 가져 오는 것입니다. 이것이 모든 상황에서 작동하는지 확실하지 않습니다.
반면에 클라이언트가 "http://example.com:8042"절대 경로와 연결하는 것은 그리 번거롭지 않은 것 같습니다 . 결국 클라이언트는 서버에 요청을 보낼 때 이미 해당 체계와 도메인 이름을 알고 있습니까?
대체로 절대 uri를 사용하는 것이 좋습니다. 절대 경로를 사용하여 상대 uri로 대체하고 상대 경로를 사용하지 마십시오 .
클라이언트 코드를 작성하는 사람에 따라 다릅니다. 클라이언트와 서버를 작성하는 경우 큰 차이가 없습니다. 클라이언트 또는 서버에서 URL을 작성하는 데 어려움을 겪을 것입니다.
그러나 서버를 구축하고 다른 사람들이 클라이언트 코드를 작성하기를 기대한다면 완전한 URI를 제공하면 훨씬 더 좋아할 것입니다. 상대 URI를 확인하는 것은 약간 까다로울 수 있습니다. 먼저이를 해결하는 방법은 반환 된 미디어 유형에 따라 다릅니다. Html에는 기본 태그가 있고 Xml에는 모든 중첩 요소에 xml : base 태그가있을 수 있으며, Atom 피드에는 피드에 기본이있을 수 있고 콘텐츠에 다른 기본이있을 수 있습니다. 클라이언트에 기본 URI에 대한 명시적인 정보를 제공하지 않으면 요청 URI 또는 Content-Location 헤더에서 기본 URI를 가져와야합니다! 그리고 그 후행 슬래시를 조심하십시오. 기본 URI는 마지막 슬래시 오른쪽에있는 모든 문자를 무시하여 결정됩니다. 이는 이제 상대 URI를 확인할 때 후행 슬래시가 매우 중요하다는 것을 의미합니다.
작은 언급이 필요한 유일한 다른 문제는 문서 크기입니다. 각 항목에 여러 링크가있을 수있는 많은 항목 목록을 반환하는 경우 항목을 압축하지 않으면 절대 URL을 사용하면 항목에 상당한 양의 바이트가 추가 될 수 있습니다. 이것은 성능 문제이며 사례별로 중요한지 결정해야합니다.
유일한 실제 차이점은 클라이언트가 상대 버전에서 구성하는 대신 절대 URI를 사용하는 것이 더 쉽다는 것입니다. 물론, 그 차이는 절대 버전을하도록 나를 흔들기에 충분할 것입니다.
애플리케이션이 확장됨에 따라로드 밸런싱, 장애 복구 등을 수행 할 수 있습니다. 절대 URI를 반환하면 클라이언트 측 앱이 진화하는 서버 구성을 따릅니다.
RayLou의 삼분법을 사용하여 우리 조직은 (2)를 선호했습니다. 주된 이유는 XSS (Cross-Site Scripting) 공격을 피하는 것입니다. 문제는 공격자가 서버에서 돌아 오는 응답에 자신의 URL 루트를 삽입 할 수있는 경우 후속 사용자 요청 (예 : 사용자 이름 및 암호를 사용한 인증 요청)이 공격자의 자체 서버로 전달 될 수 있다는 것입니다 *.
일부는로드 밸런싱을 위해 요청을 다른 서버로 리디렉션 할 수 있다는 문제를 제기했지만 (내 전문 분야는 아니지만) 클라이언트를 다른 서버로 명시 적으로 리디렉션하지 않고도로드 밸런싱을 활성화하는 더 좋은 방법이 있다고 확신합니다. 호스트.
*이 논리에 결함이 있으면 알려주십시오. 물론 목표는 모든 공격을 막는 것이 아니라 적어도 하나의 공격 경로를 막는 것입니다.
항상 전체 URL을 사용해야합니다. URL은 모두 고유해야하므로 리소스의 고유 식별자 역할을합니다.
나는 또한 당신이 일관되어야한다고 주장합니다. Location HTTP 헤더는 HTTP 사양을 기반으로 전체 URL을 예상하므로 새 리소스가 생성 될 때 전체 URL이 Location 헤더에서 클라이언트로 다시 전송됩니다. Location 헤더에 전체 URL을 제공 한 다음 응답 본문 내의 링크에 상대 URI를 제공하는 것은 이상 할 것입니다.
절대 URI 사용의 한 가지 단점은 api를 프록시 할 수 없다는 것입니다.
다시 가져 가세요 ... 사실이 아닙니다. 도메인을 포함한 전체 URL로 이동해야합니다.
Regarding the pros, I see the reduction in bytes to be transmitted at the expense of extra handling required by a client for the (absolute) path. If you are desperate to save every byte, even after trying content-encoding as gzip, proper use of caching headers, usage of etags and conditional requests on the client, then this may be necessary in the end, but I expect much higher returns on your efforts elsewere.
Regarding the cons, I see a loss of control regarding how you can direct the flow of clients between resources in the future (load balancing, A/B testing, ...), and I would consider it a bad practice regarding managing a web API. The URL you provide is no longer basically opaque for the client (see Tim Berners-Lee Axioms of Web Architecture on URI opacity). In the end, you become responsible to keep clients happy regarding their creative usage of your API, even if it is only regarding the structure of your URL space. Should you ever need to allow for a explicitly defined URL modification, consider the usage of URI templates as used in the Hypertext Application Language.
An important consideration in large API results is the extra network overhead of including the full URI repeatedly. Believe it or not, gzip does not entirely solve this issue (not sure why). We were shocked at how much space the full URI took up when there were hundreds of links included in a result.
참고URL : https://stackoverflow.com/questions/2239405/hateoas-absolute-or-relative-urls
'Program Club' 카테고리의 다른 글
| Java가 지원하지 않는 주요 부 버전 52.0 (0) | 2020.10.14 |
|---|---|
| Django : 데이터베이스 항목의 동시 수정으로부터 어떻게 보호 할 수 있습니까? (0) | 2020.10.14 |
| 숫자 유형과 일치하는 일반 제약 (0) | 2020.10.14 |
| iPhone 대 iPad / 브라우저의 HTML5 인라인 동영상 (0) | 2020.10.14 |
| Android 애플리케이션에서 YouTube 비디오를 재생하는 방법은 무엇입니까? (0) | 2020.10.14 |