Slide 1

Slide 1 text

RSpecʹΑΔ Open APIࣗಈςετ ~STORESͷݱ৔͔Β~ hey × Da Vinci Studio ʙϓϩμΫτͷ੒௕Λࢧ͍͑ͯΔཪଆʢٕज़ͱ૊৫ʣʙ 2020.08.27 @fuqda90

Slide 2

Slide 2 text

About me fuqda (;ͩ͘) • 2017೥11݄ʙݱࡏ STORESόοΫΤϯυΤϯδχΞ (Ruby) • 2018೥2݄ʙݱࡏ Tama.rbͱ͍͏஍ҬRubyίϛϡχςΟ΍ͬͯ·͢ • झຯ͸ΪλʔͰ͢(ίϩφ͕མͪண͍ͨΒόϯυ׆ಈ͍ͨ͠) Twitter : ˏfuqda90

Slide 3

Slide 3 text

ࠓճ͓࿩͢Δ͜ͱ • Open APIͱؔ࿈༻ޠͷઆ໌(͸͡Ίͯͷํ޲͚) • STORESͰͷRSpecΛ࢖ͬͨOpen API (APIυΩϡϝϯτ)ͷࣗಈςετ·ͰͷܦҢ • RSpec ❌ Open APIͷӡ༻ͱ൵تަʑ

Slide 4

Slide 4 text

ࠓճ͓࿩͠ͳ͍͜ͱ • RSpecͦͷ΋ͷͷ஌ݟ΍ಥͬࠐΜͩ಺༰ • RSpec ❌ Open API ͷ ϕετϓϥΫςΟεతͳ࿩ (໛ࡧதͰͯ͠…

Slide 5

Slide 5 text

໨࣍ ɾOpen APIͱؔ࿈༻ޠͷઆ໌ ɾOpen APIࣗಈςετӡ༻ ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 6

Slide 6 text

໨࣍ ▶︎ Open APIͱؔ࿈༻ޠͷઆ໌ ɾOpen APIࣗಈςετӡ༻ ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 7

Slide 7 text

Open APIͬͯͳʹʁ • REST APIͷAPIυΩϡϝϯτͷ هड़ϑΥʔϚοτͷ͜ͱ • ͦͷϑΥʔϚοτʹج͍ͮͯॻ͔Εͨ APIυΩϡϝϯτΛ ※Open API SpecificationͱݺͿ ※ ҰൠతʹOpen APIͱݴͬͨ৔߹͸ Open API SpecificationΛҙຯ͢Δ͜ͱ͕ଟ͍

Slide 8

Slide 8 text

Open APIؔ࿈༻ޠ Swagger

Slide 9

Slide 9 text

SwaggerͬͯͳΜ͚ͩͬʁ • Open APIͷ࢓༷ʹج͍ͮͨAPIυΩϡϝϯτ ͷ࡞੒Λࢧԉ͢ΔΦʔϓϯιʔεπʔϧ܈ • Open API Initiative(OAI)ͱ͍͏REST APIͷ ΠϯλʔϑΣʔεͷඪ४Խஂମʹ࠾༻͞Εͨ

Slide 10

Slide 10 text

ओͳSwaggerπʔϧ • Swagger Edittor (ϒϥ΢β΍ϩʔΧϧͰOpen APIΛهड़ग़དྷΔΤσΟλʔ) • Swagger UI (Open APIͷهड़ΛಈతʹAPIυΩϡϝϯτͱͯ͠ϨϯμϦ ϯά͢Δπʔϧ) • Swagger Codegen (Open API͔Βαʔόʔ/ΫϥΠΞϯτͷίʔυΛੜ੒͢Δ πʔϧ)

Slide 11

Slide 11 text

͞ΒʹৄࡉΛ஌Γ͍ͨ৔߹͸ެࣜΛࢀর

Slide 12

Slide 12 text

໨࣍ ɾOpen APIͱؔ࿈༻ޠͷઆ໌ ɾOpen APIࣗಈςετӡ༻ ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 13

Slide 13 text

໨࣍ ɾOpen APIͱؔ࿈༻ޠͷઆ໌ ▶︎ Open APIࣗಈςετӡ༻ ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 14

Slide 14 text

ςετͷ࿩ͷલʹSTORESͰ Open APIΛӡ༻͍ͯ͘͠Α͏ʹ ͳͬͨܦҢΛઆ໌

Slide 15

Slide 15 text

STORESͷ ϑϩϯτ/όοΫΤϯυͷঢ়ଶ ϑϩϯτΤϯυ όοΫΤϯυ ˞Ұ෦"OHVMBS+4 ݱࡏ ϦΫΤετ Ϩεϙϯε +40/

Slide 16

Slide 16 text

Open APIಋೖҎલɿ ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ ϑϩϯτΤϯυ όοΫΤϯυ ˞Ұ෦"OHVMBS+4 ݱࡏ "1*ͷεΩʔϚ͕ ཉ͍͠Ͱ͢ʂ Ͳ͏͠Α͏ʜ 

Slide 17

Slide 17 text

Open APIಋೖҎલɿ ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ ϑϩϯτΤϯυ όοΫΤϯυ ˞Ұ෦"OHVMBS+4 ݱࡏ ͋Γ͕ͱ͏ ͍͟͝·͢ ࠔ࿭ FTBʹॻ͖·ͨ͠

Slide 18

Slide 18 text

Open APIҎલɿ ͱ͋ΔҊ݅ͰͷAPIυΩϡϝϯτ

Slide 19

Slide 19 text

markdownͷAPIυΩϡϝϯτΛ ࢓༷มߋͷͨͼʹ๨Εͣʹ ߋ৽͢Δͷ͠ΜͲ͍…

Slide 20

Slide 20 text

͕࣌ܦͪ… ⏳ Open APIΛ࢖ͬͨ։ൃ΁Ҡߦ

Slide 21

Slide 21 text

Open APIಋೖҎ߱ɿ ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ ϑϩϯτΤϯυ όοΫΤϯυ ˞Ұ෦"OHVMBS+4 ݱࡏ "1* εΩʔϚ Λڠۀͯ͠࡞੒

Slide 22

Slide 22 text

Open APIಋೖҎ߱ɿ ͱ͋ΔҊ݅Ͱͷϑϩϯτ/όοΫΤϯυͷ։ൃ ϑϩϯτΤϯυ .PDLαʔόʔ ˞Ұ෦"OHVMBS+4 ݱࡏ IUUQBQJWCMPHT Ϩεϙϯε +40/ ˞4XBHHFSπʔϧ 4UPQMJHIU4UVEJP࢖༻

Slide 23

Slide 23 text

Α͏΍͘ςετͷ࿩

Slide 24

Slide 24 text

APIεΩʔϚΛϑϩϯτ/όοΫΤϯ υͰڞ༗ग़དྷΔΑ͏ʹͳͬͨ ͱ͸͍͑… εΩʔϚͷ༗ޮੑνΣοΫΛ खಈͰ΍Δͱഁ୼ͦ͠͏

Slide 25

Slide 25 text

ࣗಈԽͩʂʂʂʂ

Slide 26

Slide 26 text

Open APIࣗಈςετ ςετίʔυ 0QFO"1* "1*υΩϡϝϯτ

Slide 27

Slide 27 text

Open APIࣗಈςετ ςετίʔυ 0QFO"1* "1*υΩϡϝϯτ ίίͷ࢓૊ΈΛৄ͘͠

Slide 28

Slide 28 text

RSpec ❌ Open APIͷৄࡉ committee-rails ͱ͍͏ gemΛ࢖ͬͯ RSpecͰAPIεΩʔϚ(YAML)ͱ APIͷࠩ෼ΛνΣοΫ

Slide 29

Slide 29 text

committee-railsͷ࢖͍ํ 
 
 describe 'Api::V1::BlogsController', type: :request do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('APIεΩʔϚͷύε'), old_assert_behavior: false } end describe 'GET /api/v1/blogs' do it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do get '/api/v1/blogs' assert_response_schema_confirm end end end

