0

DDDの原則に従って、Spring Data REST/HATEOASを使用して、子コレクションのエンティティを操作する最適な方法を教えてください。例えばSpring Data 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のインラインで、専用の「コントローラ」リソースを使用して状態の変更を処理し、イベントを発生させて追加のビジネスロジックをトリガーできるため、集約全体を単純にPUTする必要はありません。上記の例でコメントを追加/削除/更新することを検討してください。

私は本当に好きではない多くのオプションが残っています。

  1. すべての子エンティティのリバースをすべて作成し、DDD集約設計コンセプトを効果的に破棄します。

  2. すべての子エンティティのリポジトリを作成し、投影を使用して集計を作成します。インターネットからの一般的なアドバイス(SDRデベロッパーのOliver Gierkeを含む)は、パフォーマンス上の理由から可能な限り双方向の関係を避け、手動で関係を管理する必要があります。

  3. GUIDなどの不変の一意の識別子を子エンティティに追加します。 HATEOASの全体のポイントは、URIがのIDであることを考えると、間違っていると感じます。これは子供の子供たちを扱うときにも破壊されます。

私が設計原理を保持することを可能にする唯一の実行可能な選択肢であると考えられるように私は現在、2に向けて傾斜を感じています。

誰も遭遇して同様の問題を克服しましたか?

編集:私は可能な解決策を作ってみた

:子エンティティのためのリポジトリを作成することなく、双方向の関係に

移動します。これにより、私はRestControllerを介して処理できる/ topics/1/posts/add-postなどのResourceProcessorを使用して、自分自身で&という別のリンクを作成できるように、私に親の鍵を渡します。これは1レベルの深さで十分に機能するはずです。深い入れ子にはパフォーマンスに影響があります。/topics/1/posts/1/comments/add-comment JPAと同様に、親関係を調べるためのルックアップに関連するコストがかかるでしょう。これは、エンティティに自然なキーがないところでIdを公開する@Alan Hayのソリューションと並行して行われます。

このアプローチでは、DDD & HATEOASは、双方向関係に関するアドバイスを犠牲にして管理しています。

思考?

+1

内側Commentオブジェクトに対するアクションのリンクを取得する必要がありますもし必要なら。 https://stackoverflow.com/questions/34973156/how-to-expose-the-resourceid-with-spring-data-rest –

+0

私はこれが子コレクションをインライン展開するときのデフォルト動作であるべきだと思います。子供のシナリオの子供にIDを公開することの欠点は、URIがハイパーメディアの原則を破るように構成するためにクライアントに負担をかけることだけです。 –

+0

どこへのリンク?彼らは休憩のリソースとして公開されていないのでインライン展開されているので、このリンクがどこを指しているのか分かりません。 –

答えて

0

_linksを、リポジトリを介してマッピングされていないリソースに追加することは可能です。アクションdeleteCommentを追加するには、例えば、次のような@Beanを構成する必要があります。

@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; 
     } 
    }; 
} 

あなたは実体のIdsを露出させることができるPost

関連する問題