Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
How Microservices are linked at Cookpad
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
adorechic
March 14, 2016
46k
12
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
How Microservices are linked at Cookpad
adorechic
March 14, 2016
More Decks by adorechic
See All by adorechic
採用技術、絞るか広げるか / Make variety of technology widely or narrowly?
adorechic
0
150
Rails + ReactなSPAサイトでのSEO / SEO at Rails + React SPA
adorechic
4
27k
分かれたシステムをていねいにモノリスに集約する/Integrate decentralized systems to a monolith carefully
adorechic
16
19k
クックパッドがどのようにMicroservicesしてきたか/How Cookpad shifts to Microservices
adorechic
58
40k
Microservices Overview
adorechic
0
230
Microservices stacks
adorechic
1
220
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.6k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
850
ラッコキーワード サービス紹介資料
rakko
1
5.4M
How to Ace a Technical Interview
jacobian
280
24k
Ruling the World: When Life Gets Gamed
codingconduct
0
400
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
410
A designer walks into a library…
pauljervisheath
211
25k
Producing Creativity
orderedlist
PRO
348
41k
The Invisible Side of Design
smashingmag
301
52k
How GitHub (no longer) Works
holman
316
150k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Crafting Experiences
bethany
1
380
Transcript
)PX.JDSPTFSWJDFTBSF MJOLFEBU$PPLQBE ΫοΫύουגࣜձࣾ ٕज़෦։ൃج൫( ٢ਸྙ
ࠓճ͞ͳ͍͜ͱ w.JDSPTFSJWDFTͱʙ w.BSUJO'PXMFS͕ʙ wಋೖ͖͔͢൱͔ʙ w.JDSPTFSWJDFTͷηΦϦʔ ֶͼ͍ͨํ
ࠓճ͢͜ͱ w ΫοΫύουͰͷࣄྫ ‣ ͦͦͲ͏͍͏ཻͰ͔Ε͍ͯΔʁ ‣ αʔϏεؒͲͷΑ͏ʹ௨৴͢Δʁ ‣ αʔϏεؒͷςετͬͯͲ͏ͬͯΔʁ ‣
ߏཧʗσϓϩΠʁԾԽͯ͠Δʁ ‣ ϏϧυύΠϓϥΠϯʁόονδϣϒʁ ‣ νʔϜؒͷ࿈ܞҙࢥܾఆͲ͏ͯ͠Δʁ
ͲΜͳαʔϏε͔Β ߏ͞Ε͍ͯΔ͔
αʔϏεͷओͳྨ wϢʔβʔαʔϏε ‣ Ϣʔβʔ͕͏ϓϩμΫτ wϏϡʔαʔϏε ‣ ͋ΔαʔϏεͷผϏϡʔ ‣ ͍ΘΏΔ#BDLFOEGPSGSPOUFOET wڞ௨ج൫
‣ ܾࡁɺ௨ɺϩάFUDʜ
ϢʔβʔαʔϏε
ϢʔβʔαʔϏε wϓϩμΫτʹϑΥʔΧεͨ͠λΠϓ ྉཧڭࣨ Ϩγϐ Ϣʔβʔ ΧϑΣ ܾࡁ ௨ ಠཱͨ͠αʔϏε
Α͋͘Δػೳ ڞ௨ج൫Λ׆༻ ଞͷυϝΠϯͷϞσϧΛར༻Ͱ͖Δ
ϏϡʔαʔϏε wυϝΠϯϞσϧಉ͡ͰผͷϏϡʔ OEM൛ Ϩγϐ Ϩγϐ Ϣʔβʔ ௨ ࠜຊతʹఏڙ͢Δͷಉ͡ UIΞΧϯτମܥ͕ҧ͏
ඞཁʹԠͯ͡ଞαʔϏε ΛΈ߹ΘͤΔ ΦϦδφϧͷυϝΠϯ
ϏϡʔαʔϏε w#'' #BDLFOEGPSGSPOUFOET ʹ͍ۙ ‣ Α͋͘ΔσόΠε͝ͱʹઐ༻ϏϡʔΛ࡞Δ έʔε΄΅ͳ͍ ‣ 0&.൛ͷΑ͏ͳέʔεͰΘΕ͍ͯΔ
ఏڙ͢ΔυϝΠϯϞσϧಉ͡ 㾎ҟͳΔ6*Ͱఏڙ͢Δ 㾎ΞΧϯτମܥ͕ҧ͏
ڞ௨ج൫αʔϏε wڞ௨ͯ͠ΘΕΔج൫ػೳ w 0"VUIϓϩόΠμ w ܾࡁ w 1VTI௨ʗϝʔϧ৴ w ΞΫςΟϏςΟ
w ϩά w ηΩϡΞσʔλ
αʔϏεؒͲͷΑ͏ʹ ௨৴͢Δͷ͔
3&45GVM)ZQFSNFEJB"1* wύϑΥʔϚϯεΑΓॊೈੑʗૄ݁߹Λॏࢹ ‣ Ϟσϧ͕ඇৗʹଟؔ͘࿈͕ෳࡶ ‣ ಛఆͷߴෛՙϞσϧ͕͋ΔΘ͚Ͱͳ͍ { "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" }, } }
(BSBHF w HJUIVCDPNDPPLQBEHBSBHF w 3&45GVMIZQFSNFEJB"1*GPS3BJMT 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
(BSBHF$MJFOU w HJUIVCDPNDPPLQBEHBSBHF@DMJFOU w YYYDMJFOU͕ແݶ૿৩͠ͳ͍ w ͲͷαʔϏεΛར༻͢Δͱ͖ಉ͡ΠϯλʔϑΣΠε w αʔϏε͝ͱʹҟͳΔͱֶशίετ͕ߴ͍
# 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
αʔϏεؒ௨৴ͷ ίετܰݮʗোੑ
&YQFEJUPS wHJUIVCDPNDPPLQBEFYQFEJUPS w3VCZ൛ͷ/FUqJY)ZTUSJY w"TZODISPOPVTFYFDVUJPO wෳͷαʔϏε͔ΒͷϦιʔεΛฒߦͯ͠औಘ w'BVMUUPMFSBODF w$JSDVJUCSFBLFS
αʔϏεؒ࿈ܞͷςετ
ޓੑΛͲ͏୲อ͢Δ͔ w αʔϏε͝ͱͷςετ͞Ε͍ͯΔ w ࿈ܞઌελϒ͢Δ w ඇޓͷมߋʹؾ͚ͳ͍ w ܕPSςετ w
+40/4DIFNBཧ͕େมͦ͏ w ͱͱςετจԽ͍͍ࠜͯͨͷͰ্ख͘ ׆༻͍ͨ͠
$POTVNFS%SJWFO$POUSBDUUFTUJOH wར༻ଆ $POTVNFS ͕"1*Λελϒͯ͠ςετ ‣ ظ͢ΔৼΔ͍Λܖ $POUSBDU ͱͯ͠ "1*ଆʹ͢ w"1*ଆ͕ࣗ$POUSBDUΛຬ͍ͨͯ͠Δ͔Ͳ͏
͔ݕূʢςετʣ͢Δ http://martinfowler.com/articles/consumerDrivenContracts.html
1BDU w HJUIVCDPNSFBMFTUBUFDPNBVQBDU w ΫϥΠΞϯτଆ w $*ͰQBDUϑΝΠϧΛੜ w "1*ଆ w
$*ͰQBDUϑΝΠϧΛWFSJGZ ग़య: https://github.com/realestate-com-au/pact#how-does-it-work
1BDU w ΫϥΠΞϯτଆ 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 w QBDUpMFʢҰ෦ʣ { "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" } }
1BDU 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
3BDL7$3 w HJUIVCDPNNJZBHBXBSBDLWDS w 7$3͕ϕʔεͰखܰ w "1*ϦΫΤετΛΧηοτσʔλԽͯ͠ελϒ w "1*ଆ͕ΧηοτσʔλΛΫϥΠΞϯτʹఏڙ͢Δ w
ඇޓͷมߋ͕͋ΕΫϥΠΞϯτଆͷ$*Ͱݕ w "1*ଆͷϏϧυͷํ͕ߴසͷ߹ɺΫϥΠΞϯτଆͷ ݕલʹϦϦʔε͞Ε͏Δ w ݱࡏ1BDUʹҠߦͨ͠
αʔϏεΛ·͍ͨͩ ΤϥʔΛ͢Δ
4FOUSZ w HJUIVCDPNHFUTFOUSZTFOUSZ w αʔϏε͝ͱͷΤϥʔΛूཧ͍ͯ͠Δ w ͜Ε͚ͩͩͱαʔϏεؒͷඥ͚͕Ͱ͖ͳ͍ w αʔϏε"ˠ#ͷϦΫΤετ࣌ʹΤϥʔ w
Τϥʔ"ͱ#ͦΕͧΕͰه͞ΕΔ w ͜ͷোʹΑΔΤϥʔͷൣғʁ
5SBDF-PHHJOH w ϦΫΤετ*% w ϔομʹ͋Εͦͷ··͍ɺͳ͚Ε࠾൪ w (BSBHF$MJFOU͕ϦΫΤετ࣌ʹηοτ w ϦΫΤετઌʹ w
4FOUSZ w ϦΫΤετ*%ͰΤϥʔΛݕࡧ
αʔόʔʗ࣮ߦڥʗߏཧ
%PDLFS w ϙʔλϒϧͳ࣮ߦڥ w TUBHJOHQSPEVDUJPOόονಉ͡Πϝʔδ w ڥґଘڥมͱͯ͠ೖ w ຊମͷڊେ3BJMTͳͲҰ෦Λআ͖ɺ΄ͱΜͲͷΞϓϦέʔ γϣϯ͕%PDLFS
w ΞϓϦέʔγϣϯͷϦϙδτϦʹ%PDLFSpMF w ։ൃऀ͕खݩͰ࿔ΕΔΑ͏ʹ w ϖωτϨςετڥͳͲඞཁʹԠ͙ͯ͢͡࡞ΕΔ
ϏϧυύΠϓϥΠϯ w$*ͰΞϓϦέʔγϣϯͷςετ w%PDLFSΠϝʔδ࡞ wBTTFUQSFDPNQJMFࡁΈͷΠϝʔδ wTUBHJOHʹࣗಈσϓϩΠ wQSPEVDUJPODIBUPQTͰσϓϩΠ
)BLP w HJUIVCDPNFBHMFUNUIBLP w %PDLFSΞϓϦ༻ͷσϓϩΠπʔϧ w ΫοΫύουͰόοΫΤϯυʹ&$4Λར༻ w ΞϓϦέʔγϣϯ͝ͱͷઃఆ:".-Ͱཧ w
ڥ͝ͱʹڥมΛઃఆͰ͖Δ w ൿಗFUDFOWFUDWBVMUͰཧ
FUDFOWFUDWBVMU w HJUIVCDPNTPSBIFUDFOW w FUDEͰઃఆΛཧ w HJUIVCDPNTPSBIFUDWBVMU w FUDEͷΛ҉߸Խ w
ͱͱFUDEʹ"$-͕ແ͔ͬͨͨΊ࡞ΒΕͨ w ࢦఆͷ伴Λ͍࣋ͬͯΔΠϯελϯεͰ͔͠෮߸ Ͱ͖ͳ͍
FUDXFC w HJUIVCDPNTPSBIFUDXFC
DIBUPQT w )VCPUͰσϒϩΠ w σϓϩΠδϣϒ3VOEFDLͰཧ w σϓϩΠํ๏͕౷Ұ͞Ε͍ͯΔ w νϟοτݟͯΔͱΘ͔Δ
όονδϣϒ
,VSPLP wશαʔϏεͷδϣϒΛҰׅཧ ‣ ϫʔΫϑϩʔཧ ผαʔϏεͷδϣϒΛϑοΫ͢Δ ‣ 8FCίϯιʔϧͰΤϥʔ֬ೝɾ࠶࣮ߦ
,VSPLP wαʔϏεͷ࠷৽ͷ%PDLFSΠϝʔδΛ࣮ߦ ‣ αʔϏε͝ͱͷϫʔΧʔڥෆཁ ‣ Ҏલ֤ΞϓϦͰLVSPLPઐ༻ͷߏཧΛ ༻ҙ͍ͯͨ͠ ‣ ֤αʔϏεͷΞϓϦέʔγϣϯ͕ͦͷ··ಈ ͘
νʔϜ͝ͱͷαϙʔτ νʔϜΛԣஅͨ͠ҙࢥܾఆ
ٕज़ྖҬ՝ڞ༗ձ w֤νʔϜͷٕज़Ϧʔμʔͱٕज़ج൫ʴΠϯϑϥ Ͱٕज़తͳ՝ʹ͍ͭͯ͠߹͏ w։ൃ͢Δͱ͖ʹࠔ͍ͬͯΔ͜ͱ w͋ͬͨΒخ͍͠ͷɺ͏ཁΒͳ͍ͷ wΈΜͳ͕ࠔ͍ͬͯΔʗඞཁͱ͍ͯ͠Δͷ͔ɺ ͦͷνʔϜ͚ͩͳͷ͔
ٕज़ج൫୲ w ֤νʔϜͷٕज़తͳࠩ w ٕज़ج൫ʹ·Θ͢༨ྗ͕͋Δʗͳ͍ w ج൫ܥͷܦݧ͕͋Δϝϯόʔ͕͍Δʗ͍ͳ͍ w ֤νʔϜʹઐͷٕज़ج൫୲ w
௨ৗͷґཔͱผʹΧδϡΞϧʹ૬ஊͰ͖Δ w ͕ͬͭΓೖͬͯվળ͢Δ͜ͱ
·ͱΊ w αʔϏεߏ ‣ ϓϩμΫτϑΥʔΧεʗ#''ʗڞ௨ج൫ w αʔϏεؒͷ࿈ܞ ‣ 3&45GVM)ZQFSNFEJB"1*(BSBHF ‣
$%$UFTUJOH1BDU w%PDLFSΛத৺ͱͨ͠ڥ ‣ )BLP &$4 FUDFOWFUDWBVMU ,VSPLP wνʔϜ࿈ܞʗαϙʔτ ‣ ٕज़ྖҬ՝ڞ༗ձɺٕज़ج൫୲