Slide 30

Slide 30 text

committee-railsͷ࢖͍ํ 
 
 describe 'Api::V1::BlogsController', type: :request do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('APIεΩʔϚͷύε'), old_assert_behavior: false } end describe 'GET /api/v1/blogs' do it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do get '/api/v1/blogs' assert_response_schema_confirm end end end APIεΩʔϚͷಡΈࠐΈ

Slide 31

Slide 31 text

committee-railsͷ࢖͍ํ 
 
 describe 'Api::V1::BlogsController', type: :request do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('APIεΩʔϚͷύε'), old_assert_behavior: false } end describe 'GET /api/v1/blogs' do it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do get '/api/v1/blogs' assert_response_schema_confirm end end end εΩʔϚݕূ༻ϝιουͷఆٛݩΫϥεͷಡΈࠐΈ

Slide 32

Slide 32 text

committee-railsͷ࢖͍ํ 
 
 describe 'Api::V1::BlogsController', type: :request do include Committee::Rails::Test::Methods def committee_options @committee_options ||= { schema_path: Rails.root.join('APIεΩʔϚͷύε'), old_assert_behavior: false } end describe 'GET /api/v1/blogs' do it 'Ϩεϙϯε͕APIυΩϡϝϯτͱҰக͢Δ' do get '/api/v1/blogs' assert_response_schema_confirm end end end APIεΩʔϚͱ࣮ࡍͷAPIͷ஋ͷݕূ

Slide 33

Slide 33 text

