在Spring Data REST中POSting@OneToMany子资源关联

目前我有一个使用Spring Data REST的Spring Boot应用程序。我有一个域实体,它与另一个域实体有关系。这些类的结构如下:Post@OneToManyComment

邮 编.java:

@Entity
public class Post {

    @Id
    @GeneratedValue
    private long id;
    private String author;
    private String content;
    private String title;

    @OneToMany
    private List<Comment> comments;

    // Standard getters and setters...
}

评论.java:

@Entity
public class Comment {

    @Id
    @GeneratedValue
    private long id;
    private String author;
    private String content;

    @ManyToOne
    private Post post;

    // Standard getters and setters...
}

他们的Spring Data REST JPA存储库是以下方面的基本实现:CrudRepository

PostRepository.java:

public interface PostRepository extends CrudRepository<Post, Long> { }

注释存储库.java:

public interface CommentRepository extends CrudRepository<Comment, Long> { }

应用程序入口点是一个标准的、简单的 Spring Boot 应用程序。一切都是配置库存。

应用.java

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

一切似乎都正常工作。当我运行应用程序时,一切似乎都正常工作。我可以发布一个新的Post对象,如下所示:http://localhost:8080/posts

身体:{"author":"testAuthor", "title":"test", "content":"hello world"}

结果位于 :http://localhost:8080/posts/1

{
    "author": "testAuthor",
    "content": "hello world",
    "title": "test",
    "_links": {
        "self": {
            "href": "http://localhost:8080/posts/1"
        },
        "comments": {
            "href": "http://localhost:8080/posts/1/comments"
        }
    }
}

但是,当我执行GET时,我得到了一个空对象,如果我尝试将注释发布到相同的URI,我得到一个HTTP 405方法不允许。http://localhost:8080/posts/1/comments{}

创建资源并将其与此关联的正确方法是什么?如果可能的话,我想避免直接POST。CommentPosthttp://localhost:8080/comments


答案 1

假设您已经发现了 post URI,从而发现了关联资源的 URI(被视为在下面),则通常会执行以下步骤:$association_uri

  1. 发现集合资源管理注释:

     curl -X GET http://localhost:8080
    
     200 OK
     { _links : {
         comments : { href : "…" },
         posts :  { href : "…" }
       }
     }
    
  2. 点击链接和您的数据到资源:commentsPOST

     curl -X POST -H "Content-Type: application/json" $url 
     { … // your payload // … }
    
     201 Created
     Location: $comment_url
    
  3. 通过向关联 URI 发出 a 来将评论分配给帖子。PUT

     curl -X PUT -H "Content-Type: text/uri-list" $association_url
     $comment_url
    
     204 No Content
    

请注意,在最后一步中,根据 text/uri-list 的规范,您可以提交多个 URI 来标识由换行符分隔的注释,以便一次分配多个注释。

关于一般设计决策的更多说明。帖子/评论示例通常是聚合的一个很好的例子,这意味着我会避免从到的反向引用,也可以完全避免。如果注释本身没有生命周期(它们通常不会在组合样式关系中),则更愿意直接以内联方式呈现注释,并且添加和删除注释的整个过程都可以通过使用JSON Patch来处理。Spring Data REST在即将推出的2.2版本的最新候选版本中添加了对此的支持。CommentPostCommentRepository


答案 2

您必须先发布评论,并在发布评论时创建关联帖子实体。

它应该看起来像下面这样:

http://{server:port}/comment METHOD:POST

{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}

它将完美地工作。


推荐