๐ Controller Annotation
Annotation | ์์ญ | Description |
@RestController | Class | Spring์ ์ปดํฌ๋ํธ ์ค์บ ๋์์ด ๋๋๋ก ํ๊ณ HTTP ์์ฒญ๊ณผ ์๋ต์ ์๋์ผ๋ก ๋งคํ๋๋๋ก ํ๋ ๋ฑ Spring์์ Controller๋ก ๋์ํ ์ ์๋๋ก ๊ธฐ๋ณธ์ ์ธ ๋์์ ๋ด๊ณ ์๋ ์ด๋
ธํ
์ด์
์
๋๋ค. @Controller์ @RequestBody๊ฐ ํฉ์ณ์ง ์ด๋ ธํ ์ด์ ์ผ๋ก RESTful ์น ์๋น์ค์์ ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. |
@RequiredArgsConstructor | Class | Spring 4.3๋ถํฐ๋ @Autowired๋ฅผ ํตํ ์์กด์ฑ ์ฃผ์
๋ณด๋ค ์์ฑ์๋ฅผ ํตํ ์์กด์ฑ ์ฃผ์
์ ๊ถ์ฅํ๊ณ ์์ต๋๋ค. @RequiredArgsConstructor๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑ์ ์ฝ๋๋ฅผ ๋ฐ๋ก ์ ์ง ์์๋ ๋ฉ๋๋ค. 'private final Service service'์ ๊ฐ์ด ์ฌ์ฉ๋ฉ๋๋ค. |
@RequestMapping | Class | ํจ์ ๋ ๋ฒจ์ ์ฌ์ฉํ ์ ์์ง๋ง ํจ์ ๋ ๋ฒจ์๋ @GetMapping๊ณผ ๊ฐ์ HTTP ๋ฉ์๋ ๋ ๋ฒจ์ ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๊ณ ํด๋์ค ๋ ๋ฒจ์๋ @RequestMapping์ ์ฌ์ฉํฉ๋๋ค. Controller์ ํฌํจ๋ ๋ชจ๋ ํจ์์ ๊ณตํต ์ ์ฉํ ๊ณตํต ๊ฒฝ๋ก์ ๊ฐ์ ๋ด์ฉ์ ์ ์ต๋๋ค. |
@Api, @Tag | Class | Swagger๋ฅผ ์ฌ์ฉํ ๋ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค. |
@ApiOperation, @Operation | Method | Swagger๋ฅผ ์ฌ์ฉํ ๋ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค. |
@GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping |
Method | @RequestMapping์ ํ์ ์ด๋
ธํ
์ด์
์ผ๋ก ๊ฐ ํจ์๋ง๋ค ์ฌ์ฉํ๋ HTTP ๋ฉ์๋์ ๋ฐ๋ผ ์ง์ ํด์ ์ฌ์ฉํฉ๋๋ค. path : ๊ฐ API์ ํ์ ๊ฒฝ๋ก produces, consumes : ์์ฒญ๊ณผ ์๋ต์ ํ์์ ์ง์ ํ ๋ ์ฌ์ฉํฉ๋๋ค. ์ฃผ๋ก JSON ํํ๋ก ํต์ ํ๊ธฐ ๋๋ฌธ์ 'MediaType.APPLICATION_JSON_VALUE'๋ฅผ ์ฌ์ฉํฉ๋๋ค. |
@PathVariable | Param | Method : 'GET' URL ๊ฒฝ๋ก์์ ๋ณ์๋ฅผ ์ถ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ฃผ๋ก RESTful ์น ์๋น์ค์์ ๊ฒฝ๋ก ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ๋ ๋ฐ ์ฐ์ ๋๋ค. '/products/{id}'์ ๊ฐ์ ๊ฒฝ๋ก์์ id๋ฅผ ์ถ์ถํ ๋ ์ฌ์ฉํฉ๋๋ค. |
@RequestParam | Param | Method : 'GET' ์์ฒญ์ ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์(ํ๋ผ๋ฏธํฐ)๋ฅผ ์ถ์ถํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. URL์ ? ๋ค์ ์ค๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ฝ์ด์ต๋๋ค. ์ฟผ๋ฆฌ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ ๋ ์ฌ์ฉํฉ๋๋ค. '/products?id=123'์ ๊ฐ์ด URL์์ id๋ฅผ ์ถ์ถํ ๋ ์ฌ์ฉํฉ๋๋ค. ์ ๋ฌ๋๋ ํ๋ผ๋ฏธํฐ๊ฐ ๋ง์ ๊ฒฝ์ฐ VO ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋์ค ๋ด ํ๋์ ์๋์ผ๋ก ๋งตํํด์ค๋๋ค. (๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ) 'POST', 'PUT', 'PATCH'์๋ Request๊ฐ form ๋ฐ์ดํฐ ํ์์ผ๋ก ์จ๋ค๋ฉด (URL ๋ค์ Query String ํํ๋ก ์จ๋ค๋ฉด) ์ฌ์ฉํ ์ ์์ง๋ง JSON ํํ๋ ์์ฉํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ฃผ๋ก 'GET'์์๋ง ์ฌ์ฉํฉ๋๋ค.) |
@RequestBody | Param | Method : 'POST', 'PUT', 'PATCH' HTTP ์์ฒญ์ ๋ณธ๋ฌธ(body) ๋ถ๋ถ์ ํน์ ์๋ฐ ๊ฐ์ฒด๋ก ๋งคํํ๋๋ก ์ง์ํฉ๋๋ค. ์ฃผ๋ก POST๋ PUT ์์ฒญ๊ณผ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ, ํด๋ผ์ด์ธํธ๊ฐ JSON ๋๋ XML ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. - ์๋ฅผ ๋ค์ด, ํด๋ผ์ด์ธํธ๊ฐ JSON์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ ์ด๋ฅผ ์๋ฐ ๊ฐ์ฒด๋ก ๋ณํํ๋ ค๋ฉด @RequestBody๋ฅผ ์ฌ์ฉํฉ๋๋ค |
@Valid | Param | ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ํ ๋ ๊ฐ์ฒด์ ์ ํจ์ฑ์ ๊ฒ์ฌํฉ๋๋ค. @NotNull, @NotEmpty, @Size, @Pattern์ ๊ฐ์ Hibernate Validator๋ก ์ ์๋ ์ด๋ ธํ ์ด์ ๊ณผ ๊ฐ์ด ์ฌ์ฉ๋ฉ๋๋ค. VO ํด๋์ค๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ๊ฐ ํ๋์ ํ์ํ ์ ํจ์ฑ ๊ฒ์ฌ ์ด๋ ธํ ์ด์ ์ ๋ถ์ฌ์ ์์ฒญ์ ์์ฝ๊ฒ ํํฐ๋งํ ์ ์์ต๋๋ค. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @RestController @RequestMapping("/vl") @Api(tags = {"Simple"}) @RequiredArgsConstructor public class SimpleController { private final SimpleService simpleService; @ApiOperation(value = "", httpMethod = "GET", notes = "") @GetMapping(path = "/simple", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<CommonResponseVO> method(@Valid SimpleRequestVO, simpleRequestVO){ return ResponseUtil.createSuccessResponse(simpleService.method(simpleRequestVO)); } } | cs |
๐ Service Annotation
Annotation | ์์ญ | Description |
@Service | Class | @Controller์ ๋น์ทํ ์ญํ ์ ํฉ๋๋ค. ์ปดํฌ๋ํธ ์ค์บ ๋์์ด ๋๊ณ Spring Container์ Bean์ผ๋ก ๋ฑ๋ก๋ฉ๋๋ค. ํด๋น ํด๋์ค๊ฐ ๋น์ง๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ Service ํด๋์ค๋ผ๋ ๊ฒ์ ๋ํ๋ด๊ธฐ๋ ํฉ๋๋ค. |
@RequiredArgsConstructor | Class | Controller์์ ์ฌ์ฉ๋๋ ์ด์ ์ ๊ฐ์ต๋๋ค. ์์ฑ์ ์์กด์ฑ ์ฃผ์
์ ์ํด์ ์ฌ์ฉ๋๋ฉฐ 'private final Repository repository'์ ๊ฐ์ด ์ฌ์ฉ๋ฉ๋๋ค. |
@Transactional | Method | DB์ ํธ๋์ญ์
์ ๋ง๋ค๊ณ ๊ด๋ฆฌํ๊ธฐ ์ํด์ ์ฌ์ฉํฉ๋๋ค. ๋จ์ํ @Transactional๋ง ์ ์ด์ฃผ๋ฉด ์คํ๋๋ ํจ์๊ฐ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๋ฌถ์ฌ์ ์ค๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด DB์ Rollback์ ์คํํฉ๋๋ค. readOnly, rollbackFor, noRollbackFor, propagation, isolation, timeout์ ๊ฐ์ ์ต์ ์ผ๋ก ํธ๋์ญ์ ์ ๋๋ ์ ์์ต๋๋ค. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Service @RequiredArgsConstructor public class Service { private final Repository repository; private final SecondService secondService; @Transactional @HystrixCommand(fallbackMethod = "fallbackService") public PaginationResponseVO method(RequestVO requestVO) { ... return new PaginationResponseVO(); } public PaginationResponseVO fallbackService(RequestVO requestVO) { return secondService.method(requestVO); } } | cs |
๐ Model Annotation
๐@NoArgsConstrutor, @AllArgsConstrutor, @RequiredArgsConstructor ์ฌ์ฉ ์ฌ๋ถ๋ ํ์์ธ์ง ์๋์ง ํ์ธ์ด ๋ ํ์!
Annotation | ์์ญ | Description |
@NoArgsConstrutor @AllArgsConstrutor (access = AccessLevel.PRIVATE) |
Class | ๊ธฐ๋ณธ ์์ฑ์์ ๋ชจ๋ ํ๋๋ฅผ ํฌํจํ ์์ฑ์๋ฅผ ์๋์ผ๋ก ์์ฑํด์ค๋๋ค. ํ๋๊ฐ ๋ง์ ๊ฒฝ์ฐ ์์ฑ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด ํ๋ ์์์ ํ์ ์ ๋ชจ๋ ๋ง์ถฐ์ค์ผ ํ๊ธฐ ๋๋ฌธ์ ํด๋จผ์๋ฌ๋ฅผ ๋ง๋ค์ด๋ผ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๊ฒ ๋ฉ๋๋ค. ๋ฐ๋ผ์ VO๋ Builder๋ก ์์ฑํ๋ ๊ฒ์ ์ถ์ฒํ๋ฉฐ ์ธ๋ถ์์ ์์ฑ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก AccessLevel์ ์ค์ ํ๊ธฐ๋ ํฉ๋๋ค.
|
@Data | Class | @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor ๋ฅผ ํฉ์น Annotation @RequiredArgsConstructor์ ์ด๊ธฐํ ๋์ง ์์ ๋ชจ๋ final ํ๋, @NonNull๊ณผ ๊ฐ์ด ์ ์ฝ์กฐ๊ฑด์ด ์ค์ ๋์ด์๋ ๋ชจ๋ ํ๋๋ค์ ๋ํ ์์ฑ์๋ฅผ ์๋์ผ๋ก ์์ฑํ๋ค. |
@Builder | Class | Builder ํจํด์ ์๋์ผ๋ก ์์ฑํด์ค๋๋ค. |
@SuperBuilder | Class | VO๋ฅผ ์์ ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ถ๋ชจ์ ํ๋๋ฅผ Builder์์ ์ฌ์ฉํ ์ ์๋๋ก ํด์ค๋๋ค. |
@Builder.Default | Field | Builder๋ก ์์ฑํ ๋ ๊ธฐ๋ณธ๊ฐ์ ์ง์ ํด์ฃผ๊ธฐ ์ํด์ ์ฌ์ฉํฉ๋๋ค. |
@ApiModelProperty | Field | Swagger๋ฅผ ์ฌ์ฉํ ๋ ์ฌ์ฉํ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค. |
@Min(1) @Max(50) |
Field | @Vaild์ ๊ฐ์ด ์ฌ์ฉ๋๋ฉฐ VO ์์ ์๋ ํ๋ ๊ฐ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํด์ค๋๋ค. @Min, @Max ์ด์ธ์๋ @Positive, @PositiveOrZero ๋ฑ ์ฌ๋ฌ ์ข ๋ฅ์ Annotation์ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
@NotNull @NotEmpty @NotBlank |
Field | Null ์ฌ๋ถ ์ฒดํฌ Null ์ฌ๋ถ ์ฒดํฌ, ๋น ๋ฌธ์์ด(""), ๋น ๊ฐ์ฒด(List) ์ฒดํฌ Null ์ฌ๋ถ ์ฒดํฌ, ๋น ๋ฌธ์์ด(""), ๋น ๊ฐ์ฒด(List) ์ฒดํฌ, ๊ณต๋ฐฑ ๋ฌธ์์ด(" ")์ธ์ง ์ฒดํฌ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | @Getter @ToString @SuperBuilder @NoArgsConstructor @AllArgsConstructor(access = AccessLevel.PRIVATE) @EqualsAndHashCode(callSuper = false) public class RequestVO extends PaginationRequestVO { @Builder.Default @Enum(enumClass = DefaultBlogSortType.class) @ApiModelProperty(value = "๋ธ๋ก๊ทธ๋ฅผ ์กฐํํ๋ ์ ๋ ฌ ๊ธฐ์ค (๊ธฐ๋ณธ๊ฐ: ACCURACY)", notes = "๋ธ๋ก๊ทธ ์กฐํ ์ ๋ ฌ ๊ธฐ์ค", example = "RECENCY", allowableValues = "ACCURACY, RECENCY") private String sortType = DefaultBlogSortType.ACCURACY.name(); @ApiModelProperty(value = "ํน์ ๋ธ๋ก๊ทธ URL", notes = "ํน์ ๋ธ๋ก๊ทธ ๊ธ๋ง ๊ฒ์ํ๊ณ ์ถ์ ๊ฒฝ์ฐ") private String blogUrl; @ApiModelProperty(value = "๋ธ๋ก๊ทธ๋ฅผ ๊ฒ์ํ๋ ๊ธฐ์ค ํค์๋", notes = "๋ธ๋ก๊ทธ ๊ฒ์ ํค์๋", required = true) @NotEmpty private String keyword; @Min(1) @Max(50) @Builder.Default @ApiModelProperty(value = "Page ๋จ์๋ก ์กฐํ ์ ํ ๋ฒ์ ๊ฐ์ ธ์ฌ Page์ ํฌ๊ธฐ (๊ธฐ๋ณธ๊ฐ: 10)", notes = "1~50 ์ฌ์ด์ ์ ์", example = "10") private Integer pageSize = 10; @Min(1) @Max(50) @Builder.Default @ApiModelProperty(value = "Page ๋จ์๋ก ์กฐํ ์ ๋ฐ์ดํฐ ์กฐํ ์์ ๊ฑด ์ (๊ธฐ๋ณธ๊ฐ: 1)", notes = "1~50 ์ฌ์ด์ ์ ์", example = "1") private Integer start = 1; public GetVO toGetVO() { String query = ObjectUtils.isEmpty(blogUrl) ? keyword : blogUrl + " " + keyword; String sort = sortType.toLowerCase(); return GetVO.builder() .query(query) .sort(sort) .page(this.start) .size(this.pageSize) .build(); } } | cs |
๋ฐ์ํ