使用外键保存对象的专业/标准方法是什么?

时间:2017-09-14 09:40:55

标签: rest spring-mvc spring-4

我正在使用Spring-mvc开发一个简单的字典RESTful API。有两个相关的实体:

public class Word {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  private String word;

  @ManyToOne(fetch=FetchType.EAGER)
  @JoinColumn(name="LANGUAGE_ID", insertable=false, updatable=false)
  private Language language;

}

根据上述代码,相关实体为Language

问题:我想用POST请求在Word实体上实现CREATE操作。实现并不困难,但我确实找到了至少两个与POST请求URL和JSON请求体相关的候选解决方案:

解决方案Candicate I :直接插入JSON正文请求。 JSON主体包含嵌套的JSON对象 - 语言,类似于

{id:1, word:"hello", Language: {id:1, language:"English"}}

参考:Spring: Save object with foreign keys with a POST request

Solution Candidate II :通过POST请求网址获取引用的语言ID,例如

POST http://localhost:8080/rest/language/1/words

因此,JSON POST请求正文中根本没有Language引用。

参考:https://www.youtube.com/watch?v=_Jnu_jHfQbM

我有两个问题:

问题1 :在这两个候选解决方案中,哪个更好,或者说专业标准解决方案?或者还有其他解决方案吗?

问题2 :对于给定的候选解决方案,在任何情况下,我们都需要至少在相应的Language类中检索引用的controller POJO。但是从OO设计原则的角度来看,这种方式似乎与控制器紧密耦合,所以我认为我们应该将这种检索行为与控制器中的其他地方解耦吗?例如在service层中。但这是专业的方式吗?我们需要有一个相应的DTO?

2 个答案:

答案 0 :(得分:0)

在我看来,应该保存的数据必须嵌套在正文中。 Spring可以将json数据直接映射到对象中,您不必将其从参数设置为另一个模型类。

我会为你的实体创建单独的模型类。因此,控制器将数据填充到模型类并将它们提供给服务。然后,服务将模型类映射到实体。之后,他们可以通过存储库存储。

示例:

<?php
$a=$_SERVER['REQUEST_URI'];
if(strpos($a,'/category/catalog/'))
{
str_replace("/category/catalog/","/catalog/?_category=",$a);
echo '<script type="text/javascript">window.location=\''.$a.'\';</script>';
}
?>

答案 1 :(得分:0)

假设单词属于语言,我会将其设计如下:

POST /api/languages/en/words HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
  "word": "hello"
}

在请求有效负载中将表示单词(例如JSON文档)发送到表示层次结构的URL(语言具有单词

您还可以使用two-letter codes来识别语言,因为它比数值更清晰。在上面的示例中,en表示英语

我建议您避免在REST API和use DTOs中暴露持久性实体。您的REST资源表示不需要与持久性对象具有相同的属性。

让您的REST控制器尽可能精简,并使您的服务层专注于业务规则。