我正在使用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?
答案 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控制器尽可能精简,并使您的服务层专注于业务规则。