Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Spring Boot と Swagger #渋谷java
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
890
SpringはどうやってDIしているのか? #jjug_ccc
kariyayo
4
3.7k
Apexで複数環境のLambda関数をデプロイする話 #jawsug
kariyayo
1
2k
近況報告といろいろ作るのが楽しい話 #yokohama_north
kariyayo
0
920
目指せ3つ星インデックス #yokohama_north
kariyayo
2
890
Gradleを使えるようになるために
kariyayo
0
120
Other Decks in Programming
See All in Programming
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
1
110
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
190
mrbgem 三角測量 開発
ogom
0
160
Are APIs Still Relevant in the AI Era?
soyuka
0
380
WebRTC映像をAirPlayに対応させる挑戦.pdf
monolithic_adam
0
330
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
280
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
30
13k
カツオ、ご期待ください
suneo3476
0
130
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
570
Simple Storage Service(S3) is not simple
iwatsukayura
0
110
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
430
Featured
See All Featured
The Language of Interfaces
destraynor
162
27k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
250
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
The Limits of Empathy - UXLibs8
cassininazir
1
690
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.2k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
brightonSEO & MeasureFest 2025 - Winning Strategies for Black Friday CRO & PPC - Christian Goodrich
cargoodrich
3
860
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
500
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*
͓͠·͍