LoginSignup
9
6

More than 5 years have passed since last update.

Swagger を CentOS6.5 上で動かしてみた

Posted at

Myuon Corp. Advent Calendar 2016 3日目です。

Swagger を vagrant で建てた CentOS6.5 上で動かしてみた

Swagger を業務で使ってみようということになり、Vagrant 上に導入してみました。

Vagrant で CentOS6.5 を建てる方法については、割愛して Swagger とはなにか、導入の仕方と動かし方、扱い方をまとめてみようと思います。

Swagger とはなにか

Swagger とは Restful な API 仕様の記法と、記述するためのツール群です。
API 仕様を yamljson で記述することができます。
何より特徴的なのが yaml, json の編集をブラウザ上で実行する事ができ、ライブプレビューで仕様書風なページが表示されることです。
また、記述したものをプレビューされている仕様書風なページ上で実行することができます。

スクリーンショット 2016-12-02 20.44.12.png

実際に作成した仕様書を元に Server, Client のソースコードをジェネレートすることができるみたいですが、そこはまだ触れていないのでいずれまとめたいと思います。

建てた Vagrant の環境

今回、Swagger の Editor を Vagrant で建てようということになり、ミニマムな状態の CentOS (6.5) を建てました。

  • OS

    $ cat /etc/redhat-release
    CentOS release 6.5 (Final)
    $ uname -a
    Linux swagger 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
    
  • 容量

    $ df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/sda1       7.3G  1.6G  5.4G  24% /
    tmpfs           295M     0  295M   0% /dev/shm
    vagrant         465G  370G   96G  80% /vagrant
    

Swagger の導入

Swagger には node.js 製のもの、 javascript 製のものがあるようです。

まずは、エディタを動かしたいので swagger-editor を導入します。

必要なものは以下のものです。

  • nodejs
  • npm
  • wget
  • http-server
  • swagger-editor

上の3つは yum でインストールしちゃいます。

$ sudo yum install -y nodejs
$ sudo yum install -y npm
$ sudo yum install -y wget

次の、 http-server は node.js 製の HTTP サーバです。
npm でインストールします。

$ npm install -g http-server

単に swagger-editor 内の index.html が HTTP サーバ上で動作すれば良いので、手元に rails があれば public の下に swagger-editor を置いても動作します。
とりあえず動かすのが目的であれば、他のもので代用しても問題ありません。

最後に、swagger-editor の取得です。
wget でソースコードの zip をダウンロードします。

$ wget https://github.com/swagger-api/swagger-editor/releases/download/v2.10.4/swagger-editor.zip

ダウンロードしたものは解凍しましょう。

$ unzip ./swagger-editor.zip

Swagger の動かし方

ようやく、swagger-editor を動かす時が来ました。

http-server swagger-editor

実行すると、次のような出力が得られます。

Starting up http-server, serving swagger-editor
Available on:
  http://127.0.0.1:8081
  http://10.0.2.15:8081
  http://192.168.33.52:8081
Hit CTRL-C to stop the server

ブラウザでアクセスすると見事エディタが起動します。
導入はすごく簡単ですね。

Swagger の扱い方

Swagger の扱い方として、次のものを順にまとめます。

  • 書き方
  • Type
  • プロジェクト

書き方

swagger-editor を起動してアクセスすると、まずエディタにはサンプルの yaml が貼り付けられていて、おおよその書き方はそのサンプルのコメントで分かるようになっています。
また、エディタのステータスバーの File > Open Example... から別のサンプルを開くこともできるので、不足分はそちらで補うこともできそうです。

