Slide 1

Slide 1 text

ΫοΫύου͕ ͲͷΑ͏ʹ .JDSPTFSWJDFTԽ͖͔ͯͨ͠ ΫοΫύουגࣜձࣾ ٕज़෦։ൃج൫άϧʔϓ ٢઒ਸྙ

Slide 2

Slide 2 text

Slide 3

Slide 3 text

σΠϦʔ ΞΫηεͷαʔϏε ͲΜͳߏ੒ʹ͠·͔͢ʁ

Slide 4

Slide 4 text

ҰԠ৑௕Խͯ͠୆"QQ%# ਺ඦ୆·ͰΦʔτεέʔϧͰ͖Δߏ੒

Slide 5

Slide 5 text

αʔϏεཁٻʹରͯ͠ ద੾ͳߏ੒Λߟ͑Δ

Slide 6

Slide 6 text

εΫϥονͰαʔϏεΛ্ཱͪ͛Δ ͲΜͳߏ੒ʹ͠·͔͢ʁ

Slide 7

Slide 7 text

.POPMJUIJDΞʔΩςΫνϟ .JDSPTFSWJDFTΞʔΩςΫνϟ

Slide 8

Slide 8 text

.JDSPTFSWJDFT ͍ͭ΍Δ΂͖ʁ

Slide 9

Slide 9 text

Slide 10

Slide 10 text

͜͜·Ͱඞཁʁ

Slide 11

Slide 11 text

w ࠷ॳ͔Β.JDSPTFSWJDFTͰ͸ͳ͍ w ϑΣʔζ͝ͱͷ޻෉ͷੵΈॏͶ w ΫοΫύουͷߏ੒ͷมભΛḷΔ

Slide 12

Slide 12 text

˞஫ҙ ࿩ͷྲྀΕΛΘ͔Γ΍͘͢͢ΔͨΊʹ τϐοΫ͝ͱͷ࣌ܥྻ͕લޙͨ͠Γ ͍ۙτϐοΫΛ·ͱΊͨΓ͍ͯ͠·͢

Slide 13

Slide 13 text

w ᴈ໌ظ w ୯ҰαʔϏεɺϞσϧڞ༗ɺ༻్͝ͱͷΠϯϑϥ w αʔϏε֦େظ w ΞϓϦέʔγϣϯංେԽ΁ͷରԠͱݶք w ୤.POPMJUIJDظ w ౷Ұతͳ"1*ɺڞ௨ج൫ɺαʔϏε෼ׂ w .JDSPTFSWJDFTԽظ w αʔϏε෼ׂͷฐ֐Λղফ͢Δɺ෼ׂίετͷ௿Լ

Slide 14

Slide 14 text

ᴈ໌ظ

Slide 15

Slide 15 text

୯Ұͷ3BJMT DPPLQBE

Slide 16

Slide 16 text

༻్͝ͱʹαʔόʔΛ෼͚͍ͨ w Πϯϑϥͷੑ࣭ͷҧ͍ͰΘ͚ͯ؅ཧ͍ͨ͠ w "1*͸ผυϝΠϯͰ഑৴͢Δ w όοΫάϥ΢ϯυδϣϒ༻ͷαʔόʔΛΘ͚Δ w %#΍Ωϟογϡ؅ཧͳͲ΋ඞཁʹԠͯͦ͡ΕͧΕ෼͚͍ͨ w ΞϓϦέʔγϣϯͷ࣮૷͸·ͱΊ͓͖͍ͯͨ

Slide 17

Slide 17 text

QVQQFUͷSPMFΛΘ͚ͯผʑʹߏ੒؅ཧ QVQQFU͕ΞϓϦέʔγϣϯͷDPOpHΛ഑෍ DPPLQBE XFC DPPLQBE BQJ DPPLQBE CBDLHSPVOEXPSLFS ΞϓϦέʔγϣϯίʔυ͸શͯಉ͡ɻผϞʔυͱͯ͠ಈ࡞ͤ͞Δ

Slide 18

Slide 18 text

