在 For Get 和 POST 中重用相同的域对象

Posted

技术标签:

【中文标题】在 For Get 和 POST 中重用相同的域对象【英文标题】:Reusing the same Domain Object in For Get and POST 【发布时间】:2018-09-14 09:37:01 【问题描述】:

假设我有一个学生对象

public class Student
private long id;
private string name;
private List<string> courses

在典型的 Get 请求中,为了获取学生,我将 Student 对象发送到客户端。

在通过添加或删除课程来修改学生对象的 PUT 请求或创建学生记录的 POST 请求的情况下,我只需要从客户端接收 student.id 和课程列表。

我的问题是,我可以在 PUT 或 POST 请求中从客户端发回相同的 Student 对象,而不包括名称或 name=null 吗? 或者我应该创建一个单独的域对象,例如由客户端发送:

    public class StudentReponse

       private long id;
       private List<string> courses;

我想我的一般问题是,我们应该在 Rest API 中分离请求和响应对象吗?还是为了代码的可重用性尝试在两个方向上使用相同的域对象?

【问题讨论】:

你必须把它们分开! 【参考方案1】:

我们应该在 Rest API 中分离 Request 和 response 对象吗?

是的 - 它允许独立地发展请求和响应。 如果在发出创建时遵循 REST 实践,则应返回 201 - created 和新创建对象的 ID。

如果客户端需要有关它的详细信息,客户端可以使用 ID + GET 来获取完整的资源表示。

同时考虑不要直接通过 REST 公开域对象。 例如,拥有一个域实体对象——它可能会有一些与持久层相关的字段,如数据库 ID、createdOn、createdBy 等。这些字段不应发送给客户端。使用简单的 StudentDto(StudentResponse,StudentResponseDto 随便你怎么称呼它)表示,它只包含客户感兴趣的那些字段。

保持域和响应对象分开还使您能够单独发展它们或更改数据表示。 想象一下,您有一个 JPA 实体,并且在同一个类中同时使用了 JPA 和 Jackson 注释 - 它非常混乱且难以阅读和维护。

更新:

如果您使用相同的对象由客户端修改并发送回服务器,我想您可以重用它并像这样建模:

获取

@GetMapping("/students/id")
public StudentDto getStudent(@PathVariable long id) 
    return studentService.get(id);

更新(替换)

@PutMapping("/students/id/")
public ResponseEntity updateStudent(@PathVariable long id, @RequestBody StudentDto student) 
    return new ResponseEntity(studentService.replaceStudent(id, student), HttpStatus.OK);

更新(部分更新)

@PostMapping("/students/id/")
public ResponseEntity updateStudent(@PathVariable long id, @RequestBody StudentDto student) 
    return new ResponseEntity(studentService.updateStudent(id, student), HttpStatus.OK);

【讨论】:

我同意不公开实体对象。我正在考虑重新使用相同的 Dto,因为我们实际上是给客户端一个要修改并发送回服务器的对象。 @user955165 是的,我想你可以重复使用它 - 为了清楚起见,我添加了一个更新

以上是关于在 For Get 和 POST 中重用相同的域对象的主要内容,如果未能解决你的问题,请参考以下文章

GET 和 POST 请求的相同 Rails 4 路由

file_get_contents现在按预期工作 - 外部域工作相同的域没有

如何使用 ASP.NET 和 iframe 跨域对用户进行身份验证?

在 Laravel 中为 GET 和 POST 使用不同的控制器,但使用相同的名称

存储$ _GET并在POST请求中再次使用它

Django 创建多个 URL,为 POST 和 GET 调用相同的视图