优雅的代码赏心悦目,你的代码触目惊心。
当编写 Spring Boot
接口时,优雅和规范是至关重要的。一个良好设计的接口能够提高代码的可读性、可维护性和可扩展性,从而为整个应用程序的开发和维护带来便利。
在本文中,我们将探讨如何通过遵循最佳实践和设计原则,编写出优雅规范的 Spring Boot
你的接口也可以像企业级项目接口一般规范且优雅。
RESTful API
设计原则API
管理的资源的名词(例如,/articles、/users
)。@GetMapping("/articles/{id}")
public ResponseEntity<Product> getArticleById(@PathVariable Long id) {
// ...
}
HTTP
方法:遵循 CRUD
操作的 RESTful
约定(CREATE: POST、READ: GET、UPDATE: PUT、DELETE:DELETE
)。@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
// ...
}
HTTP
状态代码,如成功 (2xx
)、错误 (4xx
) 或服务器问题 (5xx
)。@DeleteMapping("/articles/{id}")
public ResponseEntity<?> deleteArticle(@PathVariable Long id) {
if (productService.deleteArticle(id)) {
return ResponseEntity.noContent().build(); // 204 No Content
} else {
return ResponseEntity.notFound().build(); // 404 Not Found
}
}
关于更多restful
标准,参考https://en.wikipedia.org/wiki/REST
这里所谓得合理,不是很好定义,但本着高效、简洁、清晰得原则推荐。
@RestController
:默认情况下,将控制器标记为返回 JSON
或其他结构化数据。这是一个综合注解,是
@Controller
和@ResponseBody
的功能于一身,一个注解作两个注解的事情,简洁高效。
@RestController
public class HelloController {
// .....
}
@RequestMapping
:定义每个controller
的基本路径。这样做可以使代码更加整洁和易于维护。不需要在每个方法上都重复写基本路径部分,在类级别定义基本路径可以带来更清晰、更简洁、更易维护的代码结构,同时也有助于提高开发效率和代码质量。
@RestController
@RequestMapping("/user")
public class HelloController {
// .....
}
在不同类型的方法上直接使用
@GetMapping、@PostMapping、@PutMapping@DeleteMapping
注解进行标识,而不是使用笼统的@RequestMapping(method = RequestMethod.POST)
。
@PathVariable
获取请求的路径变量;@RestController
@RequestMapping("/articles")
public class ArticleController {
@GetMapping("/{id}")
public ResponseEntity<Article> getArticleById(@PathVariable Long id) {
// 根据文章的id查询文章
Article article = articleService.findArticleById(id);
if (article != null) {
return ResponseEntity.ok(article);
} else {
return ResponseEntity.notFound().build();
}
}
}
@RequestBody
将请求正文内容反序列化为 Java 对象。@RestController
@RequestMapping("/api")
public class UserController {
@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
// 这里的 User 对象会从请求的 JSON 数据中反序列化得到
userService.saveUser(user);
return ResponseEntity.ok(user);
}
}
通过在类的构造函数中接受依赖对象作为参数来进行注入。这种方式可以确保依赖在对象创建时被注入,提高了代码的可测试性和可维护性。
@RestController
public class ProductController {
private final ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
// ... other controller methods
}
@ControllerAdvice
的使用@ControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(ArticleNotFoundException.class)
public ResponseEntity<ErrorResponse> handleArticleNotFound(ArticleNotFoundException ex) {
// ... create error response with details
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
}
}
DTO
代替POJO
的直接使用对于数据传输对象,建议对
pojo
进行dto
的封装,而不是使用原实体。提高代码的可读性、可维护性和数据封装性。
public class ArticleDto {
private Long id;
private String title;
private String contents;
// more
}
SpringSecurity
等安全框架进行认证授权,包括令牌机制的使用,如JWT
。XSS
和SQL
注入等。https
进行网络通信;/api/v1/articles
)或基于标头的版本控制。使用版本控制
API
来管理更改并保持与客户端的兼容性。
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping("/details")
public ResponseEntity<String> getProductDetails(@RequestHeader("Accept-Version") String version) {
if ("v1".equals(version)) {
return ResponseEntity.ok("Product details for version 1");
} else if ("v2".equals(version)) {
return ResponseEntity.ok("Product details for version 2");
} else {
return ResponseEntity.badRequest().body("Unsupported version");
}
}
}
Mockito
或 JUnit
等工具对每个接口进行测试,保证接口的准确性和稳健性。上面虽然列举好几种编写接口的规范和建议,但这些不是一成不变的,在具体的项目,还需要根据业务和项目需求做出一些让步和改动,灵活运用这些建议,你的接口也可以很优雅。代码就是一行行蓝色的诗,而不是冰冷乏味的英文串。