ΞϓϦέʔγϣϯؒͰϞσϧΛڞ༗͍ͨ͠ w ػೳ͕େ͖͘ҟͳΔΞϓϦέʔγϣϯΛ෼͚͍ͨ w 1$εϚʔτϑΥϯ޲͚αΠτ w ϑΟʔνϟʔϑΥϯ޲͚αΠτ w ΋ͱ΋ͱϑΟʔνϟʔϑΥϯ޲͚ผαʔϏεͩͬͨͷΛ౷߹ͨ͠ w ελοϑ޲͚؅ཧαΠτ w σʔλ͸ಉ͡΋ͷΛݟͯɺϞσϧϩδοΫ΋ڞ༗͍ͨ͠

Slide 19

Slide 19 text

Ϟσϧ΍ڞ௨ϥΠϒϥϦ෦෼ΛTIBSFEͱͯ͠ಠཱ ֤ΞϓϦέʔγϣϯ͔Β͸TZNMJOLͰࢀর DPPLQBE XFC BQJʜ DPPLQBE BENJO DPPLQBE GFBUVSFQIPOF

Slide 20

Slide 20 text

TIBSFEΛؚΊશΞϓϦέʔγϣϯ͕ҰͭͷϦϙδτϦʹಉډ ʮຊମʯʮDPPLQBE@BMMʯͱݺ͹ΕΔ

Slide 21

Slide 21 text

αʔϏε֦େظ

Slide 22

Slide 22 text

ϨγϐҎ֎ͷαʔϏε͕ੜ·Ε࢝ΊΔ w ϨγϐΛͷͤΔɺ͕͢͞Ҏ֎ͷػೳ w ಛച৘ใɺྉཧڭࣨͳͲͷαʔϏεʹͭͳ͕͍ͬͯ͘ w ϓϩτλΠϓΛ࡞ͬͯՁ஋ݕূΛ܁Γฦ͢ w ϓϩτλΠϓͳͷͰܧଓͯ͠࢖͏͔͸ෆ໌ w ޻਺Λ࠷খݶʹ͢ΔͨΊʹɺطଘͷࢿ࢈Λ࠷େݶ׆༻

Slide 23

Slide 23 text

ผΞϓϦέʔγϣϯͱ͢Δ ৔߹΋TIBSFEΛڞ༗ ຊମʹ͍͋ͷΓ ʢຊମ͸ڊେԽʣ ೝূɺܾࡁɺϩάͳͲ͸ ຊମͷϞδϡʔϧΛ௚઀࢖͏ ඞཁͳΒαʔϏε͝ͱͷॲཧΛ௚઀࣮૷

Slide 24

Slide 24 text

$*ʹ͔͔Δ͕࣌ؒංେԽ w ͨͩͰ͑͞ςετ͕ͲΜͲΜ૿͕͔͔͑ͯ࣌ؒΔ w TIBSFEΛ௨ͯ͡શ෦ͭͳ͕͍ͬͯΔͷͰશવҧ͏ՕॴͰࢥΘ͵Өڹ͕ ग़ͯςετ͕ࣦഊ͢Δ w मਖ਼ͯ͠࠶࣮ߦʹ·͕͔͔ͨ࣌ؒΔ w ͋ΔνʔϜ͕$*ΛGBJMͤ͞ΔͱଞͷνʔϜ΋σϓϩΠͰ͖ͳ͍ w σϓϩΠ·Ͱͷ଴ͪ࣌ؒΛ࠷খԽ͍ͨ͠

Slide 25

Slide 25 text

SFNPUF@TQFD ෳ਺୆ͷαʔόʔͰ ςετΛ෼ࢄ࣮ߦ ෼Ҏ಺ʹ ऴΘΔΑ͏ʹ

Slide 26

Slide 26 text

ςετ͸͞Βʹ૿͑ଓ͚ͨ w ։ൃ͕ϐʔΫ࣌ͷςετΛ͞͹ͨ͘ΊͷϫʔΧʔ਺૿ w Ұํٳ೔͸શવཁΒͳ͍ w ॊೈʹ૿ݮ͍ͤͨ͞ w ϫʔΧʔͷো֐΍ͨ·ͨ·ࣦഊ͢ΔFYBNQMFͷӨڹ૿

Slide 27

Slide 27 text

3334QFD w HJUIVCDPNDPPLQBESSSTQFD w &$εϙοτΠϯελϯεΛར༻ͯ͠ίετΛ཈͑Δ w ࣦഊͨ͠ςετͷࣗಈ࠶࣮ߦ

Slide 28

Slide 28 text