໨࣍ ɾOpen APIͱؔ࿈༻ޠͷઆ໌ ɾOpen APIࣗಈςετӡ༻ ɾOpen APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 34

Slide 34 text

໨࣍ ɾOpen APIͱؔ࿈༻ޠͷઆ໌ ɾOpen APIࣗಈςετӡ༻ ▶︎ Open APIࣗಈςετӡ༻͔Βͷֶͼ

Slide 35

Slide 35 text

ศརʹͳͬͨ൓໘ ৭ʑͱࢼߦࡨޡͨ͠
 ͜ͱ͕͋ͬͨͷͰ
 ͦͷ͓࿩Λ…

Slide 36

Slide 36 text

ࣄҊ1: ͋Ε…ςετམͪͳ͘ͳ͍ʁ

Slide 37

Slide 37 text

APIΛมߋͯ͠ɺ ࣮૷ͱεΩʔϚͷؒʹ ࠩ෼͕͋Δͷʹ CI͕௨ͬͯΔ…

Slide 38

Slide 38 text

committee-railsͷམͱ݀͠⛳

Slide 39

Slide 39 text

assert_request_schema (assert_response_schema)Ͱݕূ͞ΕΔύϥϝʔλ͸ required Ͱࢦఆͨ͠ϑΟʔϧυ͚ͩ post: summary: POST /api/v1/blogs description: ϒϩά࡞੒API tags: - blog requestBody: content: application/json: type: object properties: blog: type: object required: - title - content ݟͯΔͷίί͚ͩ

Slide 40

Slide 40 text

ղܾࡦ

Slide 41

Slide 41 text

ޙड़͢ΔͷͰҰ୴εΩοϓ

Slide 42

Slide 42 text

ࣄҊ2: ҟৗܥͷAPIεΩʔϚͱ ͦͷςετͲ͏͢Δʁ

Slide 43

Slide 43 text

ྫ͑͹͜Μͳ৔߹ͷ࿩ class BlogsController < ApplicationController ※தུ
 def create
 ※தུ begin ※ਖ਼ৗܥͷॲཧ rescue ::Mongoid::Errors::Validations render status: :bad_request, json: { errors: blog.errors } end end

Slide 44

Slide 44 text

ྫ͑͹͜Μͳ৔߹ͷ࿩ class BlogsController < ApplicationController ※தུ
 def create
 ※தུ begin ※ਖ਼ৗܥͷॲཧ rescue ::Mongoid::Errors::Validations render status: :bad_request, json: { errors: blog.errors } end end ͦ΋ͦ΋ίίͷ෦෼ͷৄࡉΛͲ͜·Ͱ APIυΩϡϝϯτʹ࢒͔͢໰୊

Slide 45

Slide 45 text

ղܾࡦ

Slide 46

Slide 46 text

YAMLʹ͸࠷௿ݶͷεςʔλείʔυͱ Τϥʔ಺༰ͷ഑ྻ͕ฦͬͯ͘Δ͜ͱ͚ͩΛఆٛ responses: ※தུ '400': description: Bad Request content: application/json: schema: type: object properties: errors: type: array blogs: {} required: - errors Τϥʔ഑ྻ͕ඞਢͰ͋Δ ͜ͱ͚ͩఆٛ͢Ε͹Α͠ ͱͨ͠

Slide 47

Slide 47 text

͜ͷ෦෼ʹ͍ͭͯ͸౰֘API͕ ಛఆগ਺ͷ։ൃऀ޲͚(SSKDs)APIͳͷͰ ෆಛఆଟ਺ͷ։ൃऀ޲͚(LSUDs)API΄Ͳ γϏΞͰ͸ͳ͍఺͕͋Δ͔΋…

Slide 48

Slide 48 text

ࣄҊ3: CSVΞοϓϩʔυ (μ΢ϯϩʔυ) APIͷ εΩʔϚͱͦͷςετ Ͳ͏͢Δʁ

Slide 49

Slide 49 text

ͦ΋ͦ΋CSVϑΝΠϧͷத਎ ·ͰOpen APIͰఆٛ͢Δ΋ͷ ͳͷ͔ʁ

Slide 50

Slide 50 text

͜Μͳstack overflowΛൃݟ

Slide 51

Slide 51 text

APIͷϨεϙϯεͷCSVΛ Open APIͷYAMLͰ Ͳ͏ॻ͘ͷʁతͳ࣭໰

Slide 52

Slide 52 text

ͦͷճ౴͕ͪ͜Β

Slide 53

Slide 53 text

ʻ༁ʼ Open API ࢓༷Ͱ͸ CSV ϨεϙϯεͷྫΛఏڙ ͍ͯ͠·ͤΜɻ ͦͷͨΊɺεΩʔϚ͸จࣈྻܕɺ จࣈྻͷ഑ྻɺ·ͨ͸ۭͷεΩʔϚͷ͍ͣΕ͔ ʹͳΓ·͢ɻ(͜Ε͸ʮ೚ҙͷ஋ʯΛҙຯ͠·͢)

