REST Api가 Facade 디자인 패턴을 따르지 않는 이유


9

REST [api] 구조를 OO 모델과 비교할 때 다음과 같은 유사점이 있습니다.

양자 모두:

  • 데이터 지향

    • REST = 자원
    • OO = 객체
  • 데이터 주변의 서라운드 작동

    • REST = 자원 주변의 동사 (Get, Post, ...)
    • OO = 캡슐화를 통한 객체 주변의 작업 촉진

그러나 OO 사례는 우수 패턴을 적용하려고 할 때 항상 REST API에 의존하지는 않습니다. REST에서는 모든 요청을 처리 할 컨트롤러가 하나도 없으며 내부 객체 복잡성을 숨기지 않습니다.

두 개념 간의 간단한 객체 관계

OO와 REST의 비유

반대로 REST는 자원과 다른 두 가지 이상의 모든 관계에 대한 자원 공개를 촉진합니다.

  1. 리소스 계층 관계를 통해 (ID 43의 연락처는 주소 453으로 구성됨) /api/contacts/43/addresses/453

  2. REST json 응답의 링크를 통해 :

>> GET /api/contacts/43
<< HTTP Response {
   id: 43, ...
   addresses: [{
      id: 453, ...
   }],
   links: [{
      favoriteAddress: {
          id: 453
      }
   }]
}

objectA에 의해 숨겨진 기본 복잡성

OO로 되돌아오고, 외관 디자인 패턴이 존중 Low Coupling사이 objectA 및 ' objectB 클라이언트 '및 High Cohesion이를위한 objectA 및 내부 객체 조성물 ( objectC , objectD ). 으로 objectA의 인터페이스,이 한계에 영향을 현상 허용 objectBobjectA (내부 변화 objectCobjectD을 만큼 같이) objectA에 여전히 존중 API (동작).

REST에서는 데이터 (자원), 관계 (링크) 및 동작 (동사)이 다른 요소로 분해되어 웹에서 사용할 수 있습니다.

REST를 사용하면 클라이언트와 서버 간의 코드 변경에 항상 영향을 미칩니다 . 요청과 리소스 High Coupling사이에 있기 때문 입니다.Backbone.jsLow Cohesion

REST 링크로 촉진 된 Backbone.js javascript application" REST 리소스 및 기능 " 검색을 처리 하는 방법을 찾지 못했습니다 . WWW는 다중 서버에 의해 제공되며 OO 요소는 여러 호스트에서 서비스를 받기 위해 폭발해야했지만 주소와의 접촉을 보여주는 페이지를 "저장"하는 것과 같은 간단한 시나리오에서는 나는 결국 :

GET /api/contacts/43?embed=(addresses)
[save button pressed]
PUT /api/contacts/43
PUT /api/contacts/43/addresses/453

브라우저 응용 프로그램에 대한 저장 작업 원자 트랜잭션 책임을 이동시킵니다 (두 개의 리소스를 별도로 처리 할 수 ​​있기 때문에).

이를 염두에두고 개발을 단순화 할 수없는 경우 (파사드 디자인 패턴은 해당되지 않음) 고객에게 더 많은 복잡성을 가져 오는 경우 (트랜잭션 원자 저장 처리) RESTful의 이점은 어디에 있습니까?


1
이해하겠습니다. 두 개의 REST 호출을 사용하여 "임베디드"(구성) 링크 된 주소로 연락처를 업데이트해야한다고 말하고 있습니다. 하나는 연락처 용이고 다른 하나는 해당 주소 용입니다. 연락처 업데이트를 처리 할 수있는 Facade가 있습니다. PUT /api/contacts/43캐스케이드를 내부 객체의 업데이트로 만드는 데 어떤 문제가 있습니까? 나는 이와 같이 설계된 많은 API를 가지고 있었다 (마스터 URL은 "전체"를 읽고 / 만들고 / 업데이트하고 하위 URL은 조각을 업데이트한다). 변경이 필요하지 않은 경우 (성능상의 이유로) 주소를 업데이트하지 마십시오.
Anthony Accioly