σϓϩΠʹ͕͔͔࣌ؒΔ w DBQJTUSBOP w ཁ͢ΔʹTTI઀ଓͯ͠σϓϩΠ w ୆਺΋ଟ͘ճͷσϓϩΠͰ෼Ҏ্͔͔Δ w TTIͰࣦഊ͢Δස౓͕૿Ճ w ϦτϥΠ͢ΔӋ໨ʹͳΓ͞Βʹ͕͔͔࣌ؒΔ

Slide 29

Slide 29 text

NBNJZB w HJUIVCDPNTPSBINBNJZB w 4FSGͰΦʔέετϨʔγϣϯ w $*͕௨ͬͨΒUBSCBMMʹͯ͠4ʹΞοϓ w ։ൃऀ͕४ຊ൪؀ڥͰಈ࡞֬ೝ͍ͯ͠Δؒʹ഑෍ͯ͠४උ w σϓϩΠίϚϯυͰ͸੾Γସ͑Δ͚ͩ

Slide 30

Slide 30 text

։ൃ؀ڥ͕ॏ͗͢Δ w खݩͰSBJMTΛىಈͯ͠τοϓදࣔ͢Δ·Ͱ෼Ҏ্͔͔Δ w ͱʹ͔͘HFN΍ൃߦΫΤϦ͕ଟ͗͢Δ w ։ൃ؀ڥͷύϑΥʔϚϯενϡʔχϯά w ։ൃ؀ڥͰ΋ΩϟογϡΛ׆༻͢ΔΑ͏ʹͳΔ w ෆཁͳίʔυ୨Է͠ͷܒ໤

Slide 31

Slide 31 text

मਖ਼͕ٴ΅͢Өڹൣғ͕Θ͔Βͳ͍ w ᴈ໌ظ͸ڞ௨Ϟδϡʔϧͱͯ͠੾Γग़ͨ͠Γ"1*Λ੔උ͢ΔͷͰ͸ ͳ͘ɺ௚઀࢖ͬͨΓ֦ுͨ͠Γ͢Δߥʑ͍͠ελΠϧ w TIBSFEͰෳ਺ͷΞϓϦέʔγϣϯ͕ͭͳ͕͍ͬͯͯͲ͏࢖ΘΕ Δͷ͔Θ͔Βͳ͍ w ϥΠϒϥϦ΋ϞϯΩʔύον΍ϑΥʔΫ͍ͯ͠Δ΋ͷ͕ଟ͘஌ͬͯ ͍Δڍಈͱҧ͏

Slide 32

Slide 32 text

ػೳͷڥք͕͍͋·͍ w ͲͷνʔϜ͕୲౰͍ͯ͠Δͷ͔͕͍͋·͍ w ମ੍มߋͳͲͰͷҾ͖ܧ͗࿙Ε΋ൃੜ͕ͪ͠ w ϓϩμΫτΦʔφʔ͸"νʔϜ͚ͩͲ࣮࣭ӡ༻΍࣮૷͸#νʔϜ͕ ΍ͬͪΌͬͯΔ w ػೳมߋ͢Δͱ͖ʹӨڹड͚ΔνʔϜ͕ଟ͍ w νʔϜΛ·͍ͨͩௐ੔ͱίϛϡχέʔγϣϯ͕େม

Slide 33

Slide 33 text

Ͳ͏͢Ε͹ɾɾɾ

Slide 34

Slide 34 text

୤.POPMJUIJDظ

Slide 35

Slide 35 text

୤ຊମ୤TIBSFE͍ͨ͠ w طଘͷࢿ࢈Λ࢖͑Δͱ͍ͬͯ΋ਏΈ͕ڧ͘ͳ͖ͬͯͨ w Ϟδϡʔϧࣗମ͕αʔϏεͱີ݁߹͓ͯ͠Γ݁ہ࠶ར༻ͮ͠Β͍ w εΫϥονͰ࡞Ε͹ίʔυϕʔε΋খ͘͞ࡁΉ w ґଘ͕গͳ͘։ൃ؀ڥͷಈ࡞΍ςετ΋଎͍ w গͳ͘ͱ΋৽نͰ࡞ΔͳΒ෼͚ͨ΄͏͕Α͍ͷͰ͸

Slide 36

Slide 36 text

