왜 작은 고정 어휘가 RESTful 서비스의 이점으로 보입니까?


13

따라서 RESTful 서비스에는 어휘에 고정 된 동사 세트가 있습니다. RESTful 웹 서비스는이를 HTTP 메소드에서 가져옵니다. 고정 어휘를 정의하면 몇 가지 장점이 있지만 실제로 요점을 이해하지는 못합니다. 누군가가 그것을 설명 할 수 있습니다.

각 주에 대해 어휘를 동적으로 정의하는 것보다 REST로 설명 된 고정 어휘가 더 나은 이유는 무엇입니까? 예를 들어 객체 지향 프로그래밍은 널리 사용되는 패러다임입니다. RPC는 고정 인터페이스를 정의하기 위해 설명되었지만 사람들이 RPC가 이러한 제약 조건에 의해 제한된다고 가정하는 이유를 모르겠습니다. RESTful 서비스가 컨텐츠 구조를 동적으로 설명하는 것처럼 인터페이스를 동적으로 지정할 수 있습니다.

REST는 어휘를 확장하지 않고도 성장할 수 있다는 장점이 있습니다. RESTful 서비스는 더 많은 리소스를 추가하여 동적으로 성장합니다. 객체 별 어휘를 동적으로 지정하여 서비스를 확장 할 때 무엇이 ​​잘못 되었습니까? 왜 우리는 객체에 어휘로 정의 된 메소드를 사용하고 서비스가 클라이언트에게 이러한 메소드가 무엇인지 그리고 부작용이 있는지 여부를 설명하도록하지 않습니까?

본질적으로 서버 측 리소스 구조에 대한 설명이 어휘의 정의와 동일하다는 느낌이 들지만 이러한 리소스와 상호 작용할 수있는 제한된 어휘를 사용해야합니다.

고정 어휘는 실제로 클라이언트의 문제를 서버의 문제와 분리합니까? 확실히 서버의 일부 구성과 관련이 있어야합니다. 이것은 일반적으로 RESTful 서비스의 리소스 위치입니다. 동적 어휘 사용에 대한 불만은 어쨌든이 구성을 이해하는 방법을 동적으로 추론해야하기 때문에 불공평 해 보입니다. RESTful 서비스는 하이퍼 미디어를 통해 객체 구조를 식별하여 수행 할 수있는 전환을 설명합니다.

RPC와 같은 서비스에서 쉽게 잘 작동 할 수있는 자체 설명 동적 어휘보다 고정 어휘를 더 잘 만드는 것이 무엇인지 이해하지 못합니다. 이것은 HTTP 프로토콜의 제한 어휘에 대한 잘못된 추론입니까?

반사

내 생각을 내가 한 것보다 조금 더 명확히하기 위해서. 웹용이 아닌 범용 API를 설계한다고 가정 해 봅시다. 누군가 객체에서 이러한 메소드 이름 만 사용할 수 있다고 말하면 기쁠까요? REST는 HTTP로 제한되지 않지만 작성하는 모든 API, 웹 연결 또는 단순히 GET POST PUT 및 DELETE 메소드가 포함 된 객체로 구성된 상황을 고려하십시오. 따라서 정의하려는 object.foo 메소드는 불가능합니다. foo라는 새 객체를 정의하고 GET 메소드를 호출해야합니다. 이것이 본질적으로 REST의 작동 방식이며, 그것에 대해 생각하기가 약간 불편합니다. 당신은 foo가하는 일에 대해 더 잘 이해하지 못하고, 부모 객체의 메소드가 무엇인지에 대한 새로운 객체를 만들도록 강요당했습니다. 또한 API는 그다지 복잡하지 않습니다. 더 많은 객체를 만들어 인터페이스 복잡성을 숨겼습니다. RESTful 웹 서비스는 우리가 노출하는 API의 맥락에서 충분하거나 충분하지 않은 인터페이스를 채택하도록 강요합니다. 웹 대면 API를 사용하여이를 수행하는 데는 적절한 이유가있을 수 있지만 모든 범용 API에서 모든 오브젝트에 대해 표준 인터페이스를 채택하지 않는 것이 좋습니다. 실제적인 예가 이해 될 것이다.


사용자가 질문과 답변을 신속하게 구문 분석 할 수 있도록 "업데이트"를 별도의 답변 (특히 "다른 업데이트"섹션)으로 추가하는 것을 고려할 수 있습니다. 권장 사항 : blog.stackoverflow.com/2011/07/…
Johann

@Johann 감사합니다. 추가 질문이 이제이 질문에 대한 답변으로 존재합니다.
Matt Esch

답변:


9

