Slide 1

Slide 1 text

RubyKaigi を振り返ってみた

Slide 2

Slide 2 text

自己紹介 1 ● Sansan 株式会社で Ruby 書いてます! ● 好きな言語は Ruby です! ● @pekepek

Slide 3

Slide 3 text

RubyKaigi を振り返ってみた

Slide 4

Slide 4 text

ご飯がおいしかったな

Slide 5

Slide 5 text

4

Slide 6

Slide 6 text

今年もノベルティが豪華だったな

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

貴重な発表がいっぱい聞けたな

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

振り返ってみたら 9 ● 今年も最高に楽しかった ● 特にサバと博多ラーメンは最高だった ● ヨーヨーは毎年楽しい ● 刺激的な発表がいっぱいあった

Slide 11

Slide 11 text

まずい! 全然 LT 出来るような振り返りがない!

Slide 12

Slide 12 text

こんな飯の話だけで LT 終われない...

Slide 13

Slide 13 text

このままじゃ怒られちゃう! ということで急遽興味のあった Curses と Committee を触ったので話します!

Slide 14

Slide 14 text

ぼくの After RubyKaigi

Slide 15

Slide 15 text

Curses をさわったお話

Slide 16

Slide 16 text

Ruby Curses 15 ● 4/19 14:20 - の Shugo Maeda さんの発表 Terminal curses で 紹介されたライブラリ ● C の curses ライブラリの Ruby binding ○ 呪いって意味らしい ○ Terminal の操作が可能 → これで自由に文字色を変えられるエディタを作ってみよう! (最終的に Qiita で色がつく形式で保存出来るといいな)

Slide 17

Slide 17 text

Hello Curses 16 Curses.init_screen # 画面の初期化 Curses.setpos(4, 10) # カーソルを x = 10, y = 4 の座標に移動 Curses.addstr('Hello, Curses') # 引数の文字列を表示 Curses.addch('.') # 一文字を表示 Curses.getch # stdin から一文字の入力を受け付ける Curses.setpos(5, 10) Curses.getstr # stdin から文字列の入力を受け付ける Curses.setpos(6, 10) Curses.addstr('bye') Curses.refresh # 画面の更新 Curses.close_screen # 画面を閉じる

Slide 18

Slide 18 text

カーソル移動 17 Curses.stdscr.scrollok(true) # スクロール可能にする(false だとスクロールしない) Curses.stdscr.scrl(1) # 引数の数だけ下にスクロール(マイナスも指定可能) 文字列削除 Curses.deleteln # 行の表示削除 Curses.delch # カーソル位置の表示削除

Slide 19

Slide 19 text

画面制御 18 Curses.noecho # 入力を画面に表示しない Curses.echo # 入力を画面に表示する Curses.stdscr.maxx # 最大 x 座標 Curses.stdscr.maxy # 最大 y 座標 Curses.cols # 画面の列数 Curses.lines # 画面の行数

Slide 20

Slide 20 text

特殊文字の入力操作 19 # arrow key などの function key を押した際に一文字の値を返すようにする Curses.stdscr.keypad = true case Curses.getch # key の入力値に対応する値を定数で全て定義している when Curses::Key::DOWN Curses.addstr('cursor_down') when Curses::Key::UP Curses.addstr('cursor_up') end

Slide 21

Slide 21 text

文字色を変更する 20 # 色の使用を開始 Curses.start_color # color の定義、id, 文字色, 背景色 Curses.init_pair(1, Curses::COLOR_BLUE, Curses::COLOR_WHITE) # 色を設定、定義した color pair を id で指定して渡す # attrset 自体は色の設定以外にも bold など字体の設定が出来る Curses.attrset(Curses.color_pair(1))

Slide 22

Slide 22 text

こんなのを組み合わせてごちゃごちゃして エディタを作った

Slide 23

Slide 23 text

デモ

Slide 24

Slide 24 text

Curses 感想 23 ● カーソルの操作がエスケープシーケンスに比べて簡単でいい感じ ● 他にも Window や Form の定義など便利そうな IF がいっぱいあって楽しそう ● pry などで見れないので debug に苦労した

Slide 25

Slide 25 text

Committee をさわったお話

Slide 26

Slide 26 text

いや、なんとか動作できるものは作れたけど、 こんな出来損ないのエディタだけで LT 乗り切れない...

Slide 27

Slide 27 text

ということで Committee もさわりました!

Slide 28

Slide 28 text

Committee 27 ● 4/18 13:30 - ota さんの発表 How to use OpenAPI3 for API developer で紹介されたライブラリ ● OpenAPI で API リクエスト・レスポンスの検証が可能 ● ちょうど API Blueprint から OpenAPI 3.0 に移行したいと考えていた ○ 基本的な Web API の仕様は Blueprint で書いて、JSON Schema で validation ○ API Gateway の仕様書は OpenAPI 3.0 で書いている ○ Swagger UI が見やすく、Swagger Editor など周辺ツールも豊富 → 全て OpenAPI 3.0 に移行しようというチームの流れに → しかし、ver 3.0 に対応した validator が見つからず、断念していた → Committee が解決してくれる!!(お世話になります :dogeza: )