ೝূͳͲຊମͱͷ΍ΓͱΓ͸ "1*Λ௨ͯ͡ߦ͏ ίʔυ΋%#΋ ຊମ͔Βಠཱ ܾࡁͷΑ͏ʹ ڞ௨ͯ͠ར༻Ͱ͖Δ ػೳΛ੾Γग़͠ ੾Γग़͞Εͨػೳ͸ ຊମ͔Β΋"1*࿈ܞ

Slide 37

Slide 37 text

"1*Λ௨ͯ͠ϦιʔεΛѻ͏ w J04"OESPJEΞϓϦ͕ߴػೳԽ w 8FC7JFXͰఏڙ͍ͯͨ͠΋ͷ΋ωΠςΟϒ࣮૷Խ w "1*ͰຊମͷϦιʔεΛࡉ੍͔͘ޚͰ͖ΔΑ͏ʹ͢Δ w ΠϯλʔϑΣΠεΛ౷Ұ͍ͨ͠ w ϑΥʔϚοτͷҟͳΔ"1*͕ෳ਺ଘࡏ͍ͯͨ͠ w "1*͝ͱʹYYYDMJFOU

Slide 38

Slide 38 text

3&45GVMIZQFSNFEJB"1* GET /v1/users/123 { "id": 123, "name": "ύυඒ", "kitchen": { "id": 15, "created": "2016-03-10T10:59:24+09:00", } }, "_links": { "self": { "href": "/v1/users/123" }, "recipes": { "href": "/v1/users/123/recipes" }, } } Ϧιʔεؒͷؔ࿈Λ ϦϯΫͱͯ͠දݱͰ͖Δ

Slide 39

Slide 39 text

