prmdを利用して空のレスポンスを表現する

prmdで生成されるドキュメントは、Response Exampleが自動的に生成されて便利。

f:id:willnet:20171229175710p:plain

しかし、何かを作成するときや何かを削除するときなど、レスポンスボディがなくても問題ないことを表すのが面倒。

prmd/link.md.erb at 928d9cb1c0fa1163bab5f3cb43c81eed4a147aa2 · interagent/prmd を読んで、どのようにResponse Exampleが生成されるかを調べて、空のレスポンスを表現する方法を調べてみた。

方法1: relをemptyにする

これが一番手っ取り早いけど、status codeが202に決め打ちになっている。

方法2: response_example を使う

次のようにresponse_exampleを指定するとResponse Examnpleをカスタマイズできる。若干面倒だけど現状ではこれしか方法がないように見える。

links:
- description: ユーザフォロー API
  href: "/api/user/{(%2Fschemata%2Fuser%23%2Fdefinitions%2Fid)}/follow"
  method: POST
  rel: create
  title: ユーザフォロー API
  schema:
    properties:
      access_token:
        "$ref": "/schemata/session#/definitions/access_token"
    required:
      - access_token
    type: object
  response_example:
    head: HTTP/1.1 201 Created
    body: ''

続、Railsのきれいなコードについて議論する勉強会

Railsのきれいなコードについて議論する勉強会の話の続き。

とりあえずお題を集めてみようと思い、GitHub上にclean-rails-jaというorganizationを作りました*1。下記のIssueで議論のお題になりそうな案を募集しています。

「こういうとき、いつもどうしたら良いか悩むんですよねー」というものがある方は↓にどしどしその内容をご記入ください。

Railsのきれいなコードのお題案 · Issue #1 · clean-rails-ja/conversation

お題が集まってきたらそれを整理して、勉強会に臨めるとよいなと思います。

*1:ginzarbでもよかったけど別件な気もするのでとりあえず分けてみた

Railsのきれいなコードについて議論する勉強会

この件、やりたい気持ちはあるし、いいねたくさんついたので興味ある人がいるのはわかるけど、事前準備のハードルが結構高い。そこをクリアできる案を出すか、もしくは事前準備担当します!みたいな人がいないと開催は難しい。

これまでの経験上、適当に人を集めてもお題はちゃんと集まらない。のでなんらかの工夫が必要。

工夫の案

案というか、思いついたことをそのままダンプしただけです

  • 参加者は全員必ず何らかのお題を出すようにするとどうか
    • 参加人数が激減する
    • 会が開けるレベルで人集まるかが課題
  • 2週間前(1ヶ月前)にはオンライン上にお題が出ているようにするとよりよい
    • 事前にお題に対する案を練っておいたほうが議論深まるはず
    • これだと、勉強会という形式をとらなくてもそのままオンライン上で議論してもよいのでは?という気もする
  • 有志で頑張ってお題をひねり出す
    • 有志いるんですかね…

意見ある人はコメントください

ActionCableでセッションを使う

(追記)ちょっと自信なくなってきた(スタンドアロン版だとちょっと違うのでは?という気がしてきた)ので今度時間のあるときに調べます

Rails Guidesを読むと、Action Cableはセッション使えないと書いてあるのだけど、よくよく考えるとAction Cable はRailsのルーティングにマウントして使う形式だし、そうするとセッション用のRack Middlewareは使われているはずでなんかおかしいぞ…?と思って調べたら普通に

request.session[:user_id]

みたいな感じでセッション情報を取得できた。Rails Guidesはおそらくクッキーセッションを利用して別ドメインでAction Cableのサーバを立ててる前提で書かれてるんじゃないかという気がする。仮に別ドメインでも

  • redisなどのセッションストアを使う
  • Action Cableのサーバをサブドメインにして、セッションクッキーをサブドメインと共有にする

などすれば普通に使えそう(未検証)。

Action Cable Overview — Ruby on Rails Guides

webpacker3のコードをざっと読んだ

webpacker3は、「2から導入されたテスト環境でのlazy compileが開発環境にも入り、webpack-dev-serverの起動が必須ではなくなった」「デフォルト設定類がnpmのパッケージ側に寄せられた」くらいの認識だったのだけど、コード見るとどうやらそれ以外の変更も入っているみたいですね。

  • 開発環境だとWebpacker::DevServerProxyがミドルウェアの先頭に入る
  • Webpacker::DevServerProxyはRack::Proxyを継承している。やっていることは
    • /assets/packs(デフォルトの場合)配下にリクエストが来ている、かつwebpack-dev-serverが起動していたらwebpack-dev-serverにプロキシする
  • 「webpack-dev-serverが起動している」というのは設定しているホスト&ポートに対してTCPソケットで接続を試してつながれば起動しているとみなす
    • webpacker 3.0.1まではここの例外処理に問題があって、例えばdocker-compose環境などを使用しているとErrno::EADDRNOTAVAILなどで死んだりしていた
      • 3.0.2で解消されたはず

webpacker2までは、webpack用のassetsはアプリケーションサーバとは別のwebpack-dev-serverのアドレスに対してリクエストしていたのだけど、webpacker3ではそれがなくなってアプリケーションサーバ内でうまいことしてくれるようになったのだった。

余談

webpackerをアップグレードしたときはyarn upgrade @rails/webpackerも一緒に実行してgemとバージョンを合わせて置いたほうが良さそう(忘れると死にそう)。

headless chromeをdockerで動かすときに注意する点

前提

  • Google Chrome 61.0.3163.100
  • chromedriver 2.3.1
  • Docker 17.03.1-ce
  • docker-compose 1.11.2

注意点

  • dockerがデフォルトで利用しているseccompの設定だとheadless chromeが動かない
  • seccompを変更することはできる

    • dockerコマンドのオプションでseccomp用の設定ファイルを渡すことができる
    • chromeを動かすための設定ファイルを作って公開している人がいる
  • しかし現行のdocker-composeだと、設定ファイルを渡すやり方ができない

    • docker-compose.ymlに一つづつ設定を書いていくことはできるがダルい
    • seccomp:unconfinedのようにしてseccomp自体を無効にすることはできるがセキュリティ的に不安
    • 次のようにCAP_SYS_ADMINを設定することで、↑よりはだいぶマシな感じになる
services:
  app:
    # ...
    cap_add:
      - sys_admin

参考

webpacker2から3へアップグレード

だいたい次のような感じで行けるはず(実際は試行錯誤したのでこの通りにはやっていない)。設定ファイルやpackage.jsonに記載されるpackageなどがだいぶ減った。

  • bundle update webpacker
  • config/webpack 配下を全部消す
  • package.jsonを消す
  • yarn.lockを消す
  • public/packs配下にファイルが有れば消す
  • ./bin/rails webpacker:install
  • ./bin/webpacker などをオーバライドする
  • 差分を見て残すべきものを残す

package.jsonに無駄な指定が残っているのに気付かず、webpackerのバージョン違いが2つ混在する形になっていてしばらく時間吸われた。

それほどjsを使っているわけではないアプリケーションなのでバージョン上げても大差ないのだけど、webpack-dev-serverがなくても大丈夫になったのは大きい。