Swagger Maven Plugin を使って Swagger ファイルを生成する

Spring には SpringFox という Swagger ファイルを簡単に作れる便利機能があります.

今回はこれを Maven で実行してみたいと思います.

Swagger Maven Plugin

Swagger 公式のプラグインは無いようで、個人の方が出しているものを使わせていただきます.

pom.xml を以下のように記述します.

以下、ポイントとなるところを解説します.

locations タグに Swagger 生成の元となるパッケージを指定します.

 
outputFormats タグに Swagger のファイルフォーマットを指定します.
今回は YAML を指定しました.

 
swaggerDirectory タグに Swagger ファイルの出力先を指定します.

 
execution タグはお好みで設定してもらえれば大丈夫ですが、今回は compile 時に生成されるようにしています.

 

実行結果

mvn compile を実行します.

$ mvn compile

[INFO] --- swagger-maven-plugin:3.1.8:generate (default) @ demoAPI ---
23:11:03,027 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
23:11:03,028 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
23:11:03,028 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [jar:file:/Users/aa367474/.m2/repository/com/example/common/0.0.1-SNAPSHOT/common-0.0.1-SNAPSHOT.jar!/logback.xml]
23:11:03,122 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@3cb67d62 - URL [jar:file:/Users/aa367474/.m2/repository/com/example/common/0.0.1-SNAPSHOT/common-0.0.1-SNAPSHOT.jar!/logback.xml] is not of type file
23:11:03,313 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
23:11:03,331 |-INFO in ch.qos.logback.core.joran.util.ConfigurationWatchListUtil@a5312 - Adding [jar:file:/Users/aa367474/.m2/repository/org/springframework/boot/spring-boot/2.1.2.RELEASE/spring-boot-2.1.2.RELEASE.jar!/org/springframework/boot/logging/logback/defaults.xml] to configuration watch list.
23:11:03,331 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@3cb67d62 - URL [jar:file:/Users/aa367474/.m2/repository/org/springframework/boot/spring-boot/2.1.2.RELEASE/spring-boot-2.1.2.RELEASE.jar!/org/springframework/boot/logging/logback/defaults.xml] is not of type file
23:11:03,337 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word clr with class [org.springframework.boot.logging.logback.ColorConverter]
23:11:03,337 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wex with class [org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter]
23:11:03,337 |-INFO in ch.qos.logback.core.joran.action.ConversionRuleAction - registering conversion word wEx with class [org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter]
23:11:03,349 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.apache.catalina.startup.DigesterFactory] to ERROR
23:11:03,349 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.apache.catalina.util.LifecycleBase] to ERROR
23:11:03,349 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.apache.coyote.http11.Http11NioProtocol] to WARN
23:11:03,350 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.apache.sshd.common.util.SecurityUtils] to WARN
23:11:03,350 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.apache.tomcat.util.net.NioSelectorPool] to WARN
23:11:03,350 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.eclipse.jetty.util.component.AbstractLifeCycle] to ERROR
23:11:03,351 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.hibernate.validator.internal.util.Version] to WARN
23:11:03,352 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
23:11:03,372 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [APPLOG]
23:11:03,390 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:11:03,487 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@653977121 - Archive files will be limited to [10 MB] each.
23:11:03,496 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@653977121 - No compression will be used
23:11:03,499 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@653977121 - Will use the pattern ./logs/app.%d{yyyyMMdd}.%i.log for the active file
23:11:03,506 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@2eff2960 - The date pattern is 'yyyyMMdd' from file name pattern './logs/app.%d{yyyyMMdd}.%i.log'.
23:11:03,506 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@2eff2960 - Roll-over at midnight.
23:11:03,507 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@2eff2960 - Setting initial period to Tue Feb 19 10:29:13 JST 2019
23:11:03,515 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[APPLOG] - Active log file name: ./logs/app.log
23:11:03,515 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[APPLOG] - File property is set to [./logs/app.log]
23:11:03,517 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
23:11:03,517 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [PERFORMANCE]
23:11:03,517 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:11:03,519 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@556600496 - Archive files will be limited to [10 MB] each.
23:11:03,519 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@556600496 - No compression will be used
23:11:03,520 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@556600496 - Will use the pattern ./logs/performance.%d{yyyyMMdd}.%i.log for the active file
23:11:03,523 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@73ed5944 - The date pattern is 'yyyyMMdd' from file name pattern './logs/performance.%d{yyyyMMdd}.%i.log'.
23:11:03,523 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@73ed5944 - Roll-over at midnight.
23:11:03,523 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@73ed5944 - Setting initial period to Fri Mar 22 16:17:36 JST 2019
23:11:03,524 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[PERFORMANCE] - Active log file name: ./logs/performance.log
23:11:03,524 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[PERFORMANCE] - File property is set to [./logs/performance.log]
23:11:03,525 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
23:11:03,525 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ALERT]
23:11:03,525 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:11:03,526 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@39285494 - Archive files will be limited to [10 MB] each.
23:11:03,527 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@39285494 - No compression will be used
23:11:03,527 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@39285494 - Will use the pattern ./logs/alert.%d{yyyyMMdd}.%i.log for the active file
23:11:03,528 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@55b4eff5 - The date pattern is 'yyyyMMdd' from file name pattern './logs/alert.%d{yyyyMMdd}.%i.log'.
23:11:03,528 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@55b4eff5 - Roll-over at midnight.
23:11:03,529 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@55b4eff5 - Setting initial period to Tue Feb 19 10:29:13 JST 2019
23:11:03,530 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[ALERT] - Active log file name: ./logs/alert.log
23:11:03,530 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[ALERT] - File property is set to [./logs/alert.log]
23:11:03,530 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender]
23:11:03,530 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [ACCESS]
23:11:03,530 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
23:11:03,532 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@481632639 - Archive files will be limited to [10 MB] each.
23:11:03,532 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@481632639 - No compression will be used
23:11:03,533 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@481632639 - Will use the pattern ./logs/access.%d{yyyyMMdd}.%i.log for the active file
23:11:03,534 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@58b7cd4 - The date pattern is 'yyyyMMdd' from file name pattern './logs/access.%d{yyyyMMdd}.%i.log'.
23:11:03,534 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@58b7cd4 - Roll-over at midnight.
23:11:03,534 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@58b7cd4 - Setting initial period to Tue Feb 19 10:29:13 JST 2019
23:11:03,535 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[ACCESS] - Active log file name: ./logs/access.log
23:11:03,535 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[ACCESS] - File property is set to [./logs/access.log]
23:11:03,535 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
23:11:03,538 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
23:11:03,542 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - This appender no longer admits a layout as a sub-component, set an encoder instead.
23:11:03,542 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
23:11:03,542 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
23:11:03,543 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [performance] to DEBUG
23:11:03,543 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [performance] to false
23:11:03,544 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [PERFORMANCE] to Logger[performance]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [error] to INFO
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [error] to true
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [detail] to INFO
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [detail] to true
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [access] to DEBUG
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [access] to true
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.example.common] to DEBUG
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.example.common] to false
23:11:03,545 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.example.common]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.example] to DEBUG
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.example] to false
23:11:03,545 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.example]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework] to INFO
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.springframework] to false
23:11:03,545 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.springframework]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [ch.qos.logback] to ERROR
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [ch.qos.logback] to false
23:11:03,545 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ch.qos.logback]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
23:11:03,545 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
23:11:03,545 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
23:11:03,547 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@3cf27e51 - Registering current configuration as safe fallback point