(BSBHF w HJUIVCDPNDPPLQBEHBSBHF class Employee < ActiveRecord::Base include Garage::Representer belongs_to :division has_many :projects property :id property :title property :division, selectable: true collection :projects, selectable: true link(:division) { division_path(division) } link(:projects) { employee_projects_path(self) } def self.build_permissions(perms, other, target) perms.permits! :read end end Ϧιʔεͱͯ͠ͷ ଐੑ΍ϦϯΫΛఆٛ ೝՄ৚݅΋ఆٛͰ͖Δ

Slide 40

Slide 40 text

(BSBHF$MJFOU w HJUIVCDPNDPPLQBEHBSBHF@DMJFOU # GET https://garage.example.com/v1/me user = client.get("/me") user.id user.name # GET https://garage.example.com/v1/recipes recipes = client.get("/recipes") recipes.total_count recipes[0].id recipes[0].name ϦιʔεΛจࣈྻͰࢦఆ "1*ͷ࣮૷͕૿͑ͯ΋ ΫϥΠΞϯτ͸ͦͷ··࢖͑Δ ͲͷαʔϏεΛ࢖͏ͱ͖΋ ࢖͍ํ͸ಉ͡ ֤ΤϯυϙΠϯτͷ࢓༷͚ͩ Θ͔Ε͹Α͍

Slide 41

Slide 41 text

"VUPEPD w HJUIVCDPNSLBNVSBBVUPEPD # spec/requests/users_spec.rb describe "Users" do describe "GET /v1/me", autodoc: true do it "returns a current_resource_owner" do get "/v1/me", params: {}, headers: headers expect(response).to have_http_status(:success) expect(response.body).to be_json_as( id: resource_owner.id, name: resource_owner.name ) end end end ςετ͔ΒυΩϡϝϯτΛ ࣗಈੜ੒

Slide 42

Slide 42 text

ೝূɺϩάɺ௨஌ͳͲ༷ʑͳ ڞ௨ج൫αʔϏε͕੔උ͞Ε ͍ͯͬͨ TIBSFE࿈ܞ͍ͯͨ͠αʔϏε΍ ຊମ಺͔Βଔۀ͢ΔαʔϏε͕ ग़͖ͯͨ ຊମ͸ґଘؔ܎౳ͷ໰୊Ͱ HBSBHF"1*ΛผϞʔυͰىಈ ΞϓϦ΋ผαʔϏε΋ ಉ͡"1*Λ࢖͏ ֤αʔϏεؒ΋ HBSBHF"1*Ͱ࿈ܞ

Slide 43

Slide 43 text

.JDSPTFSWJDFTԽظ

Slide 44

Slide 44 text

ߏ੒؅ཧ͕େม w 8FCόονͳͲ༻్ʹԠͯ͡ߏ੒؅ཧΛ෼͚ΔελΠϧ w BQQαʔόʔ͸ಠཱͨ͠SPMF w όονδϣϒ͸ڞ௨ͷόονϫʔΧʔͷҰ෦ͱͯ͠؅ཧ w ઃఆͷ഑෍࿙Ε w ΞϓϦέʔγϣϯ͕ಉډ͢Δͱݖݶ؅ཧ͕ࠔ೉ w *".3PMF΍ൿಗ஋ͷ؅ཧͳͲ

Slide 45

Slide 45 text

%PDLFS w ϙʔλϒϧͳ࣮ߦ؀ڥ w TUBHJOHQSPEVDUJPOόονಉ͡Πϝʔδ w खݩͰݕূ͢Δ͜ͱ΋Ͱ͖Δ w %PDLFSpMF͸ΞϓϦέʔγϣϯϦϙδτϦʹஔ͘ w ΞϓϦέʔγϣϯݻ༗ͷ৘ใ͕ू໿ w ؀ڥґଘ஋͸؀ڥม਺ͱͯ͠σϓϩΠ࣌ʹ஫ೖ

Slide 46

Slide 46 text

FUDFOWFUDWBVMU w HJUIVCDPNTPSBIFUDFOW w FUDEͰઃఆ஋Λ؅ཧ w HJUIVCDPNTPSBIFUDWBVMU w FUDEͷ஋Λ҉߸Խ w ΋ͱ΋ͱFUDEʹ"$-͕ແ͔ͬͨͨΊ࡞ΒΕͨ w ࢦఆͷ伴Λ͍࣋ͬͯΔΠϯελϯεͰ͔͠෮߸Ͱ͖ͳ͍

Slide 47

Slide 47 text

FUDXFC w HJUIVCDPNTPSBIFUDXFC 8FC6*ͰશαʔϏεͷ ઃఆ஋ΛҰׅ؅ཧ ൿಗ஋Λѻ͏ͷͰ ݖݶΛ࣋ͭਓ͚͕ͩૢ࡞

Slide 48

Slide 48 text

,VSPLP w HJUIVCDPNDPPLQBELVSPLP w શαʔϏεͷόονδϣϒ΍ϫʔΫϑϩʔΛ؅ཧ w ϫʔΧʔ͕࠷৽ͷ%PDLFSΠϝʔδΛऔಘ࣮ͯ͠ߦ 8FCͰδϣϒ؅ཧ ϩάӾཡ ࠶࣮ߦ·ͰͰ͖Δ

Slide 49

Slide 49 text

#BSCFRVF w HJUIVCDPNDPPLQBECBSCFRVF w ,VSPLPಉ༷%PDLFSίϯςφͰδϣϒ࣮ߦͰ͖Δ

Slide 50

Slide 50 text

%PDLFSӡ༻ͷચ࿅ w ౰ॳ͸খ͞ͳπʔϧΛ૊Έ߹Θͤͯ؅ཧ͍ͯͨ͠ w ౷Ұͯ͠ίϯτϩʔϧ͢Δ΋ͷ͕ͳ͍ w ઃఆ͢Δ΋ͷ͕݁ߏଟ͍ w ϗετͷ؅ཧͷखؒ w &$4ͷొ৔ w "84ϚωʔδυͳίϯςφαʔϏε

Slide 51

Slide 51 text

)BLP w HJUIVCDPNFBHMFUNUIBLP w %PDLFSΞϓϦ༻ͷσϓϩΠπʔϧ w ΫοΫύουͰ͸όοΫΤϯυʹ&$4Λར༻ w ΞϓϦέʔγϣϯ͝ͱͷઃఆ͸:".-Ͱ؅ཧ w ؀ڥ͝ͱʹ؀ڥม਺ΛઃఆͰ͖Δ w ൿಗ஋ͷΈFUDFOWFUDWBVMUͰ؅ཧ

Slide 52

Slide 52 text

൥ࡶͳ؅ཧ͔Βͷղ์ w ͱʹ͔͘%PDLFSΠϝʔδ͕͋Ε͹༷ʑͳ༻్Ͱ࣮ߦͰ͖Δ w Ϋϥ΢υ্ͷݖݶ؅ཧ͕γϯϓϧʹ w &$45BTLʹ*".3PMFͰݖݶ෇༩ w όονδϣϒ͸σϓϩΠͷ֓೦͕ͳ͘ͳͬͨ w ͦͷ࣌఺Ͱ࠷৽ͷΠϝʔδΛऔಘ࣮ͯ͠ߦ͞ΕΔ w TTIͯ͠ϩάௐࠪ͢Δ͜ͱ͸ͳ͘ͳΓɺ8FC6*Ͱ֬ೝ

Slide 53

Slide 53 text

ΞϓϦέʔγϣϯ௥Ճ͕௿ίετԽ w %PDLFSΠϝʔδ͕͋Ε͹0, w XFCCBUDIKPCRVFVFͲ͜Ͱ΋࢖͑Δ w HBSBHF@DMJFOU͚ͩೖΕ͓͚ͯ͹ଞͷαʔϏε͕࢖͑Δ w ҎલͳΒϞʔυΛΘ͚ͨΓ͍ͯͨ͠΋ͷ΋৽نͰ௥Ճͨ͠ํָ͕ w αʔϏεͷཻ౓͸࣍ୈʹখ͘͞ͳΓɺ૿͑Δ଎౓΋૿͍ͯ͘͠

Slide 54

Slide 54 text

#BDLFOE'PS'SPOUFOE Ϧιʔε͸ಉ͡΋ͷ ఏڙ͍͕ͨ͠ ೝূํ͕ࣜҟͳΔͳͲ ಛघͳΫϥΠΞϯτ ઐ༻όοΫΤϯυ

Slide 55

Slide 55 text

"1*࢓༷ͷᴥᴪʹΑΔࣄނ w ഁյతͳ࢓༷มߋʹΑΔࣄނ w ଟ͘ͷ৔߹͸ҙਤͨ͠΋ͷͰ͸ͳ͘ൃੜ w ҙਤ͍ͯ͠Δ৔߹΋Ͳ͔͜Βར༻͞Ε͍ͯΔͷ͔೺Ѳͮ͠Β͍ w ςετ͸ʁ w ࣗಈςετͰ͸ଞαʔϏεͷ"1*͸ελϒ͍ͯ͠Δ w "1*ϓϩόΠμଆ͕࢓༷มߋͯ͠΋ελϒ͸ߋ৽͞Εͳ͍ͷͰݕ஌Ͱ͖ͳ͍

Slide 56

Slide 56 text

WDS w HJUIVCDPNWDSWDS w ςετ࣌ʹ࣮ࡍͷ)551ͷϦΫΤετͱϨεϙϯεΛه࿥ w ࣍ճҎ߱ͷϦΫΤετͰ͸ه࿥ͨ͠Χηοτσʔλ͔ΒڍಈΛ࠶ݱ ͢Δ w ࣮ϦΫΤετ͔ΒελϒΛੜ੒͢Δ