@AnthonyAccioly, 당신은 올바르게 이해했습니다. 이미지를 추가하여 내 질문을 명확히하려고했습니다. 당신의 제안은 좋으며 그것은 또한 내가 얻은 결론입니다 : 수동으로 요청을 제어하고 포함 된 객체를 사용하여 내 업데이트를 유지하기위한 요청을 하나만 보냅니다. 여전히 : 왜 REST의 모든 것이 내 모델을 평평하게하여 (많은 컨트롤러를 포함하여) OO 품질 또는 시행 (캡슐화 ...)에서 멀어지게합니까? 솔루션을 사용하면 1 개의 원자 업데이트가 제공됩니다. 솔루션을 사용하지 않으면 개발자에게 새로운 책임이 부여되고 API에 대한 규칙이 없어야합니다.
Alain

참고로 언급 한 "자원 계층 관계"는 관계 정보를 식별자 (이 경우 URL)로 인코딩하는 방법에 달려 있습니다. 이 정보 노출이 REST의 일부이거나 홍보하는 것이 확실하지 않습니다. 시스템의 URL을 만들 때 스스로 결정하는 것입니다. 다른 방법으로 생각한다면 REST의 일부로이 문제를 논의하는 Roy Fielding에 대한 언급이 있습니까?
Thiago Silva

답변:


7

나는 객체가 데이터가 아닌 일관된 행동에 대해서만 올바르게 구축되었다고 생각합니다 . 나는 객체 지향 세계에서 데이터가 거의 관련이 없다고 자극하고 말할 것입니다. 실제로 "로그 싱크"와 같이 데이터를 반환하지 않는 개체 또는 통계적 속성을 계산하는 경우 전달 된 데이터를 반환하지 않는 개체를 갖는 것이 가능하고 때로는 흔한 일입니다.

우리가 혼동하지 말자 PODS (자세한 구조보다 조금 있습니다), 그리고 (같은 행동이 실제 개체를 Contacts귀하의 예제에서 클래스) 1 .

PODS는 기본적으로 저장소 및 비즈니스 오브젝트와 대화하는 데 사용되는 편의입니다. 코드를 안전하게 입력 할 수 있습니다. 그 이상도 이하도 아닌. 반면 비즈니스 개체는 데이터 유효성 검사, 저장 또는 계산을 수행하는 등의 구체적인 동작을 제공 합니다.

따라서 행동은 "응집력" 2 를 측정하기 위해 사용하는 것이며 , 객체 예에서는 최상위 접점을 조작하는 방법 만 표시하고 주소를 조작하는 방법은 표시하지 않지만 응집력이 있음을 쉽게 알 수 있습니다.

REST와 관련하여 REST 서비스를 데이터 저장소로 볼 수 있습니다. 객체 지향 디자인과의 큰 차이점은 (거의) 하나의 디자인 선택 만 있다는 것입니다. 네 가지 기본 방법이 있습니다 ( HEAD예를 들어 계산하면 더 많음). 물론 URI와 관련하여 많은 여유가있어서 깔끔합니다. 많은 id를 전달 하고 더 큰 구조를 되 찾는 것과 같은 것들 . 전달 하는 데이터 와 수행 하는 작업 을 혼동하지 마십시오 . 응집력과 결합은 데이터가 아니라 코드 에 관한 것 입니다.

분명히 REST 서비스는 높은 응집력 (자원과 상호 작용하는 모든 방법이 같은 위치에 있음)과 낮은 결합 (모든 자원 저장소에는 다른 지식이 필요하지 않음)이 있습니다.

