Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Spring Boot と Swagger #渋谷java
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
kariyayo
August 01, 2015
Programming
5.8k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Spring Boot と Swagger #渋谷java
kariyayo
August 01, 2015
More Decks by kariyayo
See All by kariyayo
MobX の話
kariyayo
0
380
echoサーバーを書いてI/Oと仲良くなる話
kariyayo
3
880
SpringはどうやってDIしているのか? #jjug_ccc
kariyayo
4
3.6k
Apexで複数環境のLambda関数をデプロイする話 #jawsug
kariyayo
1
2k
近況報告といろいろ作るのが楽しい話 #yokohama_north
kariyayo
0
910
目指せ3つ星インデックス #yokohama_north
kariyayo
2
880
Gradleを使えるようになるために
kariyayo
0
100
Other Decks in Programming
See All in Programming
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
190
霧の中の代数的エフェクト
funnyycat
1
390
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
2.7k
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.6k
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
act2-costs.pdf
sumedhbala
0
110
Apache Hive: そしてCloud Native Lakehouseへ
okumin
1
130
共通化で考えるべきは、実装より公開する型だった
codeegg
0
240
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
150
関数型プログラミングのメリットって何だろう?
wanko_it
0
180
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
180
Featured
See All Featured
Building Adaptive Systems
keathley
44
3.1k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
470
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Practical Orchestrator
shlominoach
191
11k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
220
Embracing the Ebb and Flow
colly
88
5.1k
What's in a price? How to price your products and services
michaelherold
247
13k
The Curious Case for Waylosing
cassininazir
1
430
How to make the Groovebox
asonas
2
2.3k
A Soul's Torment
seathinner
6
3.1k
The Curse of the Amulet
leimatthew05
2
13k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Transcript
Spring Boot ͱ Swagger 2015/8/1 ୈेೋճ #ौ୩Java bati (twitter: @bati11_)
࣍ • Swagger ͱ • SpringFox • JsonSchema • Swagger
CodeGen • σϓϩΠϝϯτύΠϓϥΠϯʹΈࠐΉ
Swagger ͱ • Web API ͷ༷Λ Swagger ͷϧʔϧʹଇͬͨ JSON Ͱهड़
• Swagger JSON ΛऔΓר֤͘छπʔϧ • ྫ͑ɺSwagger UI • σϞαΠτ http://petstore.swagger.io/
JSONͰهड़… { "swagger": "2.0", "info": { "description": "Api Documentation", "version":
"1.0", "title": "Api Documentation", "termsOfService": "urn:tos", "contact": { "name": "Contact Email" }, "license": { "name": "Apache 2.0", "url": "http://www.apache.org/licenses/LICENSE-2.0" } }, "host": "localhost:5555", "basePath": "/", "tags": [ { "name": "person-resource", "description": "Person Resource" } ], "paths": { "/persons": { "get": { "tags": [ "person-resource" ], "summary": "index", "operationId": "indexUsingGET", "consumes": [ "application/json" ], "produces": [ "application/json" ], "responses": { "200": { "description": "OK", "schema": { "type": "array", "items": { "$ref": "#/definitions/Person" }
JSON ΛखͰॻ͘ͷਏ͍ͷͰ… • Swagger Editor • ϒϥβ্Ͱಈ͘πʔϧ • YAMLɺϦΞϧλΠϜϓϨϏϡʔ •
SpringFox • Spring MVC ͳΒͪ͜Βͷબࢶ͋Δ
http://springfox.github.io/springfox/
• SpringͷΞϊςʔγϣϯΛݩʹSwagger JSON ΛੜͰ͖Δ @RestController @RequestMapping(value = "persons", produces =
MediaType.APPLICATION_JSON_VALUE) public class PersonResource { @RequestMapping(method = RequestMethod.GET) public List<Person> index() { ɾɾɾ } } SpringFox 4QSJOH#PPUͷίϯτϩʔϥʔ
SpringFoxΛ Spring Boot Ͱ͏
spring-swagger2 ΛґଘϥΠϒϥϦʹՃ repositories { ɾɾɾ jcenter() } dependencies { ɾɾɾ
compile ‘io.springfox:springfox-swagger2:2.0.3’ } CVJMEHSBEMF
Configuration ΫϥεΛ༻ҙ @EnableSwagger2 @Configuration public class SwaggerConfiguration { @Bean public
Docket customDocket() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage(“sample.web")) .build(); } }
ىಈͯ͠ /v2/api-docs.json ʹΞΫηε͢Δͱ Swagger JSON ΛऔಘͰ͖Δ $ ./gradlew bootRun $
curl http://localhost:8080/v2/api-docs.json { "swagger": "2.0", "info": { "description": "Api Documentation", "version": "1.0", "title": "Api Documentation", "termsOfService": "urn:tos", "contact": { "name": "Contact Email" }, ɾ ɾ ɾ
Swagger UI Λ Spring Boot Ͱ͏
spring-swagger-ui ΛґଘϥΠϒϥϦʹՃͯ͠ ىಈ͢Δ repositories { ɾɾɾ jcenter() } dependencies {
ɾɾɾ compile ‘io.springfox:springfox-swagger2:2.0.3’ compile 'io.springfox:springfox-swagger-ui:2.0.3' } CVJMEHSBEMF
/swagger-ui.html ʹΞΫηε͢Δͱ API υΩϡ ϝϯτ͕ݟΕΔ
SpringFox ͷ ΞϊςʔγϣϯͰ Swagger JSON ͷ ༰Λฤू͢Δ
• ϦΫΤετʹؔΘΔΞϊςʔγϣϯ • @Api, @ApiOperation, @ApiParam
• ϨεϙϯεʹؔΘΔΞϊςʔγϣϯ • @ApiModel, @ApiModelProperty
Tips
LocalDateTimeͷϓϩύςΟΛจࣈྻʹ͢Δ @Bean public Docket customDocket() { return new Docket(DocumentationType.SWAGGER_2) .select()
.apis(RequestHandlerSelectors.basePackage(“sample.web")) .build() .directModelSubstitute(LocalDateTime.class, String.class); }
OptionalͷϓϩύςΟΛจࣈྻʹ͢Δ @Bean public Docket customDocket() { return new Docket(DocumentationType.SWAGGER_2) .select()
.apis(RequestHandlerSelectors.basePackage(“sample.web")) .build() .directModelSubstitute(LocalDateTime.class, String.class) .alternateTypeRules(new OptionalTypeRule(typeResolver)); } private static class OptionalTypeRule extends AlternateTypeRule { public OptionalTypeRule(TypeResolver typeResolver) { super(typeResolver.resolve(Optional.class), typeResolver.resolve(Object.class)); } @Override public ResolvedType alternateFor(ResolvedType type) { return appliesTo(type) ? type.getTypeBindings().getTypeParameters().get(0) : type; } @Override public boolean appliesTo(ResolvedType type) { return Optional.class.isAssignableFrom(type.getErasedType()); } }
JSON Schema • Swagger JSONͷdefinitationsϓϩύςΟ JSON SchemaͰ͑Δ • http://spacetelescope.github.io/ understanding-json-schema/structuring.html
• ͚ͲɺnullʹରԠͯ͠ͳ͍ • type: [“string”, “null”] ʹ͢Δඞཁ͕͋Δ
ࣗͰඞਢ߲Ͱͳ͍ϓϩύςΟΛ type: “hoge” ͔Β type: [“hoge”, “null”] ʹ͢Δ def root
= new JsonSlurper().parseText(swaggerJson) root.definitions.entrySet().each { def required = it.value.required if (required != null) it.value.properties.each { if (!required.contains(it.key) && !it.value.containsKey('$ref')) { it.value.type = [it.value.type,"null"] } } } } def jsonBuilder = new JsonBuilder() jsonBuilder (root.definitions) definitions = jsonBuilder.toString() (SPPWZͷྫ
Swagger CodeGen • Swagger JSON ͔ΒίʔυΛࣗಈੜͰ͖Δ • ΫϥΠΞϯτଆαʔόʔଆੜͰ͖Δ • ΫϥΠΞϯτίʔυΛ༻Ͱ͖Δ͔ݕ౼த
σϓϩΠϝϯτύΠϓϥΠϯʹ ΈࠐΉ Ϗϧυ ΠϯςάϨʔγϣϯ ςετ 4XBHHFS$PEF(FO 4XBHHFS+40/ +40/4DIFNB ΫϥΠΞϯτϥΠϒϥϦ 4XBHHFS6*
͓͠·͍