Slide 57

Slide 57 text

3BDL7$3 w HJUIVCDPNNJZBHBXBSBDLWDS w "1*ϓϩόΠμଆ͕ࣗ਎Λςετͨ͠ΧηοτσʔλΛه࿥ɾ഑෍ w "1*ΫϥΠΞϯτଆ͸ςετ࣌"1*ϓϩόΠμ͔ΒΧηοτσʔλ Λऔಘͯࣗ͠਎Λςετ͢Δࡍͷελϒͱ͢Δ w ΫϥΠΞϯτ͸ৗʹ࠷৽ͷڍಈͷελϒΛ࢖ͬͯςετͰ͖Δ

Slide 58

Slide 58 text

$*࣮ߦස౓ͷ͕ࠩେ͖͍৔߹ͷ໰୊ w ։ൃ͕׆ൃͰҰ೔ʹԿ౓΋$*࣮ߦʴσϓϩΠ͞ΕΔ΋ͷ΋͋Ε͹ɺ Ұ೔ʹҰճఔ౓͔͠$*͕࣮ߦ͞Εͳ͍΋ͷ΋͋Δ w 3BDL7$3͸ΫϥΠΞϯτଆͰ࣮ߦ͞Εͯ͸͡Ίͯ࢓༷͕յΕͨ ͜ͱΛݕ஌Ͱ͖Δ w ΫϥΠΞϯτଆͷ$*ස౓͕গͳ͍ͱɺ"1*ϓϩόΠμଆͷมߋΛ ݕ஌͢ΔલʹσϓϩΠ͞Εͯ͠·͏