그러나 기본 사실은 여전히 ​​REST는 데이터 의 단일 리포지토리 패턴 입니다. 이는 "채팅 성"비용이 높은 느린 매체에 대한 손쉬운 접근성을 기반으로 구축 된 패러다임이기 때문에 결과가 발생합니다. 클라이언트는 일반적으로 가능한 적은 작업을 수행하려고하지만 동시에 필요한 데이터 만 수신합니다. . 데이터 트리를 얼마나 깊이 다시 보낼 것인지 결정합니다.

(올바른) 객체 지향 디자인에서 사소한 응용 프로그램은 예를 들어 컴포지션을 통해 훨씬 더 복잡한 작업을 수행합니다. REST는 API 프로토콜이지만 OOD는 전체 사용자 대면 애플리케이션을 빌드하는 데 사용되므로 데이터를 사용하여보다 전문화 된 작업을 수행 할 수있는 방법이있을 수 있습니다. 이것이 응집력 및 커플 링 측정이 OOD에서 기본이지만 REST에서는 거의 중요하지 않은 이유입니다.

OO 개념으로 데이터 디자인을 분석 하는 것이 신뢰할 수있는 측정 방법이 아니라는 점은 분명 합니다. 사과와 오렌지를 비교하는 것과 같습니다!

사실, RESTful의 이점은 (위에서) 위에서 설명한 이점이라는 것이 밝혀졌습니다. 느린 매체에 대한 간단한 API에는 좋은 패턴입니다. 매우 캐시 가능하고 샤드 가능합니다. 대화 등을 세밀하게 제어 할 수 있습니다.

나는 이것이 당신의 (quite multifaceted) 질문에 대답하기를 바랍니다 :-)


1 이 문제는 객체 관계형 임피던스 불일치 로 알려진 더 큰 문제의 일부입니다 . ORM 지지자들은 일반적으로 데이터 분석과 행동 분석 의 유사점 을 모색하는 수용소 에 있지만 ORM은 임피던스 불일치를 실제로 해결하지 않는 것처럼 보이고 누설 추상화간주 되기 때문에 늦게 비판을 받았습니다 .

2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)


당신은 옳습니다. 나는 여러 측면에서 내 질문을 폭발시키고 특정 지점을 정리하기가 힘들었습니다. 질문은 이러한 측면의 축적에 기초한 "잘못된"결론을 다루기 때문입니다. 나는 많은 의견으로 당신의 요점에 대답하려고 노력할 것입니다.
Alain

[text 1] OO와 REST 세계에서 추상화하기 위해 "data"라는 단어를 사용했습니다. OO의 속성과 REST의 데이터 구조를 추상화하는 데 사용한 단어는 무엇입니까?
Alain

@Alain "데이터"는 괜찮지 만 PODS와 비즈니스 객체를 혼동하지 않아야합니다. OOD에 대해 이야기 할 때 일반적으로 두 번째에 대해 이야기합니다. 첫 번째는 편의성이며, 사전이나 구조체 또는 튜플을 거의 쉽게 생각할 수 있습니다.
Sklivvz

예, 모델 저장이 간단한 json 구조를 사용하는 경우 Backbone.js를 사용한다는 데 동의합니다. 이것은 텍스트가 실제 코딩 경험을 반영하는 곳입니다.
Alain

[텍스트 3] 이것은 나에게 새로운 것입니다. 응집력은 방법이 특정 관계를 사용하는 횟수에 의해 측정되었다고 생각했습니다. 나는 그것을 보는 방식을 선호합니다.
Alain

1

이를 염두에두고 개발을 단순화 할 수없는 경우 (파사드 디자인 패턴은 해당되지 않음) 고객에게 더 많은 복잡성을 가져 오는 경우 (트랜잭션 원자 저장 처리) RESTful의 이점은 어디에 있습니까?

"휴식의 이점은 어디에 있습니까?"에 대한 답변 여기에 철저하게 분석되고 설명되어 있습니다 : http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

