[JSCODE] 5ํšŒ์ฐจ

Hanjmoยท2023๋…„ 5์›” 24์ผ
0

๐ŸŽฏ ๋ชฉํ‘œ

  • API ๋ฌธ์„œ ์ž‘์„ฑ

โœ๏ธ ๋‚ด์šฉ

1. ๊ฒŒ์‹œ๊ธ€ ์ „์ฒด ์กฐํšŒ, ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๋ถ„๋ฆฌ

์ด๋ฒˆ ๋ ˆ๋ฒจ ์š”๊ตฌ ์‚ฌํ•ญ์—์„œ ๊ฒŒ์‹œ๊ธ€ ์ „์ฒด ์กฐํšŒ ๊ธฐ๋Šฅ๊ณผ ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์ด ๊ฐ๊ฐ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ๋ณด๊ณ  ๋‘ ๊ธฐ๋Šฅ์˜ api๋ฅผ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค.

public List<Post> findAllPost() {
	return postRepository.findAll();
}

public List<Post> findAllPostByTitle(String keyword) {
	if (keyword.length() < 1) {
		throw new PostException(ErrorCode.BAD_REQUEST);
	}
	PostSearch postSearch = new PostSearch(keyword);
	return postRepository.findAllByTitle(postSearch);
}

2. ํˆด ์„ ํƒ

์ฐพ์•„๋ณด๋‹ˆ API ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ํˆด์ด ๊ฝค ๋งŽ์•˜๋‹ค.
Swagger, Notion, Postman ์ค‘์—์„œ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ Swagger๋ฅผ ์„ ํƒํ–ˆ๋‹ค.
๊ทธ ์ด์œ ๋Š” Notion์˜ ๊ฒฝ์šฐ API ์ŠคํŽ™์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ง์ ‘ ๋ชจ๋‘ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ท€์ฐฎ์•„์งˆ ๊ฒƒ ๊ฐ™์•„ ์ œ์™ธํ–ˆ๊ณ , Postman์€ ์–ด๋Š์ •๋„ ์ž๋™ํ™” ํ•ด์ฃผ๊ธด ํ•˜์ง€๋งŒ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ง์ ‘ ์ž‘์„ฑํ•  ๋ถ€๋ถ„์ด ๊ฝค ์กด์žฌํ–ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ž๋™์œผ๋กœ ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋Š” Swagger๋ฅผ ํƒํ–ˆ๋‹ค.
๋ฌด์—‡๋ณด๋‹ค ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ทธ๋งŒํ•œ ์ด์œ ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

3. ์˜์กด์„ฑ ์ถ”๊ฐ€

์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ build.gradle ํŒŒ์ผ์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค.

implementation 'io.springfox:springfox-boot-starter:3.0.0'
implementation 'io.springfox:springfox-swagger-ui:3.0.0'

4. SwaggerConfig ์ถ”๊ฐ€

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .useDefaultResponseMessages(true) // Swagger ์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ธฐ๋ณธ ์‘๋‹ต ์ฝ”๋“œ๋ฅผ ํ‘œ์‹œํ•  ๊ฒƒ์ด๋ฉด true
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("jscode.jscodestudy")) // Controller๊ฐ€ ๋“ค์–ด์žˆ๋Š” ํŒจํ‚ค์ง€. ์ด ๊ฒฝ๋กœ์˜ ํ•˜์œ„์— ์žˆ๋Š” api๋งŒ ํ‘œ์‹œ๋จ.
                .paths(PathSelectors.any()) // ์œ„ ํŒจํ‚ค์ง€ ์•ˆ์˜ api ์ค‘ ์ง€์ •๋œ path๋งŒ ๋ณด์—ฌ์คŒ. (any()๋กœ ์„ค์ • ์‹œ ๋ชจ๋“  api๊ฐ€ ๋ณด์—ฌ์ง)
                .build();
    }

    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SpringBoot Rest API Documentation")
                .description("jscode ์Šคํ„ฐ๋””์—์„œ ์‚ฌ์šฉํ•˜๋Š” API ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค.")
                .version("0.1")
                .build();
    }
}

5. DTO์— Swagger ๊ด€๋ จ ์• ๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€

@Data
@ApiModel(value = "๊ฒŒ์‹œ๊ธ€ ์ •๋ณด")
public class PostDto {

    @ApiModelProperty(name = "id", value = "์•„์ด๋””", example = "1", required = true, dataType = "Long")
    private Long id;

    @NotBlank(message = "์ œ๋ชฉ์€ ๊ณต๋ฐฑ ์—†์ด 1๊ธ€์ž ์ด์ƒ 15๊ธ€์ž ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
    @Size(min = 1, max = 15, message = "์ œ๋ชฉ์€ ๊ณต๋ฐฑ ์—†์ด 1๊ธ€์ž ์ด์ƒ 15๊ธ€์ž ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
    @ApiModelProperty(name = "title", value = "์ œ๋ชฉ", example = "์ œ๋ชฉ", required = true, dataType = "String")
    private String title;

    @NotEmpty(message = "๋‚ด์šฉ์€ 1๊ธ€์ž ์ด์ƒ 1000๊ธ€์ž ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
    @Size(min = 1, max = 1000, message = "๋‚ด์šฉ์€ 1๊ธ€์ž ์ด์ƒ 1000๊ธ€์ž ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.")
    @ApiModelProperty(name = "content", value = "๋‚ด์šฉ", example = "๋‚ด์šฉ", required = true, dataType = "String")
    private String content;

    @ApiModelProperty(name = "createdTime", value = "์ƒ์„ฑ์ผ์ž", required = true, dataType = "LocalDateTime")
    private LocalDateTime createdTime;

๐Ÿ’ฌ ํšŒ๊ณ 

Swagger์˜ ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…๊ณผ ์ด๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์–ด๋–ป๊ฒŒ API ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋Š”์ง€ ํ•™์Šตํ–ˆ๋‹ค.
Swagger์—๋Š” springfox์™€ springdocs๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, ๋‚˜๋Š” springfox๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.
Swagger ์‚ฌ์šฉ๋ฒ•์„ ์ตํžˆ๋ฉด์„œ springdocs๋„ ์‚ฌ์šฉํ•ด์„œ ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋ณผ ์ƒ๊ฐ์ด๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€