Slide 59

Slide 59 text

$POTVNFS%SJWFO$POUSBDUUFTUJOH w ΫϥΠΞϯτʢ$POTVNFSʣ͕"1*Λελϒͯ͠ςετ w ظ଴͢ΔৼΔ෣͍Λܖ໿ʢ$POUSBDUʣͱͯ͠"1*ଆʹ౉͢ w "1*ϓϩόΠμଆ͸ࣗ਎͕$POUSBDUΛຬ͍ͨͯ͠Δ͔Λςετ͢ Δ w "1*ϓϩόΠμଆͷ$*ͰςετͰ͖ΔͷͰɺ໰୊ʹͳΔϦϏδϣ ϯΛσϓϩΠ͢Δલʹݕ஌Ͱ͖Δ http://martinfowler.com/articles/consumerDrivenContracts.html

Slide 60

Slide 60 text

1BDU w HJUIVCDPNSFBMFTUBUFDPNBVQBDU w ΫϥΠΞϯτଆ w $*ͰQBDUϑΝΠϧΛੜ੒ w "1*ϓϩόΠμଆ w $*ͰQBDUϑΝΠϧΛWFSJGZ IUUQTHJUIVCDPNSFBMFTUBUFDPNBVQBDUIPXEPFTJUXPSL

Slide 61

Slide 61 text

1BDU $POTVNFS describe 'get_all' do let(:recipe_a) { { id: Pact.like(1), name: Pact.like('Curry') } } let(:recipe_b) { { id: Pact.like(2), name: Pact.like('Salada') } } before do provider_app.given('there are 2 recipes'). upon_receiving('a request for recipes'). with(method: :get, path: '/v1/recipes'). will_respond_with( status: 200, headers: { 'Content-Type' => Pact.term( generate: 'application/json', matcher: %r{application/json} ), }, body: [recipe_a, recipe_b] ) end it 'returns recipes' do recipes = described_class.get_all expect(recipes.size).to eq(2) expect(recipes.first.name).to eq('Curry') end end ςετ͸௨ৗͱಉ͡ 1BDUͰελϒ

Slide 62

Slide 62 text

