메모장

spring restdoc 과 Swagger 합쳐 사용하기

키스샷1104 2024. 5. 5. 14:10

이렇게 도입한 이유는 원래는 전 프로젝트에서는 swagger만 사용을 했지만 비신뢰적이라는 것이다.

그 이유는 테스트가 성공했든 실패를 했든 api가 나오기 때문이다.

그렇다고 spring restdoc만 사용하자니 이쁘지 않았다. swagger에 비해 너무 보기가 어려웠다. 

그래서 찾다보니 spring restdoc과 Swagger를 같이 사용하는 방법이 있었다. 

그래서 이것을 간단하게 구현해본것이다.

plugins {
    //rest doc
    id 'com.epages.restdocs-api-spec' version '0.18.4'
}

dependencies {
    //rest doc
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
    testImplementation 'com.epages:restdocs-api-spec-mockmvc:0.18.4'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'


}
openapi3 {
    servers = [
            { url = 'http://localhost:8080' },
            { url = 'http://production-api-server-url.com' }
    ]
    title = 'Post Service API'
    description = 'Post Service API description'
    version = '1.0.0'
    format = 'json'
}

 

@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI openAPI() {
        Info info = new Info()
                .title("swagger 테스트")
                .version("1.0")
                .description("API에 대한 설명 부분");
        return new OpenAPI()
                .components(new Components())
                .info(info);
    }
}
@Service
public class TestService {

    public TestDto testFunc() {
        return TestDto.builder()
                .data("test")
                .build();
    }
}
@RestController
@RequiredArgsConstructor
public class TestController {
    private final TestService testService;

    @PostMapping("/test/{number}")
    public ResponseEntity<TestDto> testController(@PathVariable Long number,
                                                  @RequestParam Long param,
                                                  @RequestBody TestDto requestTestDto,
                                                  @CurrentMember Member member) {
        final TestDto testDto = testService.testFunc();

        return ResponseEntity.ok(testDto);
    }
}
@Transactional
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureRestDocs
@ExtendWith(RestDocumentationExtension.class)
class TestControllerTest {
    @Autowired
    private MockMvc mock;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private TestController testController;

    @Autowired
    private TestService testService;

    @Test
    @DisplayName("Test를 하기 위해 만든것이다.")
    public void test() throws Exception {

        TestDto testDto = TestDto.builder().data("testData입니다.").build();

        mock.perform(post("/test/{number}", 1L)
                        .param("param", "3")
                        .header("Authorization", "Bearer {AccessToken}")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(objectMapper.writeValueAsString(testDto)))
                .andDo(print())
                .andDo(document("test func",
                        //todo pathParameters와 queryParameter에서는 type을 지정해주지 못한다. 이걸 해결하는 방법을 찾아보자
                        pathParameters(
                                parameterWithName("number")
                                        .description("PathVariable이다")
                                        .attributes(key("example").value(1L))
                        ),
                        queryParameters(
                                parameterWithName("param")
                                        .description("RequestParam이다")
                                        .attributes(key("example").value(3L))
                        ),
                        requestHeaders(
                                headerWithName("Authorization")
                                        .description("AccessToken")
                        ),
                        requestFields(
                                fieldWithPath("data")
                                        .type(JsonFieldType.STRING)
                                        .description("requestDto의 data이다")
                        ),
                        responseFields(
                                fieldWithPath("data").type(JsonFieldType.STRING)
                                        .description("test Data이다")
                        )))
                .andExpect(status().isOk())
                .andExpectAll(jsonPath("$.data").value("test"));
    }

}

 

cmd에서 ./gradlew openapi3

 

완료시 build/api-spec/openapi3.json을 가져옴

그리고 resources의 static 디렉토리에 넣은 후

 

위와 같이 검색 시 시작됨