Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swaggerで定義したAPI仕様から Retrofitで使用するinterfaceを自動生成してみる

Ryosuke Horie
November 28, 2017

Swaggerで定義したAPI仕様から Retrofitで使用するinterfaceを自動生成してみる

Ryosuke Horie

November 28, 2017
Tweet

More Decks by Ryosuke Horie

Other Decks in Programming

Transcript

  1. © 2017 VASILY,Inc. ࣗݾ঺հ w !)PSJF w 7"4*-: *OD w

    "OESPJEΤϯδχΞ w ϏʔϧɺࣗಈԽ޷͖
  2. © 2017 VASILY,Inc. 4XBHHFSͰ"1*࢓༷Λఆٛ "paths": { "/users/{username}/repos": { "get": {

    "summary": "List public repositories for the specified user.", "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "description": "Can be one of all, owner, member. Default: owner", "required": false, "type": "string" }, { "name": "sort", "in": "query", "description": "Can be one of created, updated, pushed, full_name. Default: full_name", "required": false, "type": "string" }, { "name": "direction", "in": "query", "description": "Can be one of asc or desc. Default: when using full_name: asc, otherwise desc", "required": false, "type": "string" } ], "tags": [ "Users" ], "responses": { "200": { "description": "successful operation", "schema": { "type": "array", "items": { "$ref": "#/definitions/Repo" } } }, "400": { "description": "Invalid status value" } } } } }
  3. © 2017 VASILY,Inc. w ͜Μͳײ͡ͷίʔυΛੜ੒͍ͨ͠ w 4XBHHFSΦϒδΣΫτ͔Βඞཁͳ৘ใΛऔಘ w LPUMJOQPFUͰίʔυੜ੒ w

    ೚ҙͷύεʹॻ͖ग़͠ LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos( @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> }
  4. © 2017 VASILY,Inc. ྫ6TFS4FSWJDFJOUFSGBDFͷੜ੒ FileSpec.builder("", "UserService") .addType(TypeSpec .interfaceBuilder("UserService") .addFunction(FunSpec.builder("listRepos") .addModifiers(KModifier.ABSTRACT)

    .addAnnotation(AnnotationSpec.builder(GET::class) .addMember("\"/users/{username}/repos\"") .build()).build() ).build() ).build().writeTo(System.out) interface UserService { @GET("/users/{username}/repos") fun listRepos() }
  5. © 2017 VASILY,Inc. ྫ6TFS4FSWJDFJOUFSGBDFͷੜ੒ FileSpec.builder("", "UserService") .addType(TypeSpec .interfaceBuilder("UserService") .addFunction(FunSpec.builder("listRepos") .addModifiers(KModifier.ABSTRACT)

    .addAnnotation(AnnotationSpec.builder(GET::class) .addMember("\"/users/{username}/repos\"") .build()) .returns(ParameterizedTypeName.get(Single::class.asTypeName(), ParameterizedTypeName.get(List::class.asTypeName(), ClassName("", "Repo")) )).build() ).build() ).build() interface UserService { @GET("/users/{username}/repos") fun listRepos(): Single<List<Repo>> }
  6. © 2017 VASILY,Inc. ྫ6TFS4FSWJDFJOUFSGBDFͷੜ੒ FileSpec.builder("", "UserService") .addType(TypeSpec .interfaceBuilder("UserService") .addFunction(FunSpec.builder("listRepos") .addModifiers(KModifier.ABSTRACT)

    .addAnnotation(AnnotationSpec.builder(GET::class) .addMember("\"/users/{username}/repos\"") .build()) .addParameter(ParameterSpec.builder("username", String::class.asTypeName().asNonNullable()) .addAnnotation(AnnotationSpec.builder(Path::class).addMember("\"username\"").build()) .build()) .returns(ParameterizedTypeName.get(Single::class.asTypeName(), ParameterizedTypeName.get(List::class.asTypeName(), ClassName("", "Repo")) )).build() ).build() ).build() interface UserService { @GET("/users/{username}/repos") fun listRepos(@Path("username") username: String): Single<List<Repo>> }
  7. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "paths": { "/users/{username}/repos": { "get": { "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "required": false, "type": "string" }, { "name": "sort", "in": "query", "required": false, "type": "string" }, { "name": "direction", "in": "query", "required": false, "type": "string" } ], "tags": [ "Users" ],
  8. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "paths": { "/users/{username}/repos": { "get": { "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "required": false, "type": "string" }, { "name": "sort", "in": "query", "required": false, "type": "string" }, { "name": "direction", "in": "query", "required": false, "type": "string" } ], "tags": [ "Users" ],
  9. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "paths": { "/users/{username}/repos": { "get": { "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "required": false, "type": "string" }, { "name": "sort", "in": "query", "required": false, "type": "string" }, { "name": "direction", "in": "query", "required": false, "type": "string" } ], "tags": [ "Users" ],
  10. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "paths": { "/users/{username}/repos": { "get": { "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "required": false, "type": "string" }, { "name": "sort", "in": "query", "required": false, "type": "string" }, { "name": "direction", "in": "query", "required": false, "type": "string" } ], "tags": [ "Users" ],
  11. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "paths": { "/users/{username}/repos": { "get": { "operationId": "listRepos", "parameters": [ { "name": "username", "in": "path", "description": "ID of pet to update", "required": true, "type": "string" }, { "name": "type", "in": "query", "required": false, "type": "string" }, { "name": "sort", "in": "query", "required": false, "type": "string" }, { "name": "direction", "in": "query", "required": false, "type": "string" } ], "tags": [ "Users" ],
  12. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repos>> } "responses": { "200": { "description": "successful operation", "schema": { "type": "array", "items": { "$ref": "#/definitions/Repo" } } }, "400": { "description": "Invalid status value" } } } } }, "definitions": { "Repo": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "url": { "type": "string" } } } }
  13. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ interface UsersService { @GET("/users/{username}/repos") fun listRepos(

    @Path("username") username: String, @Query("type") type: String? = null, @Query("sort") sort: String? = null, @Query("direction") direction: String? = null ): Single<List<Repo>> } "responses": { "200": { "description": "successful operation", "schema": { "type": "array", "items": { "$ref": "#/definitions/Repo" } } }, "400": { "description": "Invalid status value" } } } } }, "definitions": { "Repo": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "url": { "type": "string" } } } }
  14. © 2017 VASILY,Inc. LPUMJOQPFUͰͷίʔυੜ੒ data class Repo( val id: String,

    val name: String, val url: String ) "responses": { "200": { "description": "successful operation", "schema": { "type": "array", "items": { "$ref": "#/definitions/Repo" } } }, "400": { "description": "Invalid status value" } } } } }, "definitions": { "Repo": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "url": { "type": "string" } } } }