[INFO] Reflections took 172 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 26 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 21 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 15 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 16 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 12 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 8 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 13 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 9 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 13 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 13 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 14 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] picking up response class from method public com.example.demoapi.domain.SwaggerTemplateModel com.example.demoapi.controller.SwaggerTemplateController.hello()
[INFO] picking up response class from method public java.util.Map com.example.demoapi.controller.DemoApiController.handleExceptionWithCode(java.lang.String,javax.servlet.http.HttpServletRequest)
[INFO] picking up response class from method public com.example.demoapi.domain.MockPersonDto com.example.demoapi.controller.DemoApiController.findMockPerson()
[INFO] picking up response class from method public void com.example.demoapi.controller.DemoApiController.testDefaultLog()
[INFO] picking up response class from method public void com.example.demoapi.controller.DemoApiController.warn()
[INFO] picking up response class from method public com.example.demoapi.response.CustomerBaseResponse com.example.demoapi.controller.CustomerBaseController.insertCustomerBase(com.example.demoapi.domain.CustomerBaseDto)
[INFO] picking up response class from method public java.util.List com.example.demoapi.controller.CustomerBaseController.findCustomerBase(com.example.demoapi.domain.CustomerBaseDto,java.util.List,java.lang.Integer,java.lang.Integer)
[INFO] picking up response class from method public void com.example.demoapi.controller.CustomerBaseController.deleteCustomerBaseByPrimaryKey(java.lang.String)
[INFO] picking up response class from method public com.example.demoapi.domain.response.CustomerAggregationResponse com.example.demoapi.controller.CustomerController.selectCustomer(java.lang.String,java.lang.Integer) throws java.lang.Exception
[INFO] picking up response class from method public com.example.demoapi.domain.response.CustomerResponse com.example.demoapi.controller.CustomerController.selectCustomerByIntegratedCustomerId(java.lang.String,com.example.demoapi.domain.request.SampleRequest,java.util.List,java.lang.Integer,java.lang.Integer)
[INFO] picking up response class from method public java.util.Map com.example.demoapi.controller.DemoApiController.noHandleException()
[INFO] picking up response class from method public java.util.Map com.example.demoapi.controller.DemoApiController.handleSimpleException()
[INFO] picking up response class from method public com.example.demoapi.response.CustomerBaseResponse com.example.demoapi.controller.CustomerBaseController.selectCustomerBaseByIntegratedCustomerId(java.lang.String,java.util.List)
[INFO] picking up response class from method public com.example.demoapi.domain.MockPersonDto com.example.demoapi.controller.DemoApiController.getMockPerson()
[INFO] picking up response class from method public java.util.Map com.example.demoapi.controller.DemoApiController.handleRetrySample(boolean)
[INFO] picking up response class from method public com.example.demoapi.response.CustomerBaseResponse com.example.demoapi.controller.CustomerBaseController.updateCustomerBase(java.lang.String,com.example.demoapi.domain.CustomerBaseDto)
[INFO] picking up response class from method public void com.example.demoapi.controller.PetController.deletePet(java.lang.String,java.lang.Integer)
[INFO] picking up response class from method public java.util.List com.example.demoapi.controller.PetController.selectPets(com.example.demoapi.domain.request.PetRequestQuery,java.util.List,java.lang.Integer,java.lang.Integer)
[INFO] picking up response class from method public int com.example.demoapi.controller.DemoApiController.insertDepartment(com.example.demoapi.domain.DepartmentDto)
[INFO] picking up response class from method public com.example.demoapi.domain.response.PetResponse com.example.demoapi.controller.PetController.insertPet(java.lang.String,com.example.demoapi.domain.request.PetRequestBody)
[INFO] picking up response class from method public com.example.demoapi.domain.response.PetResponse com.example.demoapi.controller.PetController.selectPet(java.lang.String,java.lang.Integer)
[INFO] picking up response class from method public com.example.demoapi.domain.PersonDto com.example.demoapi.controller.DemoApiController.createPerson(com.example.demoapi.domain.PersonDto)
[INFO] picking up response class from method public com.example.demoapi.domain.response.CustomerResponse com.example.demoapi.controller.CustomerController.selectCustomerByIntegratedCustomerIdWithCem(java.lang.String,com.example.demoapi.domain.request.SampleRequest,java.util.List,java.lang.Integer,java.lang.Integer)
[INFO] picking up response class from method public com.example.demoapi.domain.response.PetResponse com.example.demoapi.controller.PetController.updatePet(java.lang.String,java.lang.Integer,com.example.demoapi.domain.request.PetRequestBody)
[INFO] Reflections took 16 ms to scan 1 urls, producing 4 keys and 15 values 
[INFO] Reflections took 15 ms to scan 1 urls, producing 4 keys and 15 values

 
ファイルも生成されています.

 

まとめ

今回は Swagger ファイルを自動生成してくれる Swagger Maven Plugin を使ってみました.

CI/CD 時などに Swagger ファイルを生成したいときは大いに活躍してくれると思います.

公式ライブラリではありませんが、今のところ特に不満もありません.
十分に実用に足ると思います.

 

以上です.