Slide 29

Slide 29 text

ということで 2 時間くらいカタカタやってたら 対応できました

Slide 30

Slide 30 text

なんてお手軽なんだ Committee (お世話になります :dogeza:)

Slide 31

Slide 31 text

やったこと

Slide 32

Slide 32 text

Gem install 31 gem 'committee' group :test do # レスポンスのテストを Rails (というか RSpec?) で使いやすいように拡張してくれている gem 'committee-rails' end

Slide 33

Slide 33 text

Response Validation 32 describe 'GET /api/path/to' do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('path', 'to', 'schema.yml').to_s, prefix: '/api' # 必要なら設定する } end specify 'validate response' do get '/api/path/to', headers: {CONTENT_TYPE: 'application/json', ACCEPT: 'application/json'} assert_schema_conform end end

Slide 34

Slide 34 text

簡単!

Slide 35

Slide 35 text

これだけで検証可能 例外ケースも OpenAPI で記述している通りに値を確認してくれる

Slide 36

Slide 36 text

とはいえ、ハマったポイントもあったので紹介

Slide 37

Slide 37 text

ハマりポイント 1 ぼくらの OpenAPI version が 3.0.1 だった

Slide 38

Slide 38 text

37 describe 'GET /api/path/to' do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('path', 'to', 'schema.yml').to_s, prefix: '/api' # 必要なら設定する } end specify 'validate response' do get '/api/path/to', headers: {CONTENT_TYPE: 'application/json', ACCEPT: 'application/json'} assert_schema_conform end end 実際はこの部分が version 3.0.1 だと意図通りに 動作しない

Slide 39

Slide 39 text

OpenAPI の parse 38 module Committee module Drivers ... def self.load_from_data(hash) if hash['openapi'] == '3.0.0' parser = OpenAPIParser.parse(hash) return Committee::Drivers::OpenAPI3.new.parse(parser) end ... 内側で load_from_data が呼ばれている OpenAPI3 の Driver を呼びたいが ver 3.0.0 のときしか呼ばれない

Slide 40

Slide 40 text

Response Validation の変更 39 describe 'GET /api/path/to' do include Committee::Rails::Test::Methods def committee_options @committee_options ||= begin h = YAML.load_file(Rails.root.join('path', 'to', 'schema.yml').to_s) parser = OpenAPIParser.parse(h) schema = Committee::Drivers::OpenAPI3.new.parse(parser) {schema: schema, prefix: '/api'} end end Driver を自分で指定して、schema を option に 渡す

Slide 41

Slide 41 text

ハマりポイント 2 responses を $ref で components にまとめていたら 展開されずに読み込まれなかった

Slide 42

Slide 42 text

元々の OpenAPI の定義 41 get: ... responses: '200': $ref: '#/components/responses/...' '400': $ref: '#/components/responses/BadRequest' '404': ... 元々 responses を components に定義していた これが Response の検証時には展開されない

Slide 43

Slide 43 text

OpenAPI を再定義 42 get: ... responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/...' '400': description: 不正なリクエスト content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': ... 展開した形で定義すると正しく読み込む ● OpenAPI の書き方が悪いのか・ Committee が対応していないのか・ Committee の使い方が間違っているのか、 まではわからなかった ● parse で Components Object を Components class にまとめるのだが、 そこには含まれいたので parse 時は展開できてい るよう

Slide 44

Slide 44 text

Request Validation 43 Rails.application.configure do ... h = YAML.load_file(Rails.root.join('path', 'to', 'schema.yml').to_s) parser = OpenAPIParser.parse(h) schema = Committee::Drivers::OpenAPI3.new.parse(parser) config.middleware.use Committee::Middleware::RequestValidation, {schema: schema, prefix: '/api'} end

Slide 45

Slide 45 text

Committee 感想 44 ● Blueprint のときは手動で JSON Schema に変換していたので、とても楽 ● わざわざ個別に Controller ごとに Schema を読み込ませる必要もない ● 悩み ○ 各 API ごとに YAML を定義しているのだが、 Committee だと一つのファイルで定義している前提になっている(?) ○ そのような構成にした方がいいのだろうか ● ただこれで OpenAPI 3.0 に全面移行できるな

Slide 46

Slide 46 text

まとめ

Slide 47

Slide 47 text

46 ● RubyKaigi は美味しいから現地に行ったほうがいい ● LT をするとちゃんと勉強するからやったほうがいい ● 本当に大切なのは After RubyKaigi