여기서 "동사"와 "명사"라는 용어는 다소 유감입니다. 이미 언급했듯이 기능을위한 객체를 쉽게 만들 수 있습니다. Java를 제외한 모든 객체 지향 언어에는 변환 기능이 내장되어 있으며 Java에서는 항상 단일 메소드를 사용하는 많은 객체로 끝나고 종종 "invoke", "execute", "apply"또는 이와 같은 객체로 끝납니다. "동사"/ "명사"구별이 실제로 의미가없는 프로그래밍 언어입니다.

REST의 "동사"는 메소드를 getter, setter (삭제 자; 일종의 setter로 간주 될 수 있음) 및 기타로 분류하는 것과 비슷합니다. 그리고 게터와 세터로 모든 것을하려고합니다. 그 이유는 다음과 같습니다.

  1. 게터와 세터가 모두 pot 등이기 때문에 통신 실패시 더 쉬운 의미론. 리소스를 두 번 얻는 것은 추가 효과가 없으며 이미 가지고있는 값으로 설정하지도 않습니다.
  2. 특정 인터페이스를 이해하지 못하는 프록시를 캐싱하여 사용할 수있는 일부 의미를 정의합니다. 게터는 캐시되고 세터는 캐시를 무효화하는 것으로 알려져 있습니다.

HTTP는 처음부터 캐시와 내결함성을 염두에두고 설계되었으므로이 두 가지 점으로 인해 네 가지 기본 방법이 있습니다.

  • GET게터입니다. 만료 및 재확인 정책을 지정할 가능성이있을 때마다 서버 상태를 수정하고 동일한 값을 반환하지 않는 것으로 가정합니다.
  • PUTDELETE세터와 Deleter가 (= 무기 호 설정 부)이다. 일반적으로 일반적인 웹 환경에서는 사용되지 않지만 REST에는 적합합니다.
  • POST 캐시는 아무것도 가정 할 수없는 일반적인 "호출"키친 싱크입니다.

REST는 원시 HTTP 또는 유사한 네트워크 프로토콜을 사용하여 간단한 재 시도를 통해 장애를 쉽게 처리하고 캐싱 프록시와 잘 작동하는 인터페이스를 구현하는 방법을 설명하는 디자인 패턴입니다.

일반적인 객체 지향 프로그래밍 API와 쉽게 일치하지 않습니다. 나는 그것이 실제로 좋은 것이라고 생각합니다. 본질적으로 신뢰할 수없고 왕복 처리가 프로세스 내 API와는 다른 설계 방식을 요구하는 중간 정도의 데이터를 전송하는 것보다 훨씬 느린 네트워크를 통한 인터페이스 문제는 사람들이 다르게 보일 때 적용하려고 시도하지 않습니다. 다른 도메인으로부터의 잘못된 경험 (SOAP, XML-RPC 등의 골칫거리입니다. 프로 시저 호출처럼 보이지만 작동하지 않으며 작동하기가 어려움).


2

필수 아이디어는 자원 표현을 통해 복잡성을 표현하므로 추가 동사가 필요하지 않다는 것입니다. "휴식에서 명사도 좋고 동사도 나쁘다."

4 개의 REST 동사를 보면 기본 CRUD 조작에 맵핑 될 수 있으므로 기본적으로 자원으로 원하는 것을 수행 할 수 있습니다. 그건 -

POST-자원 작성

GET-자료 읽기

PUT-자원 업데이트

삭제-리소스 삭제

그 밖에 무엇이 필요합니까?


RESTful 서비스에서 동사를 사용하기위한 자원을 작성하여 동사를 용이하게 할 수 있습니다. 당신이 말했듯이, 나는 더 많은 동사를 필요로하지 않습니다. 내가하고 싶은 것이 실제로 동사 일 때 추상적 동사가 명사 인 척하는 것이 더 나은 이유를 모르겠습니다. 동사가 이유없이 강제로 구속되는 것처럼 보이며 작은 동사 세트로 액세스 할 때 필요한 조치를 수행하는 명사를 작성하여 문제를 피하고 있습니다. 왜 그렇게하는 것이 좋을까요? 그것에 대한 정당한 이유가 있어야합니다. 실제적인 예로서 수량화 할 수 있습니다.
Matt Esch

4
모든 자원의 목록을 얻고, 주어진 제한 조건을 가진 모든 자원의 목록을 얻고, 동시에 많은 자원을 업데이트 또는 삭제하고, 서로 다른 두 가지 유형의 자원을 원자 적으로 생성하여 (둘 다 실패 또는 성공), 모든 자원을 삭제하십시오. 주어진 조건을 만족시키는 것 ...하고 싶은 일의 목록은 매우 길다. REST API에 맞출 수는 있지만 항상 자연스러운 것은 아닙니다. 또한 GET이 바디를 허용하지 않으므로 복잡한 필터링 조건이 까다로워집니다.
Andrea

