0

DDD의 원칙에 따라 스프링 데이터 REST/HATEOAS를 사용하면 하위 컬렉션에서 엔티티를 조작하는 가장 좋은 방법은 무엇입니까? 예를 들어스프링 데이터 REST - 애그리 게이션 컬렉션의 엔티티를 업데이트하는 방법

: JSON으로 직렬화 할 때 자신의 저장소가없는

@Entity 
public class Topic{ 

    @Id @GeneratedValue 
    private Long id; 
    private String title; 

    @OneToMany 
    private Set<Post> posts; 
    … 
} 

@Entity 
public class Post{ 

    @Id @GeneratedValue 
    private Long id; 
    private String title; 
    private String body; 

    @OneToMany 
    private Set<Comment> comment; 
    … 
} 

@Entity 
public class Comment{ 

    @Id @GeneratedValue 
    private Long id; 

    private String text; 

} 

봄 데이터 REST (SDR) 인라인 도메인 오브젝트.

{ 
    "title" : "Spring", 
    "posts" : [{ 
    "title": "Spring Boot 1.5.8", 
    "body": "blah", 
    "comments":[ {"text":"great!"} , {"text":"boo"}, 
     {"text":"comment that should be removed by moderators"}] 
    }] 
    "_links" : { 
    "self" : { 
     "href" : "http://localhost:8080/topics/1" 
    } 
    } 
} 

내가 가진 문제는 SDR뿐만 아니라 인라인 개체에 대한 '자기'링크를 제공하지 않는 모든 엔티티 ID를 숨 깁니다 때문이 아니라 내가 컬렉션의 개별 개체에 대한 핸들을 얻을 수 없습니다 생각이다.

DDD로 인라인하기 때문에 전용 '컨트롤러'리소스를 통해 상태 변경 사항을 처리하여 이벤트를 발생시켜 추가 비즈니스 논리를 트리거 할 수 있기 때문에 전체 집계를 간단하게 처리하고 싶지는 않습니다. 위의 예에서 게시물 덧글을 추가/제거/업데이트하는 것을 고려하십시오.

나는 정말 좋아하지 않는 옵션이 많이 남았습니다. 역

  1. 효과적으로 DDD 집계 디자인 개념을 포기하고 모든 하위 개체에 대한 내 모든 단방향 관계를 만들 저장소.

  2. 양방향 관계로 이동하여 모든 하위 엔터티에 대한 저장소를 만들고 프로젝션을 사용하여 집계를 작성하십시오. 인터넷 (SDR 개발자 Oliver Gierke 포함)의 일반적인 조언은 성능 고려 사항과 수동으로 관계를 관리해야하기 때문에 가능하면 양방향 관계를 피하는 것입니다.

  3. 자식 엔터티에 GUID 또는 다른 불변의 고유 식별자를 추가하십시오. HATEOAS의 전체적인 점은 URI가 식별자라는 점을 감안할 때 이것은 잘못된 것입니다. 심지어 이것은 어린이의 자녀를 다룰 때 부서집니다. 나를 설계 원칙을 유지할 수있는 유일한 실행 가능한 옵션이 될 것 같은

는 나는 현재 2쪽으로 기울어 느끼고있다.

누구나 비슷한 문제가 발생 했습니까?

편집 : 나는 가능한 해결책을 마련했습니다

: 아이 엔티티 저장소를 만들지 않고 양방향 관계

이동합니다. 이것은 내가 부모 키를 줄 수 있도록 RestController를 통해 처리 할 수있는/topics/1/posts/add-post와 같은 ResourceProcessor를 사용하여 다른 링크를 '자기'로 구성 할 수있게합니다. & 이것은 1 단계 깊이에서 충분히 잘 작동해야하며, 더 깊은 중첩을 위해 성능에 영향을 줄 수 있습니다./topics/1/posts/1/comments/add-comment를 사용하면 JPA와 마찬가지로 부모 관계를 탐색하기 위해 조회를 수행하는 것과 관련된 비용이 발생할 것입니다. 이것은 @Alan Hay의 해답 인 Id와 자연스러운 키가 존재하지 않는 Id의 해법과 함께 수행됩니다.

이 접근법은 DDD & HATEOAS를 양방향 관계에 대한 조언을 무시하는 비용으로 유지합니다.

생각하십니까?

+1

내부 Comment 개체의 행동의 링크를 얻어야한다

@Bean public ResourceProcessor<Resource<Comment>> commentProcessor() { return new ResourceProcessor<Resource<Comment>>() { @Override public Resource<Comment> process(Resource<Comment> resource) { resource.add(linkTo(methodOn(MyCustomController.class).deleteComment(resource.getContent().getId())).withRel("deleteComment")); return resource; } }; } 

개체 ID를 노출 할 수 있습니다 필요한 경우. https://stackoverflow.com/questions/34973156/how-to-expose-the-resourceid-with-spring-data-rest –

+0

자식 컬렉션을 인라이닝 할 때 기본 동작이어야한다고 생각합니다. 링크를 제공하거나 제공합니다. 아이 시나리오의 아이에게 이드를 드러내는 단점은 URI가 하이퍼 미디어 원칙을 어기는 것을 구성하기 위해 클라이언트에게 다시 책임을 묻는 것입니다. –

+0

어디로 연결 되나요? 그것들은 휴식 자원으로 드러나지 않기 때문에 줄 지어 있습니다. 그래서이 링크가 어디를 가리킬 지 확신하지 못합니다. –

답변

0

리포지토리를 통해 매핑되지 않은 리소스에 _links을 추가 할 수 있습니다. 액션 deleteComment을 추가하려면, 예를 들어,이 같은 @Bean를 구성해야합니다 : 당신은 Post

관련 문제