くりーむわーかー

プログラムとか。作ってて ・試しててハマった事など。誰かのお役に立てば幸いかと。 その他、いろいろエトセトラ。。。

file

Swaggerのアレコレ

Swaggerを使ってAPIのドキュメントを作る話。

公式

Swagger-EditorとかUIとか使えばとりあえずすぐ使える。

公式のツール群は素晴らしいと思うのですが、

ある程度規模が大きくなると、ちょっと無理。

何でかって言うと、ソースが1ファイルだから。

大きくなると行数とか普通に万超えるので。

メンテが無理。

あと、Swagger-UIって1ページに全部ずらっと並べるので

数が多くなってくるとますます無理。

なので、ソースのyamlファイルを分割するのと、

静的なHTMLファイルを作るコンバータみたいなのが欲しい。

と思ってたらやっぱりありますね。

色々あるのですが、公式がまとめてる一覧はこちら

で、最終的に下記の構成にした

Yaml⇒HTMLのコンバータはどれもYamlファイル自体は1ファイルにまとまってないとダメなので、

分割したYamlを一つのファイルにまとめるツールが必要。

で、それをやるのに「multi-file-swagger」と「swagger-merger」があるのですが(他にもあると思うけど)、今回は「swagger-merger」を利用。npmのサイト的にこっちの方がちゃんとドキュメント書いてそうだったので。そういうの大事。

npm install --save-dev swagger-merger

# 実行はこんな感じ
swagger-merger -i ./src/index.yaml -o swagger-tmp.yaml

YAMLが出来たらRedocでHTMLにする。

npm install --save-dev redoc-cli

# 実行はこんな感じ
redoc-cli bundle swagger-tmp.yaml

で、これだと修正しながらブラウザで確認できないので、

なんちゃってホットリロードが出来るようにする。

# 必要なモジュール
npm install --save-dev npm-run-all
npm install --save-dev watch
npm install --save-dev light-server

# ソースディレクトリの更新を監視して、更新されたらmakeを流す
watch \"npm run make\" ./src

# HTMLを監視して更新されたらホットリロードする
light-server -s ./dist -p 4000 -w \"./dist/*.html # # reload\"

もろもろやったサンプルはここにあげた。

ファイルの分割の書き方なんかも↑のリポジトリのsrc内参照。

あと、Redocも素晴らしいのですが、若干ん?って思うところもある。

左メニューの各APIへのリンクがsummryになってるのですが、

ここってURLというかYAMLのタグにならないもんだろうか。。。

他のHTML作るツールも軒並みsummary使ってるので、こっちが主流なのかしら?

axiosで取得した画像データを保存とか表示とかする

VueでUIを作ってて、axios使用でajaxで画像ファイルを取得した後に、

そのデータを表示したり、ローカルに保存したりしたい。

その場合のやり方。

//リクエストヘッダでコレつけた方がいいっぽ
const config = {
  responseType: 'arraybuffer'
}

//サーバに送信
this.$axios
.post('http://hogehoeg/sample.png', { data: 'somedata'}, config)
.then(response => {
  //base64でエンコードしたい場合
  let bstr = new Buffer(response.data, 'binary').toString('base64')
  
  //blobオブジェクトにしたい場合
  let blob = new Blob([response.data], { type: 'image/png' })

  //imgタグをidでとって、srcにblobのObjectURLを突っ込んで画像表示する
  let img = document.getElementById('img_tag_id')
  let url = window.URL || window.webkitURL
  img.src = url.createObjectURL(blob)
  
  //保存させたい場合(ダウンロードっぽくさせたい場合)
  let link = document.createElement('a')
  link.href = window.URL.createObjectURL(blob)
  link.download = 'download-filename.png'
  link.click()

  //Vueで別のコンポーネントにデータ渡したい場合はこんな感じ?
  this.imgdata = response.data
})

base64でやる場合は、画像サイズは32kb未満くらいで考えた方が良いのかしら。まーあんま大きい画像はやめた方がよさそうですね。

ajaxで取ってきた画像ファイルとかをダウンロードっぽく保存させたい場合は前述の感じでやるっぽ。リンク作って、ローカルのオブジェクトのURLを突っ込んで中で、Clickを発火させてる感じ?

ちょっとイレギュラーなやらせ方のような気もするんだけど、StackOverFlowとかいろいろ見てるとこのやり方しかないっぽいですかね?

で、いい感じにまとめてくれるのが↓のGitHubのリポジトリ

https://github.com/kennethjiang/js-file-download/blob/master/file-download.js

IE11だと上述のやり方じゃ上手くいかないらしく、それにも↑のリポジトリは対応してる。

これ使った方がいいと思う。車輪の再発明は控えたい。

あと、vueでaxios使う場合、下の感じで書くと、中でthisが使えない。

this.$axios
.post('http://hogehoeg/sample.png', { data: 'somedata'}, config)
.then(function(response){
  this.dataval = ''//これ無理
})

で、これをやるには呼ぶ前に「let self = this」みたいにしておくのが昔見たやり方なんだけど、

最近の書き方的にはアロー関数でやるとthisもいける。

this.$axios
.post('http://hogehoeg/sample.png', { data: 'somedata'}, config)
.then(response => {
  this.dataval = ''//これいける
})
問合せ