1) Swagger ๊ฐ์
1. ์ค์จ๊ฑฐ(Swagger)๋?
์ค์จ๊ฑฐ๋ Web API ๋ฌธ์ํ๋ฅผ ์ํ ๋๊ตฌ์ ๋๋ค.
์ค์จ๊ฑฐ ํํ์ด์ง(https://swagger.io)์์๋ ์ค์จ๊ฑฐ๋ฅผ OAS(Open API Specification)์ด๋ผ๊ณ ์๊ฐํ๊ณ ์์ต๋๋ค.
๋ง๊ทธ๋๋ก API๋ค์ด ๊ฐ์ง๋ ๋ช ์ธ(Spec)์ ๊ด๋ฆฌํ๊ธฐ ์ํ ํ๋ก์ ํธ๋ผ๊ณ ๋งํ ์ ์์ต๋๋ค.
Web API๋ฅผ ์๋์ผ๋ก ๋ฌธ์ํ ํ๋ ๊ฒ์ ๊ต์ฅํ ํ๋ ์์ ์ ๋๋ค.
Web API์ ์คํ์ด ๋ณ๊ฒฝ๋์์ ๋ ๋ฌธ์ ์ญ์ ๋ณ๊ฒฝ์ด ๋์ผ ํ๋๋ฐ ์ด๋ฅผ ์ ์งํ๋ ๊ฒ์ด ์ฝ์ง๊ฐ ์์ต๋๋ค.
Swagger๋ฅผ ์ฌ์ฉํ๋ฉด Web API๊ฐ ์์ ๋๋๋ผ๋ ์๊ด ์์ต๋๋ค. ๋ฌธ์๊ฐ ์๋์ผ๋ก ๊ฐฑ์ ์ด ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
2. ์ค์จ๊ฑฐ์ ๊ธฐ๋ฅ
์ค์จ๊ฑฐ ํํ์ด์ง๋ฅผ ๊ฐ๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
1) API Design
2) API Development
3) API Documentation
4) API Testing
5) API Mocking and Virtualization
6) API Governance
7) API Monitoring
8) OpenAPI & Swagger
Web API๋ฅผ ๋ง๋๋ ๊ฐ๋ฐ์์ Web API๋ฅผ ์ด์ฉํ๋ ๊ฐ๋ฐ์๊ฐ ์๋ค๊ณ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
Web API๋ฅผ ์ด์ฉํ๋ ๊ฐ๋ฐ์๋ Web API๊ฐ ๋ง๋ค์ด์ง ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค๋ฉด ์์ ์ด ์๋นํ ๋๋ ค์ง ์ ์์ ๊ฒ์ ๋๋ค.
Web API๋ฅผ ๋ง๋๋ ์ฌ๋๊ณผ Web API๋ฅผ ์ฌ์ฉํ๋ ์ฌ๋ ๊ฐ์ ๋ฏธ๋ฆฌ ๋ช ์ธ๋ฅผ ์ ์ํ๊ณ ๊ณต์ ํ ์ ์๋ค๋ฉด
๊ฐ๋ฐ์ด ์๋นํ ํธ๋ฆฌํด ์ง ๊ฒ์ ๋๋ค.
์ง๊ธ ์ด์ผ๊ธฐ ํ ๊ฒ๋ค์ ํธํ๊ฒ ํด์ฃผ๋ ๋๊ตฌ ์ค์ ํ๋๊ฐ ‘์ค์จ๊ฑฐ’๋ผ๊ณ ๋งํ ์ ์์ต๋๋ค.
3. ์ค์จ๊ฑฐ ํ๋ธ๋ฅผ ์ด์ฉํ์ฌ API๋ฅผ ๋ช ์ธํ ํ๊ณ ํ ์คํธํ๊ธฐ
์ค์จ๊ฑฐ ํ๋ธ ์ฌ์ดํธ๋ฅผ ์ด์ฉํ๋ฉด Web API๋ฅผ ๋ง๋ค์ง ์๋๋ผ๋ Web API๋ฅผ ๋ช ์ธํํ ์ ์์ต๋๋ค.
๋ํ, Web API๋ฅผ ๋ช ์ธํ๋ง ํ๋๊ฒ ์๋๋ผ ๊ฐ๋จํ ํ ์คํธ๋ ํ ์ ์๋ค๋ ์ฅ์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
2) Swagger ์ค์ ํ๊ธฐ
์ฝ๋๋งํฌ: calculator06
1. pom.xml ํ์ผ ์์
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
2. WebAppInitializer ํด๋์ค ์์ฑํ๊ธฐ
์๋ฐ ์น ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ๋๋ web.xml ํ์ผ์ด๋ WebApplicationInitializer๋ฅผ ๊ตฌํํ ํด๋์ค๋ฅผ ๋ง๋ค๊ฑฐ๋ ํด์ผ ํ๋ค๊ณ ์์์ ์ค๋ช ํ์์ต๋๋ค. (Spring MVC๋ฅผ ์ด์ฉํ ์น ํ์ด์ง ์์ฑ ์ค์ต ์ฐธ๊ณ )
์์์ ์ค๋ช ํ WebApplicationInitializer๋ฅผ ์์์๋ ์ง์ ๊ตฌํํ์๋๋ฐ
์ด๋ฒ์๋ WebApplicationInitializer๋ฅผ ๊ตฌํํ๊ณ ์๋ AbstractAnnotationConfigDispatcherServletInitializer๋ฅผ
์์๋ฐ์ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
AbstractAnnotationConfigDispatcherServletInitializer ํด๋์ค๋ WebApplicationInitializer๋ฅผ ๊ตฌํํ๊ณ ์์ผ๋ฉด์
ํ์ํ ๋ถ๋ถ๋ง ์ค๋ฒ๋ผ์ด๋ฉ ํ์ฌ ๊ตฌํํ๋๋ก ์ ๊ณตํ๋ ํด๋์ค์ ๋๋ค.
WebApplicationInitializer.java
package org.edwith.webbe.calculator.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.*;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// Spring ๊ธฐ๋ณธ ์ค์ ํ์ผ ํด๋์ค๋ฅผ ์ง์ ํฉ๋๋ค.
// ์ฌ๋ฌ๋ถ์ ApplicationConfig.class๋ฅผ ์์ฑํด์ค์ผ ํฉ๋๋ค.
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { ApplicationConfig.class };
}
// Spring MVC ์ค์ ํ์ผ ํด๋์ค๋ฅผ ์ง์ ํฉ๋๋ค.
// ์ฌ๋ฌ๋ถ์ MvcConfig.class๋ฅผ ์์ฑํด์ค์ผ ํฉ๋๋ค.
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { MvcConfig.class };
}
/*
* DispatcherServlet์ด ๋์ํ ๋งตํ์ ๋ณด๋ฅผ ์ค์ ํฉ๋๋ค. "/"๋ฅผ ์ค์ ํ๋ค๋ ๊ฒ์ ๋ชจ๋ ์์ฒญ์ DispatcherServlet์ด
* ์ฒ๋ฆฌํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
*/
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
/*
* ํํฐ๋ฅผ ์ค์ ํฉ๋๋ค. ์ฌ๊ธฐ์์๋ ์ธ์ฝ๋ฉ ํํฐ๋ฅผ ์ค์ ํ๊ณ ์์ต๋๋ค.
*/
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
return new Filter[] { encodingFilter };
}
}
3. ๊ธฐ๋ณธ์ ์ธ ์คํ๋ง ์ค์ ํ์ผ ์์ฑํ๊ธฐ
Spring MVC์์ ์ฌ์ฉํ Bean๋ค์ ์ค์ ํ๋ ์คํ๋ง ์ค์ ํ์ผ์ ์์ฑํฉ๋๋ค.
์ฌ๊ธฐ์์๋ 'org.edwith.webbe.calculator.service' ํจํค์ง ์ดํ์ Bean๋ค๋ง ์ฐพ๋๋ก ์ค์ ๋์ด ์์ต๋๋ค.
ApplicationConfig.java
package org.edwith.webbe.calculator.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"org.edwith.webbe.calculator.service"})
public class ApplicationConfig {
}
4. Spring MVC ์ค์ ํ์ผ ์์ฑํ๊ธฐ
MvcConfig.java
package org.edwith.webbe.calculator.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableWebMvc
@EnableSwagger2
@ComponentScan(basePackages = {"org.edwith.webbe.calculator.controller.api"})
public class MvcConfig implements WebMvcConfigurer {
// DefaultServlet์ ๋ํ ์ค์ ์ ํฉ๋๋ค.
// DispatcherServlet์ด ์ฒ๋ฆฌํ์ง ๋ชปํ๋ URL์ DefaultServlet์ด ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
// ํด๋น ์ค์ ์ด ์์ผ๋ฉด ์๋ ์์ฑ๋ Swagger ํ์ด์ง๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/*
Swagger ์ฌ์ฉ ์์๋ Docket Bean ์ ํ๊ณ ์๋ ์ค์ ํด๋์ค 1๊ฐ๊ฐ ๊ธฐ๋ณธ์ผ๋ก ํ์ํ๋ค.
Spring Boot ์์๋ ์ด ๊ธฐ๋ณธ์ ์ธ ์ค์ ํ์ผ 1๊ฐ๋ก Swagger ์ Swagger UI ๋ฅผ ํจ๊ป ์ฌ์ฉ๊ฐ๋ฅํ์ง๋ง,
Spring MVC ์ ๊ฒฝ์ฐ Swagger UI ๋ฅผ ์ํ ๋ณ๋์ ์ค์ ์ด ํ์ํ๋ค.
์ด๋, Swagger UI ๋ฅผ ResourceHandler ์ ์๋์ผ๋ก ๋ฑ๋กํด์ผ ํ๋ ์์
์ธ๋ฐ,
Spring Boot ์์๋ ์ด๋ฅผ ์๋์ผ๋ก ์ค์ ํด์ฃผ์ง๋ง Spring MVC ์์๋ ๊ทธ๋ ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
*/
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any()) // // ํ์ฌ RequestMapping์ผ๋ก ํ ๋น๋ ๋ชจ๋ URL ๋ฆฌ์คํธ๋ฅผ ์ถ์ถ
.paths(PathSelectors.ant("/api/**"))// PathSelectors.any() ๋ฅผ ํ ๊ฒฝ์ฐ ๋ชจ๋ ๊ฒฝ๋ก๊ฐ ๋ค ์ฌ์ฉ๋๋ค. RestController๊ฐ ์๋ ๊ฒ ๊น์ง ์ฌ์ฉ๋๋ค.
.build()
.apiInfo(apiInfo())
.useDefaultResponseMessages(false);
}
/**
* API Info
*/
private ApiInfo apiInfo() {
Contact contact = new Contact("๊ฐ๊ฒฝ๋ฏธ", "https://www.edwith.org", "carami@edwith.org");
ApiInfo apiInfo =
new ApiInfo("Swagger Sample", "APIs Sample", "Sample Doc 0.1v", "", contact, "This sentence will be display.", "/");
return apiInfo;
}
}
ํด๋์ค ์์ @EnableWebMvc, @EnableSwagger2๊ฐ ๋ถ์ด ์๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๊ฐ๊ฐ Spring MVC์ค์ , Swagger2์ค์ ์ด๋ผ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
ํด๋น ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ์์ ๊ฒฝ์ฐ Spring MVC์ Swagger2์ ๊ธฐ๋ณธ ์ค์ ์ด ์๋์ผ๋ก ์ค์ ๋ฉ๋๋ค.
Swagger2๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด Docket๊ฐ์ฒด๋ฅผ Bean์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
Docker๊ฐ์ฒด์๋ ์ด๋ค ๊ฒฝ๋ก์ Web API๋ค์ ์๋์ผ๋ก ๋ฌธ์ํ ํ ๊ฒ์ธ์ง์ ๋ํ ์ค์ ๊ณผ ๋ฌธ์ ์ค๋ช ์ ๋ํ ๋ด์ฉ์ด ํฌํจ๋ฉ๋๋ค.
์ฌ๊ธฐ๊น์ง ์ค์ ํ์๋ค๋ฉด, Web API๋ฅผ ์์ฑํ๊ณ ์ค์จ๊ฑฐ๋ฅผ ์ด์ฉํ ์ค๋น๊ฐ ์๋ฃ๋์์ต๋๋ค.
3) Swagger-ui ํ์ธ ๋ฐ ๊ธฐ๋ฅ ํ ์คํธํ๊ธฐ
'Spring > Boost Course Web' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
5.1 ์ํ์ ์ง๊ธฐ์ - Cookie & Session (0) | 2020.11.19 |
---|---|
4.4 Controller (0) | 2020.11.19 |
4.3 WEB API (0) | 2020.11.19 |
4.2 Layered Architecture (0) | 2020.11.19 |
4.1 Spring MVC (0) | 2020.11.19 |
3.3 Spring JDBC (0) | 2020.11.19 |