71
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GoAdvent Calendar 2015

Day 12

go-swaggerの紹介

Last updated at Posted at 2015-12-13

Swaggerとは

OpenAPI Initialiveが提唱しているRestful APIの仕様記述に関する標準化を目指して作られたフォーマット、およびそのツール群です。yamlやjsonでAPI仕様を記述し、そのワークフローを支える幾つかのツールが提供されています。

ツール名 概要
Swagger Core Swaggerの仕様書をJava向けに読み書きするライブラリ
Swagger Codegen Swaggerの仕様書からクライアント/サーバのコードベースを生成するツール群、サードパーティー含め様々な言語向けに提供されています
Swagger UI Swaggerで記述されたAPI仕様をブラウザ側から確認するためのUI
Swagger Editor ブラウザベースで作成されたSwaggerの仕様を記述するためのエディタ

詳しい仕様に関しては、公式サイトを参照ください。
http://swagger.io/

sample

Swaggerで記載されたAPIのサンプルを見てみましょう。

Sample: Petstore

GolangとSwagger

公式のSwagger CodegenではGolangの対応はありませんが、VMWare製OSSのgo-swagger/go-swagger を利用することでGolangでもSwaggerの恩恵をうけることが可能です。

go-swaggerを使ってみる

まずはgo-swaggerをInstallしてください。今のところ、安定版ではなく、安定版ができ次第gopkg.inで利用可能にするとのことでした。

$ go get -u github.com/go-swagger/go-swagger/cmd/swagger

上記をinstallすると、swaggerコマンドが使えるようになりますので、先ほどのサンプルを利用してAPIサーバを吐き出してみましょう。

$ cd $GOPATH/src/path/to/your_pj

#サーバサイドのコード生成
$ swagger generate server -f https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-expanded.json -a petstore
2015/12/13 18:11:42 rendered model template: Pet
2015/12/13 18:11:42 generated model Pet
2015/12/13 18:11:42 rendered model template: NewPet
2015/12/13 18:11:42 generated model NewPet
2015/12/13 18:11:42 rendered model template: Error
2015/12/13 18:11:42 generated model Error
2015/12/13 18:11:42 rendered handler template: petstore.FindPets
2015/12/13 18:11:42 generated handler petstore.FindPets
2015/12/13 18:11:42 rendered parameters template: petstore.FindPetsParameters
2015/12/13 18:11:49 generated parameters petstore.FindPetsParameters
2015/12/13 18:11:49 rendered responses template: petstore.FindPetsResponses
2015/12/13 18:11:49 generated responses petstore.FindPetsResponses
2015/12/13 18:11:49 rendered handler template: petstore.FindPetByID
2015/12/13 18:11:49 generated handler petstore.FindPetByID
2015/12/13 18:11:49 rendered parameters template: petstore.FindPetByIDParameters
2015/12/13 18:11:49 generated parameters petstore.FindPetByIDParameters
2015/12/13 18:11:49 rendered responses template: petstore.FindPetByIDResponses
2015/12/13 18:11:49 generated responses petstore.FindPetByIDResponses
2015/12/13 18:11:49 rendered handler template: petstore.AddPet
2015/12/13 18:11:49 generated handler petstore.AddPet
2015/12/13 18:11:49 rendered parameters template: petstore.AddPetParameters
2015/12/13 18:11:49 generated parameters petstore.AddPetParameters
2015/12/13 18:11:49 rendered responses template: petstore.AddPetResponses
2015/12/13 18:11:49 generated responses petstore.AddPetResponses
2015/12/13 18:11:49 rendered handler template: petstore.DeletePet
2015/12/13 18:11:49 generated handler petstore.DeletePet
2015/12/13 18:11:49 rendered parameters template: petstore.DeletePetParameters
2015/12/13 18:11:49 generated parameters petstore.DeletePetParameters
2015/12/13 18:11:49 rendered responses template: petstore.DeletePetResponses
2015/12/13 18:11:49 generated responses petstore.DeletePetResponses
2015/12/13 18:11:49 rendered builder template: petstore.SwaggerPetstore
2015/12/13 18:11:49 rendered embedded Swagger JSON template: server.SwaggerPetstore
2015/12/13 18:11:49 rendered configure api template: petstore.ConfigureSwaggerPetstore
2015/12/13 18:11:49 rendered doc template: petstore.SwaggerPetstore
2015/12/13 18:11:49 rendered main template: server.SwaggerPetstore

# client側のコード生成
$ swagger generate client -f https://raw.githubusercontent.com/swagger-api/swagger-spec/master/examples/v2.0/json/petstore-expanded.json -a petstore
2015/12/13 18:12:17 rendered model template: Pet
2015/12/13 18:12:17 generated model Pet
2015/12/13 18:12:17 rendered model template: NewPet
2015/12/13 18:12:17 generated model NewPet
2015/12/13 18:12:17 rendered model template: Error
2015/12/13 18:12:17 generated model Error
2015/12/13 18:12:17 rendered client parameters template: petstore.AddPetParameters
2015/12/13 18:12:20 rendered client responses template: petstore.AddPetResponses
2015/12/13 18:12:20 rendered client parameters template: petstore.DeletePetParameters
2015/12/13 18:12:20 rendered client responses template: petstore.DeletePetResponses
2015/12/13 18:12:20 rendered client parameters template: petstore.FindPetByIDParameters
2015/12/13 18:12:20 rendered client responses template: petstore.FindPetByIDResponses
2015/12/13 18:12:20 rendered client parameters template: petstore.FindPetsParameters
2015/12/13 18:12:20 rendered client responses template: petstore.FindPetsResponses
2015/12/13 18:12:20 rendered operation group client template: petstore.PetstoreClient
2015/12/13 18:12:20 rendered client embedded swagger JSON template: client.SwaggerPetstoreClient
2015/12/13 18:12:20 rendered client facade template: client.SwaggerPetstoreClient

