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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
390
echoサーバーを書いてI/Oと仲良くなる話
kariyayo
3
880
SpringはどうやってDIしているのか? #jjug_ccc
kariyayo
4
3.6k
Apexで複数環境のLambda関数をデプロイする話 #jawsug
kariyayo
1
2k
近況報告といろいろ作るのが楽しい話 #yokohama_north
kariyayo
0
920
目指せ3つ星インデックス #yokohama_north
kariyayo
2
880
Gradleを使えるようになるために
kariyayo
0
120
Other Decks in Programming
See All in Programming
Gmail/Google DriveをトリガーにAIエージェントを動かそう! / Run AI agents with Gmail/Google Drive as triggers!
har1101
2
450
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
220
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
5
550
不幸な GC
chencmd
0
810
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
450
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
2k
S3 を使うアプリケーションをローカル完結で動かすことに全力を注いでみた / Running S3 Apps Offline
contour_gara
0
660
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.3k
T3DD26: From RAGs to Riches
martinhelmich
0
110
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
780
初心者DevRelとして参加者だった私が、DevRel Talks!#2に登壇するまでにしてきたこと
sokohirai
0
160
バグを直したら useEffect が消えた
colorful12
3
760
Featured
See All Featured
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
830
Navigating Weather and Climate Data
rabernat
0
490
Facilitating Awesome Meetings
lara
57
7.1k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.9k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
550
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Discover your Explorer Soul
emna__ayadi
2
1.3k
Unsuck your backbone
ammeep
672
58k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
430
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
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*
͓͠·͍