RESTful API는 빈혈 도메인 모델을 장려하는 경향이 있습니까?


34

도메인 중심 디자인과 REST를 모두 서비스 지향 아키텍처에 적용하려는 프로젝트를 진행 중입니다. 우리는 약 100 % REST 준수에 대해 걱정하지 않습니다. 리소스 지향 HTTP API (~ Richardson의 REST 성숙도 모델의 레벨 2) 를 구축하려고한다고 말하는 것이 좋습니다 . 그럼에도 불구하고, 우리는 HTTP 요청의 RPC 스타일의 사용을 멀리하려고하는, 즉 우리가 구현하려고 우리의 HTTP 동사에 따라 RFC2616 대신 사용하는 것보다 POSTIsPostalAddressValid(...)예를 들어,.

그러나 이것에 중점을 둔 것은 도메인 기반 디자인을 적용하려는 시도를 희생하는 것으로 보입니다. 단지로 GET, POST, PUT, DELETE그리고 몇 가지 다른 거의 사용되지 않는 방법, 우리는 CRUDdy 서비스를 구축하는 경향이 있고, CRUDdy 서비스는 빈혈 도메인 모델을 가지고하는 경향이있다.

POST: 데이터를 수신하여 유효성을 검증 한 후 데이터로 덤프하십시오. GET: 데이터를 가져 와서 반환합니다. 실제 비즈니스 로직이 없습니다. 우리는 또한 서비스간에 메시지 (이벤트)를 사용하며 대부분의 비즈니스 로직은 그 주위에 구축되는 것으로 보입니다.

REST와 DDD가 어느 정도 긴장 상태입니까? (또는 내가 여기서 오해하고 있습니까? 우리가 다른 것을 잘못하고 있습니까?) RPC 스타일 HTTP 호출을 피하면서 서비스 지향 아키텍처에서 강력한 도메인 모델을 구축 할 수 있습니까?


1
POST는 의도적으로 "의도적으로 모호 하게 " 설계되었습니다 . POST의 결과는 구현에 따라 다릅니다. Twitter 및 기타 API 디자이너가하는 일을 방해하고 API의 비 CRUD 부분에 각 POST 방법을 고유 한 요구 사항에 따라 정의하는 것은 무엇입니까?
Robert Harvey

@RobertHarvey 우리는 POST를 create로 해석했다. 표준을 다시 살펴보면 지나치게 단순 할 것입니다. 예를 들어, POST IsPostalAddressValid(...)를 "양식 제출 결과와 같은 데이터 블록을 데이터 처리 프로세스에 제공"하는 데 적합 하다고 생각 하십니까?
Kazark

CREATE 동사가 없기 때문입니다 (그리고 그 문제에 대한 UPDATE 동사도 없기 때문입니다). 나는 그 동사가 어떤 이유로 든 표준에서 빠져 있다고 유지합니다. 그래서 "다른 모든 것"에 대해 POST를 함께 선택해야합니다. 이 경우 "데이터 처리 프로세스"는 우편 주소를 검사하고 해당 분석 결과에 해당하는 값을 반환하는 프로세스입니다.
Robert Harvey

1
@RobertHarvey : POST 및 PUT / PATCH는 단순히 당신이 원하는 CREATE 및 UPDATE 동사라고 생각합니다. 동사가 비 RESTful 디자인에서도 여전히 의미가 있도록 다르게 명명되었습니다.
Lie Ryan

@ LieRyan : 나는 당신에게 그것을 부여합니다. CRUD는 정의에 따라 빈혈 데이터 모델을 의미한다고 생각합니다. 예를 들어 MVC M에는 있지만 이기종 시스템에는 해당되지 않는 경우 일부 동작을 수행 할 수 있습니다. CRUD 이외의 모든 것에는 POST가 필요합니다.
Robert Harvey

답변:


38

Martin Fowler의 최초 분산 시스템 법칙 : "객체를 배포하지 마십시오!" 원격 인터페이스는 거칠고 내부 인터페이스는 세분화되어야합니다. 리치 도메인 모델은 종종 제한된 컨텍스트 내에서만 적용됩니다 .

REST API는 자체 내부 모델이있는 두 가지 컨텍스트를 분리합니다. 컨텍스트는 "anemic"objects (DTO)를 사용하여 RESAT API (coarse-grained interface)를 통해 통신합니다.

귀하의 경우 REST API 인 경계에 컨텍스트를 분산하려고하는 것처럼 들립니다. 이는 세분화 된 원격 인터페이스 또는 빈혈 모델로 이어질 수 있습니다. 프로젝트에 따라 문제가 될 수도 있고 아닐 수도 있습니다.