上記でサーバ・クライアント双方のコードが生成されました。内容は下記です。

.
├── client
│   ├── petstore
│   │   ├── add_pet_parameters.go
│   │   ├── add_pet_responses.go
│   │   ├── delete_pet_parameters.go
│   │   ├── delete_pet_responses.go
│   │   ├── find_pet_by_id_parameters.go
│   │   ├── find_pet_by_id_responses.go
│   │   ├── find_pets_parameters.go
│   │   ├── find_pets_responses.go
│   │   └── petstore_client.go
│   ├── swagger_petstore_client.go
│   └── swagger_petstore_embedded_spec.go
├── cmd
│   └── swagger-petstore-server
│       ├── configure_swagger_petstore.go
│       ├── doc.go
│       ├── embedded_spec.go
│       └── main.go
├── models
│   ├── error.go
│   ├── new_pet.go
│   └── pet.go
└── restapi
    └── petstore
        ├── add_pet.go
        ├── add_pet_parameters.go
        ├── add_pet_responses.go
        ├── delete_pet.go
        ├── delete_pet_parameters.go
        ├── delete_pet_responses.go
        ├── find_pet_by_id.go
        ├── find_pet_by_id_parameters.go
        ├── find_pet_by_id_responses.go
        ├── find_pets.go
        ├── find_pets_parameters.go
        ├── find_pets_responses.go
        └── swagger_petstore_api.go

仕様をきっちりと記載さえしていればgodoc等も良しなに生成されているようでした。
この時点でcmdまで生成されているので、

$ go install <your swagger pj>/cmd/swagger-petstore-server
$ swagger-petstore-server
serving swagger petstore at http://127.0.0.1:62665

とするだけでサンプルのサーバが立ち上がる状態になっています。
また、その実装については、cmd/swagger-petstore-server/configure_swagger_petstore.goを見ていただければ、実装すべき内容すぐわかるようになっています。

package main

import (
	"github.com/go-swagger/go-swagger/errors"
	"github.com/go-swagger/go-swagger/httpkit"
	"github.com/go-swagger/go-swagger/httpkit/middleware"

	"github.com/y-matsuwitter/swagger-sample/restapi/petstore"
)

// This file is safe to edit. Once it exists it will not be overwritten

func configureAPI(api *petstore.SwaggerPetstoreAPI) {
	// configure the api here
	api.ServeError = errors.ServeError

	api.JSONConsumer = httpkit.JSONConsumer()

	api.JSONProducer = httpkit.JSONProducer()

	api.AddPetHandler = petstore.AddPetHandlerFunc(func(params petstore.AddPetParams) middleware.Responder {
		return middleware.NotImplemented("operation addPet has not yet been implemented")
	})
	api.DeletePetHandler = petstore.DeletePetHandlerFunc(func(params petstore.DeletePetParams) middleware.Responder {
		return middleware.NotImplemented("operation deletePet has not yet been implemented")
	})
	api.FindPetByIDHandler = petstore.FindPetByIDHandlerFunc(func(params petstore.FindPetByIDParams) middleware.Responder {
		return middleware.NotImplemented("operation find pet by id has not yet been implemented")
	})
	api.FindPetsHandler = petstore.FindPetsHandlerFunc(func(params petstore.FindPetsParams) middleware.Responder {
		return middleware.NotImplemented("operation findPets has not yet been implemented")
	})

}

Clientを触ってみる

clientコードまで生成されているので、これを利用してAPIを叩いてみましょう。

package main

import (
	"log"

	apiclient "github.com/y-matsuwitter/swagger-sample/client"
	"github.com/y-matsuwitter/swagger-sample/client/petstore"
)

func main() {
	api := apiclient.Default.Petstore
	res, err := api.FindPetByID(petstore.FindPetByIDParams{1})
	log.Printf("%+v\n", res)
	log.Println(err)
}

先ほどのsampleのjsonでの仕様書だとpetstore.swagger.ioをhostとして参照する仕様となっていたので、当然上記のサンプルはそちらのhostを叩きに行きます。
ちなみにこの投稿を書いている時点では上記ホストとsampleのjson仕様書の間に乖離があるようで、正常に動作しませんでした。(というかインターネット上に幾つか存在するpetstoreの仕様書が古い?)

最後に

Goでのマイクロサービス的な開発においてはこういったサーバ/クライアント間を統一的に記述できる仕組みからコードを生成してくれる仕組みはありがたいなと感じましたが、まだまだ使用してみた感じでは未完成な部分(日本語での記述で不具合起きるなど)が多く、今のところ自分にとってのswaggerはあくまで仕様書の記述にとどまるのではないかなと思いました。
あと、似たような領域ではjson-hyper-schemaがありますが、そちらとの比較もしてみたいなと思いました。

71
67
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
67

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?