書き方の解説は yaml 形式で、例に上げるサンプルを petstore_full.yaml としてまとめます。

  • 構成


    ルート階層は次の表のようになっています。

    key 用途
    swagger string swagger のバージョン
    info object API の情報
    host string API のホスト
    basePath string API のベースパス
    schemes array 使用可能なスキームのリスト
    paths object API のパスのリスト
    securityDefinitions: object 認証などのセキュリティの定義
    definitions object モデルのリスト

    それぞれの解説をします。

    swagger はそのまんまですね。
    サンプルでは次のようになっています。

    swagger: "2.0"
    

    info は次のような情報を持ちます。

    key 用途
    description string API がどういうものなのかの説明文
    version string API のバージョン
    title string API のタイトル (プロジェクト名)
    termsOfService string 利用規約ページ
    contact object name をキーとした連絡先
    license object name をキーとしたライセンス名、 url をキーとしたライセンス条文のページのリンク

    ミニマムで設定するのであれば、 description , title , version だけで良さそうです。
    サンプルでは次のようになっています。

    info:
    description: |
    This is a sample server Petstore server.
    
    [Learn about Swagger](http://swagger.io) or join the IRC channel `#swagger` on irc.freenode.net.
    
    For this sample, you can use the api key `special-key` to test the authorization filters
    version: "1.0.0"
    title: Swagger Petstore
    termsOfService: http://helloreverb.com/terms/
    contact:
    name: apiteam@swagger.io
    license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
    

    host , basePath はそのまんまですね。
    サンプルでは次のようになっています。

    host: petstore.swagger.io
    basePath: /v2
    

    schemes は利用可能なスキームを列挙します。
    サンプルでは次のようになっています。

    schemes:
    - http
    

    これを増やすと、プレビューページで実行する際のスキームの選択肢が増えます。


    paths は一番重要なところです。
    次のような情報を持ちます。
    ※ 階層が深くなるので . で連結して階層を表現します。

    key 用途
    /pets/{petId} string リソースへのパス
    /pets/{petId}.get object
    /pets/{petId}.get.tags array Swagger の仕様書上でフィルタするためのタグ
    /pets/{petId}.get.summary string エンドポイントに対する概要
    /pets/{petId}.get.description string エンドポイントに対する説明
    /pets/{petId}.get.operationId string operationId FIXME
    /pets/{petId}.get.produces array 出力可能なコンテンツタイプのリスト
    /pets/{petId}.get.parameters array パラメータの定義のリスト
    /pets/{petId}.get.parameters[].in string パラメータの配置先 path か `query
    /pets/{petId}.get.parameters[].name string パラメータ名
    /pets/{petId}.get.parameters[].description string パラメータの説明
    /pets/{petId}.get.parameters[].requied boolean 必須かどうか
    /pets/{petId}.get.parameters[].type string
    /pets/{petId}.get.parameters[].format string 型のフォーマット
    /pets/{petId}.get.response object レスポンスの定義
    /pets/{petId}.get.response."404" object 404 レスポンスの定義
    /pets/{petId}.get.response."404".description string 404 レスポンスの説明
    /pets/{petId}.get.response."200" object 200 レスポンスの定義
    /pets/{petId}.get.response."200".description string 200 レスポンスの説明
    /pets/{petId}.get.response."200".schema object 200 レスポンスのボディ
    /pets/{petId}.get.security array セキュリティの定義
    /pets/{petId}.get.security.api_key array? [] を指定すると未指定にできる FIXME
    /pets/{petId}.get.security.petstore_auth array 後述の securityDefinitions への参照となる key

    /pets/{petId} のように {} を使用することでプレースホルダにすることができます。

    get の部分は post とすることで POST の定義を作成できます。

    tags は、Swagger のプレビューページでフィルタリングするためのもののようです。
    summary, tags, produces はオプショナルです。
    produces はルート階層に配置することも可能です。

    parameters に定義するオブジェクトは in キーに対して path を与えると、path で設置したプレースホルダに対応します。
    in キーに対して query を与えると、 ?parameter.key= のようなURLのクエリ部に対応します。
    parameterstype は後述します。

    response の子要素のキーは HTTP ステータスコードか default という文字列を指定する必要があります。
    5xx とかできないのはちょっと不便に思いました。しかも、default って、、、。

    security の子要素は、後述の securityDefinitions を参照することができるようです。

    サンプルでは次のようになっています。

    /pets/{petId}:
    get:
      tags:
        - pet
      summary: Find pet by ID
      description: Returns a pet when ID < 10.  ID > 10 or nonintegers will simulate API error conditions
      operationId: getPetById
      produces:
        - application/json
        - application/xml
      parameters:
        - in: path
          name: petId
          description: ID of pet that needs to be fetched
          required: true
          type: integer
          format: int64
      responses:
        "404":
          description: Pet not found
        "200":
          description: successful operation
          schema:
            $ref: "#/definitions/Pet"
        "400":
          description: Invalid ID supplied
      security:
        - api_key: []
        - petstore_auth:
          - write_pets
          - read_pets
    

    securityDefinitions は次のような情報を持ちます。

    key 用途
    api_key object api_key オブジェクトの定義
    api_key.type string FIXME
    api_key.name string FIXME
    api_key.in string FIXME
    petstore_auth object FIXME
    petstore_auth.type string 認証方式
    petstore_auth.authorizationUrl string 認証を行うページへのURL
    petstore_auth.flow string FIXME
    petstore_auth.scopes array FIXME

    全体的に未確認なので、早急に確認してまとめたいと思います。
    サンプルでは次のようになっています。

    securityDefinitions:
    api_key:
    type: apiKey
    name: api_key
    in: header
    petstore_auth:
    type: oauth2
    authorizationUrl: http://petstore.swagger.io/api/oauth/dialog
    flow: implicit
    scopes:
      write_pets: modify pets in your account
      read_pets: read your pets
    

    definitions はいわゆる モデル の定義です。
    次のような情報を持ちます。

    key 用途
    Pet object Pet オブジェクトの定義
    Pet.type string Pet オブジェクトの型
    Pet.required array Pet オブジェクトのプロパティの内必須なもののキーのリスト
    Pet.properties object Pet オブジェクトのプロパティの定義
    Pet.properties.id object Pet オブジェクトのプロパティ id の定義
    Pet.properties.id.type string Pet オブジェクトのプロパティ id の型
    Pet.properties.id.format string Pet オブジェクトのプロパティ id のフォーマット
    Pet.properties.name string Pet オブジェクトのプロパティ name の定義
    Pet.properties.name string Pet オブジェクトのプロパティ name の定義
    Pet.properties.name.type string Pet オブジェクトのプロパティ name の型
    Pet.properties.name.example string Pet オブジェクトのプロパティ name の例

    ルート階層のキー名がモデル名になります。
    具体的なところは type の説明を参照してください。

    サンプルでは次のようになっています。

    Pet:
    type: object
    required:
      - name
      - photoUrls
    properties:
      id:
        type: integer
        format: int64
      category:
        $ref: "#/definitions/Category"
      name:
        type: string
        example: doggie
      photoUrls:
        type: array
        items:
          type: string
      tags:
        type: array
        items:
          $ref: "#/definitions/Tag"
      status:
        type: string
        description: pet status in the store
    
  • Type


    type には 次のものがあります。

    • string
    • float
    • boolean
    • array<?>
    • integer
    • object

    string , float , boolean , array は特に解説することはありません。
    上の解説の中には出てきませんでしたが float も利用できます。
    Yaml: types を参照してください。
    ※ rails で yaml を利用する分には気づきませんでしたが、 キーに対して子要素もない、設定値もないと言うのは許可されないようです。

    integer には format がセットになります。
    format をキーとして、 int32int64 を指定する事ができます。

    object はいわゆるハッシュです。

    いずれもキーを $ref とすることで、設定値を参照にすることができます。
    この時の設定値は例えば "#/definitions/Pet" のようになります。

  • プロジェクト


    swagger を npm でインストールすると、swagger コマンドが利用できるようになります。

    この swagger コマンドには project という、サブコマンドがあり、次の機能があります。

    Commands:
    
    create [options] [name]              Create a folder containing a Swagger project
    start [options] [directory]          Start the project in this or the specified directory
    verify [options] [directory]         Verify that the project is correct (swagger, config, etc)
    edit [options] [directory]           open Swagger editor for this project or the specified project directory
    open [directory]                     open browser as client to the project
    test [options] [directory_or_file]   Run project tests
    generate-test [options] [directory]  Generate the test template
    

    肝となる edit は、どうもブラウザを起動して swagger-editor を開くもののようで、Vagrant で建てた VM では次のようなエラーが出ました。

    $ swagger project edit
    Starting Swagger Editor.
    Opening browser to: http://127.0.0.1:43390/#/edit
    { [Error: Command failed: /bin/sh: xdg-open: command not found
    ] killed: false, code: 127, signal: null }
    

    いずれ解決してやりたいと思います。
    それはさておき、ひとまずプロジェクトを作ります。

    次のコマンドで、プロジェクトを作成することができます。

    swagger project create <プロジェクト名>
    

    このコマンドを実行すると、次のような内容物を持つディレクトリが生成されます。

    $ ls -l
    total 28
    drwxr-xr-x 6 vagrant vagrant 4096 Dec  2 05:11 api
    -rw-r--r-- 1 vagrant vagrant  546 Dec  2 05:11 app.js
    drwxr-xr-x 2 vagrant vagrant 4096 Dec  2 05:11 config
    drwxrwxr-x 6 vagrant vagrant 4096 Dec  2 05:11 node_modules
    -rw-r--r-- 1 vagrant vagrant  425 Dec  2 05:11 package.json
    -rw-r--r-- 1 vagrant vagrant   31 Dec  2 05:11 README.md
    drwxr-xr-x 3 vagrant vagrant 4096 Dec  2 05:11 test
    

    作成した swagger の定義ファイルは、 ./api/swagger/ に配置します。

    Git 管理に載せる場合は、まとまっていたほうがスッキリするのでひとまずこのプロジェクトにしたもので扱う予定です。
    もっといい方法がわかったらまとめたいと思います。

    また、他の機能はまだ試せていないので、そちらも試してまとめる予定です。

まとめ

実際、swagger-editor は日本語に弱いらしく、変な入力になることが多々あります。
あまり使いやすいとは言いづらいですが、候補も出ますし、たまにテキスト全体をカット&ペーストすればエラーもちゃんと出してくれます。

プレビューのページはモデルあたりは非常に見難く、そのまま PDF化すれば納品物にできるぜというものではありません。

ドキュメント化という点では Swagger2Markup などの別のツールもあるみたいですが、まだ触れていないので色々試してまとめていきたいと思います。

それと、こういうものこそ Docker と連携しやすいっぽいですね。

まぁ、何にしろ yaml で記述できる手軽さは良いですね。
ちゃんとメンテされるドキュメンテーションへの第一歩ということで。


明日は @nullpopon@github さんです。
どんなことを記事にしてくれるのか楽しみです。

9
6
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
9
6