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
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
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.7k
スマートグラスで並列バイブコーディング
hyshu
0
280
Skillsは効率化、Agentsは"自分の拡張"——Builder時代のエージェント編成(CC Night 2026)
wemra
1
190
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
1k
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
260
鹿野さんに聞く!『TypeScriptコードレシピ集』で磨く実践力
tonkotsuboy_com
4
970
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
250
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
0
200
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
ECSアプリログをFireLensでコスト削減しようとしたけど諦めた話 in Fargate×Node.js
akihisaikeda
2
4.2k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
17
8.5k
Featured
See All Featured
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
180
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
410
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
330
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Odyssey Design
rkendrick25
PRO
2
720
RailsConf 2023
tenderlove
30
1.5k
A better future with KSS
kneath
240
18k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.2k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
460
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
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*
͓͠·͍