1BDUpMF { "consumer": { "name": "ConsumerApp" }, "provider": { "name": "ProviderApp" }, "interactions": [ { "description": "a request for recipes", "provider_state": "there are 2 recipes", "request": { "method": "get", "path": "/v1/recipes" }, "response": { "status": 200, "headers": { "Content-Type": { "json_class": "Pact::Term", "data": { "generate": "application/json", "matcher": { "json_class": "Regexp", "o": 0, "s": "application/json" } ϦΫΤετͱ Ϩεϙϯεͷ ಺༰ΛKTPOͰग़ྗ

Slide 63

Slide 63 text

1BDU 1SPWJEFS w "1*ଆ w γφϦΦʹԊͬͨηοτΞοϓίʔυ͚ͩΛ༻ҙ Pact.provider_states_for 'ConsumerApp' do provider_state "there are 2 recipes" do set_up do %w[Curry Salada].each {|name| Recipe.create!(name: name) } end end end

Slide 64

Slide 64 text

ো֐ͷ఻೻ w ࣮૷ʹόά͕ͳ͔Ζ͏ͱো֐͸ى͜Γ͏Δ w ͋ΔαʔϏε͕ো֐ʹͳΔͱͦΕΛར༻͍ͯ͠ΔαʔϏεʹ఻೻ w ϦΫΤετ͝ͱʹλΠϜΞ΢τ·Ͱ଴ͭ͜ͱͰΫϥΠΞϯτଆ΋ ٧·Δ w ΫϥΠΞϯτଆͷϦτϥΠػߏ͕"1*ϓϩόΠμʹͱͲΊΛࢗ͢

Slide 65

Slide 65 text

$JSDVJU#SFBLFS w ฏৗ࣌ͷࣦഊ͸ΫϥΠΞϯτ͸ϦτϥΠͰ͖Δ w "1*ϓϩόΠμ͕μ΢ϯ͍ͯ͠Δ৔߹͸ϦΫΤετ͠ͳ͍Α͏ʹ͢Δ w λΠϜΞ΢τ଴ͪ΋͠ͳ͍ w ͠͹Βͯ͘͠ϓϩόΠμ͕෮׆ͨ͠Β·ͨϦΫΤετΛ࠶։͢Δ

Slide 66

Slide 66 text

&YQFEJUPS w HJUIVCDPNDPPLQBEFYQFEJUPS EXPEDITOR_SERVICE = Expeditor::Service.new( non_break_count: 20, threshold: 0.2, period: 10, sleep: 5, ) def notification_counts Expeditor::Command.new(service: EXPEDITOR_SERVICE, timeout: 3) { response = client.get("/notifications/counts", params, options) response.notification_count }.set_fallback {|e| Raven.capture_exception(e) 0 }.start(current_thread: true).get end $JSDVJU#SFBLFSͷᮢ஋Λઃఆ Τϥʔ࣌͸ϩάΛه࿥ͯ͠ σϑΥϧτ஋Λฦ͢

Slide 67

Slide 67 text

&YQFEJUPS w ฏৗ࣌ ΫϥΠΞϯταʔϏε ΦϓγϣϯʹԠͯ͡ ϦτϥΠͨ͠Γ Ͳ͏ͯ͠΋ͩΊͳΒ GBMMCBDLॲཧ "1*ϓϩόΠμ

Slide 68

Slide 68 text

&YQFEJUPS w ো֐࣌ ΫϥΠΞϯταʔϏε ϦΫΤετͤͣ ࠷ॳ͔ΒGBMMCBDLॲཧ "1*ϓϩόΠμ

Slide 69

Slide 69 text

αʔϏε෼ׂ࣌ʹࠔΔϙΠϯτ͕ղܾ͞Ε͖ͯͨ w "1*͕ཚཱͯ͠Ͳ͜ΛͲ͏࢖͑͹͍͍ͷ͔Θ͔Βͳ͘ͳΔ w (BSBHFͰͲͷαʔϏε΋ಉ͡Α͏ʹ࢖͑Δ w ຖճαʔόʔ࡞ͬͯߏ੒؅ཧ͢Δͷ͕େม w %PDLFSpMFͱ:".-Λॻ͚͹)BLPͰ؀ڥ༻ҙͰ͖Δ w αʔϏεڥքͰόά΍ো֐ʹͳΓ΍͍͢ w 1BDU͕ޓ׵ੑΛ୲อ͠&YQFEJUPS͕ো֐ͷ఻೻Λ๷͙

Slide 70

Slide 70 text

αʔϏεΛ෼ׂ͢Δ͜ͱͰಘΒΕΔྑ͍͜ͱ w ίʔυϕʔε͕খ͍͞ w ςετ΍։ൃ؀ڥͷಈ࡞͕଎͍ w มߋʹΑΔӨڹൣғ͕খ͍͞ w طଘ࣮૷ʹΑΔ੍໿͕খ͍͞ w νʔϜʹ࣮͋ͬͨ૷ϧʔϧ w ػೳʹదͨ͠ϥΠϒϥϦɺݴޠͷબ୒

Slide 71

Slide 71 text

αʔϏεΛ෼ׂ͢Δ͜ͱͰಘΒΕΔྑ͍͜ͱ w γεςϜڥք͕໌֬ w νʔϜ಺Ͱίϛϡχέʔγϣϯ͕׬݁͢Δ w ׬݁Ͱ͖ͳ͍৔߹ڥքͱͯ͋͠·ΓΑ͘ͳ͍

Slide 72

Slide 72 text

·ͱΊ w ࠷ॳ͔Βɺ͋Δ͍͸͋Δ೔ಥવ.JDSPTFSWJDFTʹͳͬͨΘ͚Ͱ͸ͳ͍ w ͦͷ౎౓໰୊ʹͳͬͨ͜ͱʹରԠ͖ͯͨ͠ੵΈॏͶ w ϞϊϦγοΫͳγεςϜ͸ঃʑʹਏΈ͕େ͖͘ͳ͍ͬͯ͘ w αʔϏεΛ෼͚Δ͜ͱͰൃੜ͢Δ໰୊͸ٕज़ͰճආͰ͖Δ w ςΫχοΫΛ஌ΓϑΣʔζʹԠͨ͡ઃܭΛ͢Δͷ͕ॏཁ