Spring Rest Controller: 从映射方法返回实体的正确方式?

huangapple go评论68阅读模式
英文:

Spring Rest Controller: Correct way to return entities from mapping methods?

问题

I have the following Rest Controller class that handles HTTP requests relating to my Client entity?

For context - a client (e.g. exercise client) can have one Trainer. But a Trainer can have many clients.

Am I returning the entities in the correct way from my controller? I am using the Spring ResponseEntity class to wrap the Client related responses. Is there any other controller implementations I am missing in order to improve this code? - i.e.

Controller:

@RestController
@RequestMapping(value = "/clients")
public class ClientController {

    private final ClientService clientService;

    public ClientController(ClientService clientService) {
        this.clientService = clientService;
    }

    @GetMapping("/{clientId}")
    ResponseEntity<Client> getClientById(@PathVariable long clientId) {
        Client Client = clientService.getClientById(clientId);
        return new ResponseEntity<>(Client, HttpStatus.OK);
    }

    @GetMapping("/trainer/{trainerId}")
    ResponseEntity<List<Client>> getClientsByTrainerId(@PathVariable long trainerId) {
        List<Client> clients = clientService.getClientsByTrainerId(trainerId);
        return new ResponseEntity<>(clients, HttpStatus.OK);
    }

    @PostMapping
    public ResponseEntity<Client> createClient(@RequestBody ClientDTO clientDTO) {
        Client newClient = clientService.createNewClient(clientDTO);
        return new ResponseEntity<>(newClient, HttpStatus.CREATED);
    }

    @PutMapping("/{clientId}")
    ResponseEntity<Client> updateClient(@PathVariable Long clientId, @RequestBody ClientDTO clientDTO) {
        Client editedClient = clientService.editClient(clientId, clientDTO);
        return new ResponseEntity<>(editedClient, HttpStatus.OK);
    }
}

**Edit: Add Delete method**

```java
@DeleteMapping("/{clientId}")
long deleteClient(@PathVariable long clientId) {
    clientService.deleteClient(clientId);
    return clientId;
}
英文:

I have the following Rest Controller class that handles HTTP requests relating to my Client entity?

For context - a client (e.g. exercise client) can have one Trainer. But a Trainer can have many clients.

Am I returning the entities in the correct way from my controller? I am using the Spring ResponseEntity class to wrap the Client related responses.Is there any other controller implementations I am missing in order to improve this code? - i.e.

Controller:

@RestController
@RequestMapping(value = &quot;/clients&quot;)
public class ClientController {
private final ClientService clientService;
public ClientController(ClientService clientService) {
this.clientService = clientService;
}
@GetMapping(&quot;/{clientId}&quot;)
ResponseEntity&lt;Client&gt; getClientById(@PathVariable long clientId) {
Client Client = clientService.getClientById(clientId);
return new ResponseEntity&lt;&gt;(Client, HttpStatus.OK);
}
@GetMapping(&quot;/trainer/{trainerId}&quot;)
ResponseEntity&lt;List&lt;Client&gt;&gt; getClientsByTrainerId(@PathVariable long trainerId) {
List&lt;Client&gt; clients = clientService.getClientsByTrainerId(trainerId);
return new ResponseEntity&lt;&gt;(clients, HttpStatus.OK);
}
@PostMapping
public ResponseEntity&lt;Client&gt; createClient(@RequestBody ClientDTO clientDTO) {
Client newClient = clientService.createNewClient(clientDTO);
return new ResponseEntity&lt;&gt;(newClient, HttpStatus.CREATED);
}
@PutMapping(&quot;/{clientId}&quot;)
ResponseEntity&lt;Client&gt; updateClient(@PathVariable Long clientId, @RequestBody ClientDTO clientDTO) {
Client editedClient = clientService.editClient(clientId, clientDTO);
return new ResponseEntity&lt;&gt;(editedClient, HttpStatus.OK);
}
}

Edit: Add Delete method

@DeleteMapping(&quot;/{clientId}&quot;)
long deleteClient(@PathVariable long clientId) {
clientService.deleteClient(clientId);
return clientId;
}

答案1

得分: 3

在上面的代码中,没有必要将返回类型设为ResponseEntity&lt;&gt;。你可以声明控制器方法返回任何类型的对象,Spring足够智能,会根据需要将你的预期返回类型包装在ResponseEntity中。

例如:

@GetMapping("/{clientId}")
Client getClientById(@PathVariable long clientId) {
    return clientService.getClientById(clientId);
}

如果你想返回除了200 OK之外的不同HTTP状态代码,你可以使用相应的注解。例如:

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Client createClient(@RequestBody ClientDTO clientDTO) {
    return clientService.createNewClient(clientDTO);
}

我唯一会让控制器方法返回ResponseEntitiy&lt;&gt;的情况是,如果方法中有根据某些条件返回不同响应类型(状态代码)的逻辑。

另外,通常不建议直接在API端点中返回实体。大多数情况下,你需要将实体类型转换为DTO类型,以将事物的公共表示与持久表示分开。DTO可以具有你想要向客户端公开的任何形状,并且可以独立于域或持久形式进行变化。起初,这可能看起来像是不必要的代码重复的形式;有时两者永远不会分歧或具有不同的结构、名称等。但许多时候经验教导我们,域/持久实体与API契约会以不同的方式演变。

英文:

There's no need in the code above for the return types to be ResponseEntity&lt;&gt;. You can declare controller methods to return any type of object, and Spring is smart enough to wrap your intended return type in a ResponseEntity as needed.

For example:

    @GetMapping(&quot;/{clientId}&quot;)
   Client getClientById(@PathVariable long clientId) {
        return clientService.getClientById(clientId);
   }

If you want to return a different HTTP status code besides 200 OK, you can use an annotation for that. For example:

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Client createClient(@RequestBody ClientDTO clientDTO) {
        return clientService.createNewClient(clientDTO);
    }

The only time I ever make controller methods return ResponseEntitiy&lt;&gt; is if I have logic in the method that returns different response types (status codes) based on some conditions.


As an aside, it's usually not a good idea to return your entities directly in API endpoints. Most of the time you're going to want to transform the entity types into DTO types, to separate the public representation of things from the persistent representations. The DTO can have whatever shape you want to expose to clients, and can vary independently from the domain or persistent form. At first this might seem like unnecessary form of code duplication; sometimes the two never diverge or have differing structure, names, etc. But many times experience has taught us that the domain/persistent entities evolve differenty from the API contract.

huangapple
  • 本文由 发表于 2023年3月7日 02:43:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75654656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定