英文:
Java post request with nested objects
问题
我有一个名为Order
的对象,其中包含另一个名为Person
的对象以及其他属性。
我想知道通过POST请求创建订单的最佳解决方案是什么。
我脑海中的第一种方法是这样的:
@PostMapping("orders/create")
public void createOrder(@RequestBody Order order) {
orderRepository.save(order);
}
但我不喜欢这个解决方案的原因是客户端必须同时发送包含订单和人员所有信息的JSON字符串,就像这样:
{
"date": "2023-01-01",
"price": 10,
"person": {
"id": 1,
"name": "Foo",
...
}
}
我如何确保请求中传递的人员实际上是存在于我的数据库中的人员呢?
我能想到的第二种方法是这样的:
@PostMapping("orders/create/{personId}")
public void createOrder(@PathVariable Long personId, @RequestBody Order order) {
Person person = personRepository.findById(personId).orElseThrow();
order.setPerson(person);
orderRepository.save(order);
}
但这个解决方案需要一个像localhost:8080/orders/1
这样的POST请求,其中1是人员的ID,这太令人困惑了。
我无法理清思路,非常感谢任何见解。
英文:
I have an object Order
which contains another object Person
among other properties.
I'm wondering what is the best solution to create an order through a post request.
The first approach in my mind is something like this:
@PostMapping("orders/create")
public void createOrder(@RequestBody Order order) {
orderRepository.save(order);
}
but what I don't like about this solution is that the client has to send a json string with all the information about the order and the person at the same time, like this:
{
"date": 2023-01-01,
"price": 10,
"person": {
"id": 1,
"name": "Foo",
...
}
}
How can I also make sure that the person passed in the request is actually a person that exists in my database?
The second approach that I can think of is like this:
@PostMapping("orders/create/{personId}")
public void createOrder(@PathVariable Long personId, @RequestBody Order order) {
Person person = personRepository.findById(personId).orElseThrow();
order.setPerson(person);
orderRepository.save(order);
}
but this solution would require a post request like localhost:8080/orders/1
where 1 is the id of the person, which is horrible because it's too confusing.
I can't get my head around this, any insights are highly appreciated.
答案1
得分: 2
您说得对,将personId发送到订单API是没有意义的。由于您在RequestBody中传递了personId,您可以删除PathVariable并使用订单中的内容。
@PostMapping("orders/create")
public void createOrder(@RequestBody Order order) {
Person person = personRepository.findById(order.getPerson().getId()).orElseThrow();
order.setPerson(person);
orderRepository.save(order);
}
或者,如E-Riz的评论所指,如果Person是经过身份验证的用户,请从SecurityContext中获取他们并按其用户名查找。然后就无需将Person发送到订单中。
英文:
You're right, it doesn't make sense to send the personId to the order API. Since you're passing the personId in the RequestBody, just drop the PathVariable and use what's in the order.
@PostMapping("orders/create")
public void createOrder(@RequestBody Order order) {
Person person = personRepository.findById(order.getPerson().getId()).orElseThrow();
order.setPerson(person);
orderRepository.save(order);
}
Or, as the comment by E-Riz is eluding to, if the Person is the authenticated user, get them out of the SecurityContext and look them up by their username. Then there would be no need to send the Person in the Order.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论