1
Fowler는 좋은 생각을 많이 가지고 있지만 원래 EJB 스펙과 구현이 어떤 재앙인지 잊지 말자. 그 후에야 getName ()과 같은 모든 사소한 작업에 대한 저수준 메소드 호출이 네트워크 /로드 악몽이라는 것을 알았습니다. 조잡한 인터페이스는 갈 길이되었으며, 전체 엔터티 그래프 / 메시지가 동사 + 명사 문맥으로 송수신되었다는 개념이되었습니다.
Darrell Teague

9

POST는 의도적으로 "의도적으로 모호 하게 " 설계되었습니다 . POST의 결과는 구현에 따라 다릅니다. Twitter 및 기타 API 디자이너가하는 일을 방해하고 API의 비 CRUD 부분에 각 POST 방법을 고유 한 요구 사항에 따라 정의하는 것은 무엇입니까? POST는 catchall 동사입니다. 다른 동사가 수행하려는 작업에 적합하지 않은 경우에 사용하십시오.

다시 말해, '스마트 한'객체가 RPC 스타일 디자인을 장려 하는가? 심지어 "Anemic Domain Model"이라는 용어를 만든 Martin Fowler조차도 DTO가 다음과 같은 이점을 가지고 있다고 인정합니다.

도메인 객체에 행동을 넣는 것은 도메인 로직을 지속성 및 표현 책임과 같은 것들로부터 분리하기 위해 계층화를 사용하는 확실한 접근 방식과 모순되지 않아야합니다. 도메인 개체에 있어야하는 논리는 유효성 검사, 계산, 비즈니스 규칙 등 도메인 논리 입니다.

Richardson Maturity Model 과 관련하여 "Anemic Domain Models"에 대해 걱정하지 않고 레벨 3에 도달 할 수 있습니다. 모델을 통해 일부 Javascript를 주입하려는 경우가 아니라면 브라우저로 동작을 전송하지 않습니다.

REST는 대부분 기계 독립에 관한 것입니다. 엔드 포인트가 자원을 표현할 정도로 REST 모델을 구현하고 API 소비자가 해당 자원을 표준 방식으로 쉽게 액세스하고 유지 보수 할 수 있도록합니다. 그것이 빈혈증처럼 보인다면, 그렇게하십시오.

참조
내가 더 동사 필요


나는 이것이 RFC2616의 문제를 분명히 다루고 있다고 생각합니다. 우리가 자원 중심적이 되려고 노력한다는 것, 즉 REST에 대한 Richardson 성숙도 모델에서 레벨 2를 달성하려고한다는 사실은 어떻습니까?
Kazark

1
martinfowler.com/articles/richardsonMaturityModel.html을 읽었습니다 . "Anemic Domain Models"에 대해 걱정하지 않고 레벨 3에 도달 할 수 있습니다. 모델을 통해 일부 Javascript를 주입하려는 경우가 아니라면 브라우저로 동작을 전송하지 않습니다.
Robert Harvey

4

REST API는 한 가지 유형의 프리젠 테이션 계층입니다. 도메인 모델과 관련이 없습니다.

당신이 게시 한 질문은 어떻게 든 서로 적응해야한다는 혼란에서 비롯됩니다. 당신은하지 않습니다.

ORM을 통해 도메인 모델을 RDBMS에 맵핑하는 것과 동일한 방법으로 도메인 모델을 REST API에 맵핑합니다.이 맵핑 계층이 있어야합니다.

도메인 ← ORM → RDBMS
도메인 ← REST 맵핑 → REST API


3

IMHO 나는 그들이 빈혈증 도메인 모델 (ADM)을 장려하는 경향이 있다고 생각하지는 않지만, 시간을 내고 생각을해야합니다.