PATCHing 리소스도 꽤 멋집니다.
Wyatt Barnett

2

함수와 같은 모든 구문이 객체 인 언어를 고려하십시오. 그런 다음 RESTful 동사는 단순히 규칙 및 할당 문을 호출합니다. JavaScript의 경우 함수 호출을위한 INVOKE, 다른 객체의 객체를 삭제하기위한 DELETE (js의 delete와 동일), 값을 할당하기위한 SET 및 값을 리턴하기위한 RETURN과 같은 고정 동사 구문을 정의 할 수 있습니다. HTTP 동사를 사용하여 동등한 POST-호출 함수, PUT-값 할당, GET-값 반환-DELETE-객체 삭제를 의미 할 수 있습니다. 나는 HTTP 메소드가 실제로 객체 메소드, 실제 객체 인터페이스를 설명하고 있다는 사실에 사로 잡혔다. 모든 언어에서 명확하게 고정되고 유한 한 기본 언어 구조와 같이 훨씬 낮은 수준의 개념을 실제로 설명 할 수 없다는 것을 알지 못했다. 제정신의 언어.

물론 라우팅 / 프록시가 반영 할 고정 어휘를 갖는 것이 도움이됩니다.


1
  • 전문 프로그래머는 수백 가지를 기대하기 때문에 수천 가지의 메서드 이름은 그렇지 않습니다. 응용 프로그램이 커짐에 따라 작은 크기로 무의미하게 보이는 것은 큰 문제가 될 수 있습니다.

  • 메소드 이름이 이미 정의 된 경우 메소드 이름에 대한 표준이 필요하지 않기 때문입니다.

  • 코드의 주요 목표는 이러한 추가 변환없이 읽을 수 있기 때문입니다.

  • 그것은 '언제'를 식별하도록 장려하고 도움을주기 때문에 다른 계급이 나뉘어 야한다.

  • 코드를 인계하면 합리적이고 실제로 그것이 무엇과 방법을 훨씬 빨리 이해하는 것이 가능합니다.

  • 일반적인 어휘와 추상화 수준을 제공하므로 다른 세부 사항에 집중하고 패턴을 볼 수 있습니다.

  • 일반적인 코드와 접근 방식을 쉽게 확인할 수있어 버그를 쉽게 찾을 수 있습니다.

  • 웹 개발에서와 같이 여러 '레이어'로 작업 할 때 어떤 URL이 어떤 액션 이름과 일치하는지 알고 있으면 디버깅에 매우 편리합니다.

전반적으로 항상 '항상'필요는 없지만 대부분의 표준과 마찬가지로 사용하려고 시도하는 것이 좋습니다.


순서대로 해결 1) 프로그래머는 그렇지 않으면 수천 개의 리소스가 아니라면 수백을 예상합니까? 우리는 이미 우리가 사용하는 라이브러리에서 메소드를 기대합니다. 2) 따라서 메소드 이름에 대한 표준이 필요하지만 리소스 이름에는 표준이 필요하지 않습니까? 나는 그 논리를 이해하지 못한다. 3) 번역의 의미를 잘 모르겠습니다. 당신이 자원이 존재한다고 말하면 나는 그것을 이해해야합니다. 내가 당신에게 방법이 존재한다고 말하면 당신은 그것을 이해해야합니다. 내가 정말로 염려하는 것은 나의 행동 중 어떤 것이 부작용을 일으킬 것인가이다. 4) 당신은 확장 할 수 있겠습니까
Matt Esch

5) 다시 확장 할 수 있습니다. 저는 프로그래머입니다. 나는 잘 정의 된 객체 구조로 작업하는 데 익숙합니다. 모든 API를 정의하는 데 동일한 메커니즘을 사용하지 않는 이유는 무엇입니까? 6) 정당화없이 고려할만한 수준의 추상화는 없습니다. 7) 다시 확장 할 수 있습니까? 이런 식으로 이익을 얻는다면 반드시 이와 같은 모든 API를 코딩해야합니다. 8) 객체가 메소드를 직접 노출시킬 것으로 기대합니다. / object / method는 혼동 될 수 없습니다. 우리는 표준을 채택하여 표준을 정의합니다. 현재 동기가 부족합니다.
Matt Esch

매트 당신은 조금 논쟁적인 것처럼 보이지만 2) 나는 자원이 표준을 필요로한다고 말하지 않았다. 그것들이 표준에 따라하는 것. 그러나 'MsgToPrimary'는 어떻습니까? 메시지를 만드시겠습니까? 상태를 업데이트 하시겠습니까? 이메일을 보내다? 7) 예, 대부분의 API는 이것으로 많은 이점을 얻을 수 있습니다. 나는 표준 표준에 중점을 두려고 노력하고 규칙이 도움이되며 업데이트가 그것을 보여주는 것을 볼 수 있습니다.
Michael Durrant