이 질문의 혼란은 REST의 특성과 대처 방법에 관한 것이 아니라 예제 시스템에 대해 URL 디자인이 RESTful과 관련이 있다고 가정한다는 것입니다. 결국 REST는 참조해야 할 항목에 대해 자원이라는 항목이 있으며 식별자를 제공해야한다고 명시하지만, ER 모델의 엔티티는 작성한 URL과 1-1의 일치 성을 가져야한다는 것은 아닙니다. (URL은 모델에서 ER 관계의 카디널리티를 인코딩하지 않아야합니다).

연락처 및 주소의 경우 PUT 또는 POST 될 때마다 이러한 정보를 추출하여 다른 관계형 DB 테이블에 저장하려는 경우에도 이러한 정보를 단일 단위로 공동으로 표시하는 자원을 정의 할 수 있습니다. .


1

파사드는 '주름'이기 때문이다. 'api abstraction'과 'api chaining'을 살펴보십시오. API는 I / O와 리소스 관리의 두 가지 기능의 조합입니다. 로컬에서 I / O는 양호하지만 분산 아키텍처 (예 : 프록시, API 게이트, 메시지 큐 등) 내에서 I / O가 공유되므로 데이터와 기능이 복제되어 얽 힙니다. 이로 인해 아키텍처 간 절단 문제가 발생합니다. 이것은 기존의 모든 API를 괴롭 힙니다.

이 문제를 해결하는 유일한 방법은 API의 I / O 기능을 프리 / 포스트 핸들러 (Spring / Grails의 handlerIntercepter 또는 Rails의 필터와 같은)로 추상화하여 기능을 모나드로 사용하고 인스턴스와 외부에서 공유 할 수 있도록하는 것입니다. 압형. 요청 / 응답을위한 데이터도 객체에서 외부화되어야 공유하고 다시로드 할 수 있습니다.

http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining


0

REST 서비스 또는 일반적으로 모든 종류의 API를 이해 하면 클라이언트에 추가 인터페이스가 노출되어 컨트롤러를 통해 컨트롤러를 프로그래밍 할 수있는 것처럼 갑자기 쉽게 커질 수 있습니다. 이 서비스는 비즈 로직 위에 추가 계층에 지나지 않습니다.

즉, 위의 그림에서와 같이 여러 컨트롤러간에 biz 로직을 분리 할 필요가 없으며, 더 중요하게는 그렇게하지 않아야합니다. 데이터를 교환하는 데 사용되는 데이터 구조는 내부적으로 사용하는 데이터 구조와 일치 할 필요가 없으며, 상당히 다를 수 있습니다.

비즈 로직을 UI 코드에 넣는 것은 좋지 않다는 것이 최신 기술이며 널리 받아 들여지고 있습니다. 그러나 모든 UI는 비즈 로직을 제어하기위한 일종의 인터페이스 (UI의 I)입니다. 결과적으로 모든 biz 로직을 REST 서비스 계층 또는 다른 API 계층에 배치하는 것은 나쁜 생각입니다.

개념적으로 말해서 UI와 서비스 API 사이에는 큰 차이가 없습니다.


레이어 개념에 동의하지만 "컨트롤러를 통해 컨트롤러를 프로그래밍"한다는 것은 무엇을 의미합니까?
Alain

1
컨트롤러 자체가 실제 서비스라는 사실을 강조하고 싶습니다. 모든 것을 감싸는 인터페이스는 단지 무언가를 성취하는 수단 일뿐입니다. 어떤 방식 으로든 랩핑 된 기능에 쉽게 액세스 할 수 있도록 모든 인터페이스가 존재합니다. GUI는 휴먼 사용자를 위해이를 수행하며 클라이언트는 서비스 API를 사용합니다. 두 대상 청중 모두 인터페이스 뒤에 감싼 것들로 무언가를 달성하고자합니다. "프로그램"이 그 말에 가장 적합한 표현은 아니지만 "제어기 제어"도 어색하게 들립니다. ;-)
JensG
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.