Slide 54

Slide 54 text

ʻ༁ʼ Open API ࢓༷Ͱ͸ CSV ϨεϙϯεͷྫΛఏڙ ͍ͯ͠·ͤΜɻ ͦͷͨΊɺεΩʔϚ͸จࣈྻܕɺ จࣈྻͷ഑ྻɺ·ͨ͸ۭͷεΩʔϚͷ͍ͣΕ͔ ʹͳΓ·͢ɻ(͜Ε͸ʮ೚ҙͷ஋ʯΛҙຯ͠·͢)

Slide 55

Slide 55 text

͔֬ʹ…ެࣜΛௐ΂ͯ΋ͦΕΒ͍͠ ྫ͸ͳ͔ͬͨ (2020.08࣌఺)

Slide 56

Slide 56 text

ϑϩϯτ/όοΫΤϯυͰڞ༗͍ͨ͜͠ͱɺ ࣮૷ͱOpen APIͷఆٛͷҰகΛ Ͳ͜·Ͱݕূ͢΂͖͔ٞ࿦

Slide 57

Slide 57 text

ղܾࡦ

Slide 58

Slide 58 text

Content-Type ͕ text/csv ʹͳ͍ͬͯΔ͜ͱɺ εςʔλείʔυͷ֬ೝ ͕࠷௿ݶग़དྷΕ͹ OKͱ͢Δ͜ͱʹ requestBody: content: text/csv: schema: type: string responses: '200': description: OK content: text/csv: schema: type: string

Slide 59

Slide 59 text

݁ہͷͱ͜Ζ Ͳ͜·Ͱςετ͢Δʁ ໰୊

Slide 60

Slide 60 text

required Ͱࢦఆ͠ͳ͔ͬͨ ϑΟʔϧυ͸ݕূग़དྷͳ͍͚Ͳ ͍͍ͷ͔ʁ

Slide 61

Slide 61 text

required Ͱࢦఆ͑͢͠͞Ε͹ ҰԠνΣοΫ͸ग़དྷΔ͚Ͳ ͦΕͰ͍͍ͷ͔ʁ… (೰·͍͠

Slide 62

Slide 62 text

ϑϩϯτΤϯυͱ όοΫΤϯυͰ ࿩͠߹ͬͨ݁Ռ

Slide 63

Slide 63 text

݁࿦

Slide 64

Slide 64 text

RSpec࣮ߦ࣌ʹ required Ͱࢦఆ͠ͳ͍ͱ εΩʔϚνΣοΫग़དྷͳ͍ͷ͸ αʔόʔαΠυͷϥΠϒϥϦ (committee-rails)ͷ౎߹ʂ APIεΩʔϚʹ͸αʔόʔαΠυଆ ͷ౎߹ΛͳΔ΂͘൓ө͠ͳ͍

Slide 65

Slide 65 text

ɾԿΛ ɾͲ͜·Ͱ ɾͲΜͳ෩ʹ APIεΩʔϚͱͯ͠ ఆٛ͠ɺςετ͍͔ͯ͘͠͸ ໌֬ͳਖ਼ղ͕ͳ͍ͷͰ೰Ή

Slide 66

Slide 66 text

ղܾࡦ

Slide 67

Slide 67 text

ਖ਼ղ͕ແ͍͔Βɺ ࣗ෼ͨͪͰ ϧʔϧΛ࡞Δ

Slide 68

Slide 68 text

ελΠϧΨΠυΛ ࡞੒ͯࣾ͠಺esaͰγΣΞ ࣗ෼ͨͪͷ൑அ࣠Λ࣋ͭΑ͏ ʹ͍ͯ͠Δ

Slide 69

Slide 69 text

ɾOpen APIͷςετʹcommittee-rails͸ ɹ༗༻✨ ɾͱ͸͍͑…Open API͸શͯΛࣗಈԽͨ͠ ɹςετͰΧόʔ͖͠Εͳ͍ͷͰ஫ҙ ɾOpen APIͷςετपΓ͸໌֬ͳਖ਼ղ͕ ɹͳ͍ͷͰɺͲ͜·ͰΛݕূ͢Δ͔͸ ɹͦͷΞϓϦͷཁ݅࣍ୈ ·ͱΊ

Slide 70

Slide 70 text

ࠂ஌

Slide 71

Slide 71 text

ͪ͜Β΋ੋඇνΣοΫͯ͠Έ͍ͯͩ͘͞ ςοΫϒϩά࢝Ί·ͨ͠

Slide 72

Slide 72 text

͝ਗ਼ௌ͋Γ͕ͱ͏ ͍͟͝·ͨ͠