나는 그 이점을 이해하려고 열심히 노력하고 있습니다. 문제를 명확히하기 위해 강력한 반론을 다루어야합니다. 여전히 고정 동사 집합이 일종의 언어 설명이라는 것을 이해하지만 이해하기가 더 쉽다는 것에 동의하지 않습니다. 당신은 표현 동사를 빼앗아 말할 수 없습니다. 우리는 이제 모든 자원을 이해하지 못할 때 모든 동사를 이해합니다. 자원이 동사를 대체하고 있습니다. 임의 동사 foo를 foo라는 리소스로 바꿉니다. foo에 대한 우리의 이해는 foo가 동사 일 때보 다 명확하지 않습니다.
Matt Esch

1

대안은 끔찍한 것입니다. WSDL (일명 웹 서비스 정의 언어)은 임의의 API를 프로그래밍 방식으로 설명하는 (서투른) 방법입니다.

REST는 동사를 심각하게 제한하여 거의 모든 애플리케이션 별 변형을 문서의 페이로드로 밀어 넣습니다. 그렇게하면 많은 클라이언트 구현이 많은 이기종 서비스와 통신 할 수 있다는 이점이 있습니다. 클라이언트와 서버는 서로에게 완전히 알려지지 않았을 수 있으며 일부는 아직 작성되지 않았습니다.

Stefan Tilkov가 REST를 훌륭하게 설명 하는 팟 캐스트가 있습니다 .


1

예, 나머지 api에는 고정 된 동사 세트가 있지만 제한 할 필요는 없습니다 (또는 GET, POST, PUT, DELETE 포함). GET, POST, PUT, DELETE를 모든 시스템의 80 %에서 작동하는 REST의 기본 구현으로 봅니다.

crud보다 더 많은 연산을 구현하는 다른 시스템은 REST API에 대해 자체 동사를 구현할 수 있습니다. 게시, 소비, 평가, 설명, 검색, 찾아보기와 같은 동사는 REST 시스템에서 추가 및 구현 될 수 있습니다. 어떤 사람들은 더 큰 어휘가 더 복잡해 질 수 있다고 말할 수도 있지만, 제 대답은 그것이 다릅니다. 대상 사용자가 POST가 무엇인지 이해하는 기술 책임자라면 더 복잡 할 수 있습니다. 그러나 API의 대상 사용자가 실제 사람 (예 : 코딩하지 않고 POST가 무엇인지 모르는 사람)이면 실제 동사가 훨씬 사용하기 쉽습니다. 실제로 API에 적절한 동사 집합을 사용하면 URL을 짧게 유지하는 데 도움이됩니다 (사용자가 브라우저에 URL을 입력하도록하려는 경우 중요합니다. 사용자 지정 어휘를 사용하는 경우 d API와 동사가 잘 문서화되어 있는지 확인하고 싶습니다. 사용자 정의 REST API를 사용하는 경우 '읽기 전용 조치'를 HTTP GET으로 사용하고 POST를 사용하여 '쓰기 조치'를 수행하려고합니다.

10 대 소셜 네트워크 인 Piczo.com (편안하게 쉬어도 됨)에는 7 가지 언어로 구현 된 확장 REST API (위에 언급 된 동사 포함)가 있습니다!


0

간단합니다.

추가 동사와 복잡성이 필요한 경우가 있지만 대부분의 문제는 자원에 대한 간단한 CRUD 조치로 정리 될 수 있으며, 이것이 REST가 승격 시키려고하는 것입니다. 대부분의 웹 응용 프로그램에 대해 생각할 때 결국에는 매우 간단한 작업을 사용하는 데이터 저장소에서 레코드를 읽고 유지합니다.

object.foo ()는 모두 좋지만 무엇을합니까? 돌아 오는 것은 무엇입니까? 객체의 상태 또는 종속성을 수정하고 있습니까? 두 번 호출하여 동일한 결과를 얻을 수 있습니까? 아니면 두 가지 다른 값을 줄 수 있습니까? object.bar ()도 가지고 있다면 특정 순서로 호출해야합니까?

풍부한 API를 사용하는 데 필요한 많은 지식이 있으며 일반적으로 자체 규칙이 있습니다 (예 : setFoo는 객체를 변경하려고합니다. getBar는 dem 등원, dispose () 또는 destroy ()는 동일한 객체에 대한 다른 호출을 의미하지 않습니다. 가능할 것입니다 ...)

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