우선 ADM의 주된 특징은 ADM의 동작이 거의 없거나 전혀 없다는 것입니다. 그것은 시스템에 아무런 행동이 없다고 말하는 것이 아니며, 일반적으로 일종의 서비스 클래스에 있다는 것입니다 ( http://vimeo.com/43598193 참조 ).

물론 ADM에 동작이 없으면 어떻게해야합니까? 물론 대답은 데이터입니다. 그리고 이것이 어떻게 REST API에 매핑됩니까? 아마도 데이터는 리소스의 내용에 매핑되고 동작은 HTTP 동사에 매핑됩니다.

따라서 풍부한 도메인 모델을 구축하는 데 필요한 모든 것을 갖추고 있으므로 HTTP 동사가 데이터의 도메인 작업에 어떻게 매핑되는지 확인한 다음 해당 작업을 데이터를 캡슐화하는 동일한 클래스에 배치해야합니다.

사람들이 문제에 부딪 치는 경향이 있다고 생각합니다. 행동이 단순한 CRUD를 넘어 서면, 즉 도메인의 다른 부분에 부작용이있을 때 HTTP 동사가 도메인 행동에 어떻게 매핑되는지 보는 데 어려움을 겪고 있다고 생각합니다. HTTP 요청에 의해 수정되는 리소스. 이 문제를 해결하는 한 가지 방법은 도메인 이벤트 ( http://www.udidahan.com/2009/06/14/domain-events-salvation/ )를 사용하는 것입니다.


3

기사는 주제와 관련이 있으며 귀하의 질문에 대한 답변입니다.

내가 생각하는 핵심 개념은 다음 기사에서 언급 한 기사의 요약입니다.

"REST API의 리소스와 도메인 기반 디자인의 도메인 엔터티를 구별하는 것이 매우 중요합니다. 도메인 기반 디자인은 구현 측면 (API 구현 포함)에 적용되는 반면 REST API의 리소스는 API 디자인 및 계약을 주도합니다. API 리소스 선택은 기본 도메인 구현 세부 사항에 의존해서는 안됩니다. "


1

여러 가지 합리적으로 성공적인 구현은 엔티티에 작용하는 굵은 '비즈니스 친화적 인'방법을 사용하여 동사 + 명사 비유를 혼합하는 방법에 대한 질문에 대답했습니다.

따라서 (doomed) getName()메소드 / 서비스 대신에 expose getPerson()을 사용하여 identifier-type / ID와 같은 것을 전달하여 전체 Person엔티티를 반환합니다 .

그러한 맥락에서 Person 엔티티의 행동은 적절하게 전달 될 수 없기 때문에 (아마도 이것과 같이 데이터 중심 맥락에 있어야한다) 서비스.

서비스 및 정의 된 동사 자체는 엔티티에 대한 일부 도메인 허용 동작, 제어 및 상태 전이 규칙을 추가합니다. 예를 들어, transferPerson()서비스 호출 에서 발생하는 상황에 대한 도메인 별 논리가 있지만 인터페이스 자체는 THEIR 내부 동작을 정의하지 않고 입력 / 출력 엔티티 / 데이터 만 정의합니다.

예를 들어, 전송 동사 구현이 Person 클래스에 속하거나 Person 중심 서비스와 연관된 저자에 동의하지 않습니다 . 실제로, (이 간단한 예에서) 및 그 옵션에 대한 전송 방법은 a에 Person의해 더 잘 정의 될 수 있는데 Carrier, 여기서는 Person어떤 전송 방법이 이용 가능한지 또는 전송이 어떻게 이루어지는 지에 대한 지식이 없을 수있다 (제트 엔진이 어떻게 작동하는지 아는 사람) 어쨌든).

이것이 Person실체를 빈혈로 만드는가? 나는 그렇게 생각하지 않습니다.

건강 상태와 같이 Person 내부에있는 Person 고유의 사물에 대한 논리가있을 수 있습니다. 외부 클래스에 의해 정의되지 않아야합니다.

그러나 유스 케이스에 따라 운송 시스템의 좌석 할당 서비스와 같은 특정 시스템에서 엔티티 클래스에 중요한 / 관련 동작이없는 것이 전적으로 허용됩니다. 이러한 시스템은 Person 인스턴스 및 관련 식별자를 처리하지만 내부 동작을 정의 / 구현하지 않는 REST 기반 서비스를 잘 구현할 수 있습니다.


좋은 점 --- 이것은 다른 답변이 아직 얻지 못한 새로운 관점을 제공합니다.
Kazark

0

POST를 가능한 많이 사용하여 모델을 기본 동사 세트에 넣으려는 문제가 있습니까?

필요하지는 않습니다-대부분의 사람들에게 REST는 POST, GET, PUT 및 DELETE를 의미하지만 http rfc는 다음과 같이 말합니다.

HTTP / 1.1에 대한 일반적인 방법 세트는 아래에 정의되어 있습니다. 이 세트를 확장 할 수는 있지만 별도로 확장 된 클라이언트 및 서버에 대해 동일한 의미를 공유하는 추가 방법을 가정 할 수 없습니다.

SMTP와 같은 시스템은 동일한 스타일의 동사 기반 방법을 사용하지만 완전히 다른 세트를 사용합니다.

따라서, 당신이 이것을 사용해야 할 이유가 없습니다. 당신이 좋아하는 동사를 사용할 수 있습니다 (사실, 당신은 약간의 생각으로 기본 4에서 필요한 모든 것을 할 수 있음을 알게 될 것입니다). REST를 다른 메커니즘과 구별되게 만드는 것은 이러한 동사를 구현하는 상태가없고 일관된 방식입니다. 기본적으로 REST를 수행하지 않고 계층간에 메시지 전달 시스템을 구현하려고 시도하지 말고 대신 메시지 전달, RPC 또는 메시지 큐 메커니즘을 수행하여 의심 할 여지없이 REST의 이점을 잃어 버릴 것입니다. http 연결을 통해 실제로 잘 작동하도록하는 단순성).

완전한 기능을 갖춘 복잡한 메시징 프로토콜을 원한다면이를 구축하십시오 (웹을 통해 그렇게 할 수 있다면 REST가 그렇게 인기있는 이유가 있습니다). 그렇지 않으면 REST의 아키텍처 설계를 고수하십시오.

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