Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2重リクエスト完全攻略HANDBOOK / Double Request Handbook

Avatar for ShoheiMitani ShoheiMitani
September 26, 2025

2重リクエスト完全攻略HANDBOOK / Double Request Handbook

Kaigi on Rails 2025

Avatar for ShoheiMitani

ShoheiMitani

September 26, 2025
Tweet

More Decks by ShoheiMitani

Other Decks in Technology

Transcript

  1. 2ॏϦΫΤετ • ޡͬͯෳ਺ճಉ͡ϦΫΤετ͕ૹΒΕɺॏෳͯ͠ॲཧ͕ߦΘΕͯ͠·͏͜ͱ • αϒϛοτϘλϯ͕2ճԡ͞Εͨ • ొ࿥ը໘͕Ϧϩʔυ͞Εͨ • ֎෦αʔϏε͔Βෳ਺ճಉ͡σʔλ͕ૹΒΕͨ •

    όον͕2ճ࣮ߦ͞Εͨ • 2ॏαϒϛοτͱ͍͏ݴ͍ํ΋͋Δ͕ɺWebϒϥ΢βҎ֎ʹ΋ى͜Γ͏Δ໰୊ Λѻ͍͍ͨͷͰ2ॏϦΫΤετͱݺͿ • 2ճҎ্ϦΫΤετ͢ΔଟॏϦΫΤετ΋2ॏϦΫΤετͱݺͿ͜ͱʹ͢Δ
  2. ΋͠2ॏϦΫΤετ͕ൃੜͨ͠Β…?? • ܝࣔ൘ʹಉ͡಺༰͕2ճ౤ߘ͞ΕΔ... • ಉ͡঎඼͕2ճߪೖ͞Εͯɺ2ॏͰ࢒ߴ͕ݮΔ͜ͱʹ… • ܾࡁ / ૹۚ /

    ༧໿ / ग़඼ / ౤ථ / ใु෇༩ / ਃ੥ / etc… • ѱ༻͞Εͯෆਖ਼߈ܸΛड͚ΔηΩϡϦςΟϗʔϧʹ… • Etc…
  3. 2ॏϦΫΤετͷରࡦ͸ҙ֎ͱ೉͍͠ • ΫϥΠΞϯτͰ੍ޚ͢Ε͹͍͍Μ͡Όͳ͍ͷ͔ʁ • ΫϦοΫ࿈ଧ / ϖʔδ࠶ಡΈࠐΈ / ໭Δˠ࠶ૹ৴ͳͲɺͲ͜·ͰରԠͰ͖Δʁ •

    ϒϥ΢βͷσϕϩούʔπʔϧͰૢ࡞͞ΕͨΒʁ • ෳ਺λϒʗෳ਺୺຤͔Βಉ࣌ʹૢ࡞͞Εͨ৔߹ʹͰ͖Δରࡦ͸ʁ • ֎෦αʔϏε͔Βͷࣗಈ࠶ૹͳͲɺΫϥΠΞϯτଆΛ੍ޚͰ͖ͳ͍৔߹ʹ͸ʁ • όοΫΤϯυͰςʔϒϧઃܭΛ্ख͘΍Ε͹େৎ෉Ͱ͠ΐ • ϢχʔΫ੍໿͕͚ͭΒΕͳ͔ͬͨΓɺϩοΫ͕औΕͳ͍ঢ়گ΋͋Δ • ҙਤͨ͠ෳ਺ճͷૢ࡞ͱɺࣄނతʹൃੜͨ͠2ॏϦΫΤετΛ൑ผͰ͖Δʁ
  4. Θ͟Θ͟Kaigi on RailsͰൃද͢Δ΄Ͳʁ • WebͰݕࡧͯ͠ग़ͯ͘Δํ๏͸Webϒϥ΢βΛલఏͱ ͯ͠΋ͷ͕ଟ͍ • ʮJavaScritptͰʙʯʮ֬ೝμΠΞϩάग़ͯ͠ʙʯ • ʮઈରʹೋॏαϒϛοτΛڐ͞ͳ͍༑ͷձʯͷϒϩά͸Α

    ͘·ͱ·ͬͯΔ • ݱ࣮ͷΞϓϦέʔγϣϯ͸ෳࡶͰ৭ʑͳέʔε͕͋Δ • ຖճɺରࡦΛௐ΂ͨΓಠࣗʹฤΈग़͢͜ͱʹർΕͨ • ͜Ε͚ͩݟ͓͚ͯ͹େମΧόʔ͞ΕͯΔ΋ͷΛ࡞Γ͍ͨ https://qiita.com/unmelt/items/fb1eff5a2d9bc4da1f7e
  5. ࠓ೔ͷൃදςʔϚ • ୭ʹͱͬͯ΋਎ۙͰॏཁͳ2ॏϦΫΤετ໰୊ʹ೰·ͳ͍͍ͯ͘ੈքΛ࡞Δ • 2ॏϦΫΤετͷ໰୊΁ͷཧղ • ༷ʑͳ2ॏϦΫΤετରࡦ΁ͷཧղ • ϢʔεέʔεʹԠͨ͡ϕετϓϥΫςΟεͷ୳ࡧ •

    ྩ࿨7೥࣌఺Ͱͷ৘ใΛ·ͱΊͨHANDBOOKΛఏڙ • ۀ຿Ͱૺ۰ͨ࣌͠ʹݟฦͤΔࢿྉͱͳΕ͹޾͍ • ଞʹ΋͜͏͍͏ͷ͋ΔΑʂͬͯํ๏͋Ε͹ڭ͍͑ͯͩ͘͞🙌 • ݸʑͷରࡦͷৄࡉ͸ׂѪ͠·͢
  6. ࣗݾ঺հ ࡾ୩ ণฏ Έͨʹ ͠ΐ͏΁͍ εϚʔτόϯΫ Engineering Manager / Software

    Engineer • SIer → Fablic → ָఱ → εϚʔτόϯΫ • ΤϯδχΞྺ11೥໨ɺRailsྺ7೥໨ • Welcome Fintech Community ӡӦ
  7. ೔ৗͰ࢖͍ͬͯΔαʔϏεͷཪଆΛެ։Մೳͳܗʹམͱ͠ࠐΜͰൃද͢Δͷ͕޷͖ builderscon 2024 YAPC::Hiroshima 2024 YAPC::Fukuoka 2025 eKYC Χʔυܾࡁ ڝഅ

    x ػցֶश χον͗ͯ͢ڵຯ࣋ͨΕͳ͍? ެ։͢Δͱڝ߹༏Ґੑࣦ͏? ڪΕͣൃද͢Δ͜ͱͰಘΒΕΔ͜ͱ͸ଟ͍
  8. ࠓ೔͸ͬͪ͜ͷ࿩ Kaigi on Rails 2022 Kaigi on Rails 2021 Kaigi

    on Rails 2023 ։ൃݱ৔Ͱͷ࣮ઓ஌Λந৅Խɾ൚༻తֶͯ͠ͼʹม͍͑ͯ͘׆ಈ΋޷͖ ؂ࢹ ঢ়ଶ؅ཧ ςʔϒϧఆٛมߋ
  9. લఏ͢Γ߹Θͤʙ঺հ͢Δ๷ޚࡦͷείʔϓʙ • POST / PUT / DELETE౳ͷߋ৽ܥૢ࡞Λத৺ʹѻ͏ʢGET΁ͷԠ༻͸Մʣ • ૹ৴ऀଆʹѱҙ͸ͳ͍͕ࣄނతʹ2ॏϦΫΤετ͕ൃੜ͢Δ໰୊΁ͷ๷ޚࡦ •

    αϒϛοτϘλϯ͕Կ౓΋ԡͤΔ౳ͷ࣮૷࿙Ε • όοΫΤϯυͰͷλΠϜΞ΢τʹΑΓɺΫϥΠΞϯτ͔Β࠶ૢ࡞͕Ͱ͖Δέʔε • ૹ৴ऀଆ͕ѱҙΛ࣋ͬͯ2ॏϦΫΤετΛߦ͏Α͏ͳ໰୊΁ͷ๷ޚࡦ • ੬ऑੑΛಥ͍ͨϦϓϨΠ߈ܸ / ෳ਺୺຤Ͱͷಉ࣌ૢ࡞ • ࢓༷ͱͯ͠ಉ͡಺༰ͷૢ࡞͕ڐ༰͞Ε͍ͯΔέʔεͱͷ۠ผ͢Δํ๏ • ಉҰ঎඼ͷߪೖ / ࿈౤౤ߘ
  10. ᶃ αϒϛοτϘλϯͷ੍ޚ ᶄ Post-Redirect-Get (PRG) ύλʔϯ ᶅ ഉଞ੍ޚ • Ϧιʔεͷ൵؍ϩοΫ

    • FIFOʹΑΔॱং੍ޚ • ΞυόΠβϦʔϩοΫ ᶆ ςʔϒϧઃܭ • ঢ়ଶભҠͷϧʔϧԽ • ϢχʔΫ੍໿ ࠓ೔঺հ͢Δ๷ޚࡦͨͪ ᶇ ϨʔτϦϛοτ ᶈ APIΩϟογϡ ᶉ Idempotency-Keyϔομ ᶊ ETag ʴ If-Match ᶋ ϫϯλΠϜτʔΫϯ
  11. • ϒϥ΢βͷϦϩʔυʹΑΔ2ॏϦΫΤετΛ๷͙ํ๏ • POSTϦΫΤετͷ׬ྃ࣌ɺ௚઀HTMLΛฦ٫͢ΔͷͰ͸ͳ ͘ɺ݁Ռදࣔϖʔδ΁ϦμΠϨΫτ͢ΔϨεϙϯεΛฦ͢ • ॲཧ׬ྃޙʹϒϥ΢βͰϦϩʔυΛͯ͠΋ɺϦμΠϨΫτઌ΁ ͷGETॲཧͱͳΔͨΊɺݩͷPOSTॲཧͷ2ॏϦΫΤετ͕ى ͖ͳ͍ •

    ໭ΔϘλϯͰલը໘ʹ໭͔ͬͯΒɺ΋͏Ұ౓αϒϛοτϘλ ϯΛԡ͞ΕΔέʔεʹ͸ແྗͳͷͰɺผରࡦ͕ඞཁ ᶄ Post-Redirect-Get (PRG) ύλʔϯ ΫϥΠΞϯτ αʔόʔ POST REDIRECT GETʢ݁Ռը໘ʣ HTML ϦϩʔυʢGETʣ 🐟
  12. ᶅ ഉଞ੍ޚʙϦιʔεͷ൵؍తϩοΫʙ • RDBΛར༻͍ͯ͠Δ৔߹ʹ࠷΋؆୯ʹར༻Ͱ͖Δͷ͸൵؍తϩοΫ • User. fi nd(1).with_lock { …

    } • ૢ࡞ର৅ʹରͯ͠ɺద੾ͳϩοΫΛऔΕΔϦιʔε͕ଘࡏ͠ͳ͍৔߹΋͋Δ • ΞυόΠβϦʔϩοΫͷར༻ʢMySQL: GET _LOCK / PostgreSQL: pg_advisory_lockʣ • ActiveRecord::Base.connection.get_advisory_lock(“UserID#{user_id}:Payment”) • ϩοΫઐ༻ͷςʔϒϧ΍RedisΛ࢖͏౳ߟ͑ΒΕΔ • ඇಉظతʹॲཧΛͯ͠ྑ͍৔߹ʹ͸FIFOΩϡʔΛ࢖͏͜ͱ΋ • FIFOʢFirst-in, First-outʣͷΩϡʔΛ࢖͏͜ͱͰɺΩϡʔ୯ҐͰॱ൪ʹॲཧ͕ߦΘΕΔ ͨΊɺϩοΫΛऔಘͨ࣌͠ͱಉ͡Α͏ʹഉଞ੍ޚ͞ΕΔ 🐟
  13. ᶅ ഉଞ੍ޚʙ஫ҙ఺ʙ • ഉଞ੍ޚ͸ಉ࣌ʹૢ࡞͞ΕΔ͜ͱΛ๷͍Ͱ͍Δ͚ͩͳͷͰɺϩοΫղ์͞Εͨ ޙͷॲཧ΁ͷରԠ͸ผ్ߟ͑Δඞཁ͕͋Δ • ଈ࣌Τϥʔʹ͢ΔͳΒ : User. fi

    nd(1).with_lock(“FOR UPDATE NOWAIT”) { … } • ଈ࠲Τϥʔ΋ɺಉ࣌ʹϩοΫΛऔಘͨ͠৔߹ʹݶΔͷͰɺλΠϜϥά͕͋ͬͯ2ॏϦΫ Τετ͕དྷͨ࣌ͷ͜ͱΛߟ͑Δඞཁ͕͋Δ • ϩοΫͷऔಘൣғʹ͸஫ҙ͕ඞཁ • 2ॏϦΫΤετΛ๷͍͗ͨAPIҎ֎ͰϩοΫղ์଴͕ͪൃੜ͠ɺϨεϙϯελΠϜ͕ѱ Խ͢Δͷ͸͋Δ͋Δͳ໰୊ 🐟
  14. ঢ়ଶભҠͷϧʔϧԽ vs ϢχʔΫ੍໿ • ঢ়ଶભҠͷϧʔϧԽͰ͸ɺϩετΞοϓσʔτ΁ͷ஫ҙ͕ඞཁ • ผτϥϯβΫγϣϯͷ಺༰͕ಡΈऔΕͳ͍ͨΊɺӈਤͩͱ੥ٻ → ੥ٻ΁ͷঢ়ଶมߋΛNGͱ͢ΔΑ͏ͳϧʔϧ͸͢Γൈ͚ΒΕΔ •

    τϥϯβΫγϣϯΛషΔ৔߹ʹ͸ഉଞ੍ޚͱηοτͰߟ͑Δ΂͖ • ޙ͔Βॲཧͨ͠಺༰Ͱ্ॻ͖ͯ͠໰୊ͳ͍࢓༷Ͱ͋Ε͹ෆཁ • ϢχʔΫ੍໿ͷ৔߹ɺτϥϯβΫγϣϯΛίϛοτͨ͠λΠϛ ϯάͰΤϥʔ͕ൃੜ͢ΔͨΊɺϩοΫ͸ෆཁͳར఺͕͋Δ • σʔλϕʔεͷ੍໿͸ศར TRN1 TRN2 *%  ঢ়ଶ ஫จ ೔࣌ ࣌෼ Table Table Table *%  ঢ়ଶ ੥ٻ ೔࣌ ࣌෼ *%  ঢ়ଶ ੥ٻ ೔࣌ ࣌෼ 🐟
  15. ᶇ ϨʔτϦϛοτ • ഉଞ੍ޚ / ঢ়ଶભҠͷϧʔϧԽ / ϢχʔΫ੍໿͸͍ͣΕ΋ΞϓϦέʔγϣϯ಺Ͱσʔλ ͷ੔߹ੑΛอͭͨΊͷΞϓϩʔν •

    ΫϨδοτΧʔυʹਃ͠ࠐΉͳͲɺݱ࣮ͱͯ͠ࢦఆظؒʹෳ਺ૢ࡞͞Εͳ͍ͱ࢓্ׂ༷ Γ੾ΕΔػೳͰ͋Ε͹ɺΑΓ্ҐϨΠϠʔͰͷ๷ޚ͕Մೳ • ϨʔτϦϛοτ : γεςϜ΁ͷա౓ͳෛՙΛ๷͙ͨΊʹɺҰఆظؒ಺ʹॲཧͰ͖Δ ϦΫΤετ΍τϥϑΟοΫͷྔΛ੍ݶ͢Δख๏ͷ͜ͱ • ϢʔβʔIDͳͲΛΩʔʹAPIʹϨʔτϦϛοτΛಋೖ͠ɺҰఆظؒ͸1ճ͔͠ϦΫΤε τͰ͖ͳ͍Α͏ʹ͢Δ౳ 🐟
  16. ϨʔτϦϛοτͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'/PU&YJTU  ঎඼ͷϩοΫ  ߪೖঢ়ଶ΁ͷมߋ  &UDʜ

    σʔλετΞ 🎁ߪೖ׬ྃ 🐟 1045QBZNFOUT nJUFN@JEJUFN@ 1BZNFOUJUFN $IFDL 63-1045QBZNFOUT *UFN*%JUFN@ 4BWF 63-1045QBZNFOUT *UFN*%JUFN@ 55-
  17. • Amazon API GatewayͳͲͷඪ४ػೳʢεϩοτϦϯάʣΛར༻͢Δ͜ͱ΋Մೳ • εϩοτϦϯάͷద༻ൣғʢϦʔδϣϯ / APIΩʔ/ϝιουʣͷઃܭ࣍ୈ • ྫ:

    toB޲͚αʔϏεͷΫϥΠΞϯτຖʹAPI KeyΛൃߦ͠ɺͦͷKeyϨϕϧͰಛఆ ΤϯυϙΠϯτͷϦΫΤετΛ1ճʹߜΔͳͲ • ࡉ͔͍୯ҐͰ੍ޚ͕ඞཁͳ৔߹͸ࣗલߏங͢Δඞཁ͋Γ • rack-attack gem / throttling gem ͋ͨΓ͕ࢀߟʹͳΔ͔΋ • Rails 8͔Βඪ४ͰϨʔτϦϛοτͷػೳ͕ೖͬͨ ϨʔτϦϛοτͷิ଍ 🐟
  18. APIΩϟογϡͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'/PU&YJTU  ঎඼ͷϩοΫ  ߪೖঢ়ଶ΁ͷมߋ  &UDʜ

    σʔλετΞ 🎁ߪೖ׬ྃ 🐟 1045QBZNFOUTJUFN@ 1BZNFOUJUFN $IFDL ,FZ1045QBZNFOUTJUFN@ 4BWF ,FZ1045QBZNFOUTJUFN@ 3FTQPOTF#PEZYYYY 55-
  19. Idempotency-Keyϔομͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'/PU&YJTU  ঎඼ͷϩοΫ  ߪೖঢ়ଶ΁ͷมߋ  &UDʜ

    σʔλετΞ 🎁ߪೖ׬ྃ 1045QBZNFOUT nJUFN@JEJUFN@= )t*EFNQPUFODZ,FZYZ[u 1BZNFOUJUFN $IFDL ,FZYZ[ 4BWF ,FZYZ[ 3FTQPOTF#PEZYYYY 55- 🐟 📱 🪏,FZ࠾൪
  20. Idempotency-Keyϔομͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'&YJTU  3FTQPOTF#PEZͷऔಘ σʔλετΞ 🎁ߪೖ׬ྃ 1BZNFOUJUFN DBDIFE

    🐟 📱 1045QBZNFOUT nJUFN@JEJUFN@= )t*EFNQPUFODZ,FZYZ[u 🪏,FZ࠾൪ $IFDL ,FZYZ[
  21. APIΩϟογϡ vs Idempotency-Keyϔομ • Idempotency Keyϔομ͸APIΩϟογϡΑΓෳࡶ͕Ώ͑ʹॊೈ͔ͭݎ࿚ʹႈ౳ͳAPIαʔ όʔΛ࡞ΕΔ • ΫϥΠΞϯτ͕஋Λ࠾൪ͯ͠ઃఆ͢ΔͨΊɺႈ౳ͷൣғ͕APIΩϟογϡΑΓ΋ݫີ •

    ಉҰ୺຤Ͱͷૢ࡞Λ൑ผ͢Δ͜ͱ͕Ͱ͖Δ • ಉҰ୺຤ͰͷϦτϥΠૢ࡞ͱɺ1͔Βͷ΍Γ௚͠ͷૢ࡞΋൑ผͰ͖Δ • ະॲཧ / ॲཧத / ॲཧࡁΈͱࡉ͔͘ॲཧεςʔλεΛ؅ཧͰ͖Δ • ةݥͳߋ৽ܥͷૢ࡞ʹରͯ͠΋҆શʹႈ౳ੑΛ࣋ͨͤΔͨΊʹ͸ɺAPIΩϟογϡΑΓ΋ Idempotency-Keyϔομͷํ͕༏Ε͍ͯΔ • ෭࡞༻͕গͳ͍؆қతͳૢ࡞Ͱ͋Ε͹APIΩϟογϡͰे෼ͳέʔε΋ 🐟 📱
  22. ᶊ ETag ʴ If-Match • ETagʢEntity Tagʣͱ͍͏ߋ৽ର৅ͷόʔδϣϯΛλά؅ ཧ͠ɺIf-MatchϔομͰ৚݅෇͖ߋ৽ϦΫΤετΛૹΔ͜ ͱͰ2ॏϦΫΤετΛ๷͙ํ๏ʢָ؍తϩοΫʣ •

    αʔόʔଆͰ͸ɺΫϥΠΞϯτ͔ΒૹΒΕͨETagͷ஋Λ ൺֱ͠ɺόʔδϣϯ͕Ұகͨ͠ΒॲཧΛߦ͍ɺෆҰகͷ৔ ߹ʹ͸412 Precondition FailedΛฦ٫͢Δ • ӈͷྫͩͱόʔδϣϯΧϥϜΛETagͱͯ͠ར༻͢Δ͜ͱ΋ Ͱ͖Δ͠ɺ಺༰ͷtext͔ΒHash஋ΛٻΊͯETagͱ͢Δ͜ ͱ΋Մೳ 🐟 📱
  23. ETag ʴ If-Matchͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'7FSTJPO.BUDI  ঎඼ͷϩοΫ  &UDʜ

    σʔλετΞ 🎁ߪೖ׬ྃ 1045QBZNFOUT nJUFN@JEJUFN@= )t*G.BUDIu 1BZNFOUJUFN (FU*UFN 7FSTJPO 🐟 📱 (&5JUFNTJUFN@ &5BH 6QEBUF*UFN 7FSTJPO $IFDL $VSSFOU7FSTJPO
  24. ETag ʴ If-Matchͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'7FSTJPO/PU.BUDI  Τϥʔॲཧ σʔλετΞ 1045QBZNFOUT

    nJUFN@JEJUFN@= )t*G.BUDIu ❌1SFDPOEJUJPO'BJMFE (FU*UFN 7FSTJPO 🐟 📱 (&5JUFNTJUFN@ &5BH $IFDL $VSSFOU7FSTJPO 💀ߪೖࣦഊ
  25. ϫϯλΠϜτʔΫϯͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'5PLFOJT7BMJE  ঎඼ͷϩοΫ  &UDʜ σʔλετΞ 🎁ߪೖ׬ྃ

    1045QBZNFOUT nJUFN@JEJUFN@= nUPLFOYZ[ 1BZNFOUJUFN *TTVF UPLFOYZ[ 🐟 📱 1045UPLFOT 5PLFOYZ[ %FMFUF5PLFO $IFDL UPLFOYZ[
  26. ϫϯλΠϜτʔΫϯͷϑϩʔ 📱ΫϥΠΞϯτ 🐟αʔόʔ ⚙*'5PLFOJT*OWBMJE  Τϥʔॲཧ σʔλετΞ 1045QBZNFOUT nJUFN@JEJUFN@= nUPLFOYZ[

    ❌'PSCJEEFO *TTVF UPLFOYZ[ 🐟 📱 1045UPLFOT 5PLFOYZ[ %FMFUF5PLFO $IFDL UPLFOYZ[ 💀ߪೖࣦഊ
  27. ᶃ αϒϛοτϘλϯͷ੍ޚ ᶄ Post-Redirect-Get (PRG) ύλʔϯ ᶅ ഉଞ੍ޚ • Ϧιʔεͷ൵؍ϩοΫ

    • FIFOʹΑΔॱং੍ޚ • ΞυόΠβϦʔϩοΫ ᶆ ςʔϒϧઃܭ • ঢ়ଶભҠͷϧʔϧԽ • ϢχʔΫ੍໿ ঺հͨ͠๷ޚࡦͨͪ ᶇ ϨʔτϦϛοτ ᶈ APIΩϟογϡ ᶉ Idempotency-Keyϔομ ᶊ ETag ʴ If-Match ᶋ ϫϯλΠϜτʔΫϯ
  28. ൃදऀͷߟ͑ • جຊ͸αϒϛοτϘλϯͷ੍ޚ / PRGύλʔϯ / ഉଞ੍ޚ + ςʔϒϧઃܭΛߦ ͳ͍ͬͯΕ͹े෼ͳέʔε͕ଟ͍

    • σʔλͷ੔߹ੑ͕֬อ͞ΕΔΑ͏ςʔϒϧઃܭΛ͍ͯ͠Ε͹க໋తͳ໰୊͸ى͖ͳ͍ • 2ॏϦΫΤετࣗମɺશମͷϦΫΤετ͔ΒݟΔͱΤοδέʔεʹ౰ͨΔͷͰɺ2ॏϦ ΫΤετ͕ൃੜͨ͠ࡍͷඃ֐΍ಘΒΕΔϝϦοτΛ૝ఆͯ͠ɺద੾ͳΞϓϩʔνΛબ ୒͢΂͖ • ϫϯόϯΫͰ࣮ࡍʹར༻͍ͯ͠Δ๷ޚࡦΛཧ༝ͱͱ΋ʹ঺հ
  29. Idempotency-Keyϔομ • ֎෦αʔϏεͱͷ࿈ܞॲཧ͸ෳࡶʹͳΓ͕ͪ • ෳ਺ͷDB τϥϯβΫγϣϯ͕ඞཁͰഉଞ੍ޚ͕ෳࡶʹͳΔ • ࣗαʔϏεଆͱ֎෦αʔϏεଆͷ྆ํͰσʔλෆ੔߹͕ൃ ੜ͢ΔՄೳੑ͕͋ΓɺϦΧόϦॲཧ͕େม •

    Idempotency-KeyϔομΛར༻ͯ͠ຊॲཧͷલஈͰ2ॏ ϦΫΤετ΁ͷରࡦΛߦ͏͜ͱͰɺσʔλෆ੔߹͕ൃ ੜ͢ΔϦεΫΛݮΒ͢͜ͱ͕Ͱ͖Δ ֎෦αʔϏε ݺͼग़͠ લॲཧ τϥϯβΫγϣϯ ޙॲཧ τϥϯβΫγϣϯ ֎෦αʔϏεݺͼग़͠ॲཧ Idempotency-Key ϔομʹΑΔ๷ޚ
  30. Idempotency-Keyϔομ • ࣄނతͳ2ॏϦΫΤετͱҙਤతͳผϦΫΤετΛ۠ผ͢Δ͜ͱ͕Ͱ͖Δͷ΋ັྗత • ྫ͑͹ϓϦϖΠυΧʔυ΁ͷೖۚॲཧ͸୹࣌ؒͰෳ਺ճߦΘΕͯ΋͓͔͘͠ͳ͍ • Key͕ಉ͡ = ࣄނతͳϦΫΤετɺKey͕ҟͳΔ =

    ҙਤతͳϦΫΤετͱ۠ผͰ͖Δ • ҰํɺKeyͷνΣοΫॲཧ΍ొ࿥ॲཧͳͲͷΦʔόʔϔου͕૿͑ͨΓɺΫϥΠΞϯτଆ ͰͷKey࠾൪ॲཧͷ࣮૷ͳͲ࣮૷ίετ͕͔͔ΔͨΊɺಋೖՕॴ͸ݶఆత
  31. ϫϯλΠϜτʔΫϯ • Ϣʔβʔͷࣄނతͳ2ॏϦΫΤετΛ๷ࢭ͢Δ໨తͰ͸ͳ͘ɺϦΫΤετ಺༰ͷ౪ௌͳͲ ʹΑΔϦϓϨΠ߈ܸΛ๷͙໨తͷͨΊʹ࢖༻ • ϦϓϨΠ߈ܸ : αΠόʔ߈ܸͷҰछͰɺ௨৴ͰҰ౓ૹ৴͞Εͨਖ਼نͷσʔλΛ๣ड͠ɺͦ ͷ··࠶ૹ৴͢Δ͜ͱͰɺෆਖ਼ͳಈ࡞Λ༠ൃ͢Δ߈ܸ •

    ೖۚॲཧ͕౪ௌ͞ΕͯԿ౓΋ෆਖ਼ೖۚ͞ΕΔͳͲͷ߈ܸΛ๷͙ • ࣄނతͳ2ॏϦΫΤετΛ๷͙ͨΊɺIdempotency-Keyϔομͱ૊Έ߹Θ࣮ͤͯ૷͍ͯ͠ ΔAPI΋ଟ͍ • τʔΫϯऔಘϑϩʔͳͲ࣮૷ίετ΍ɺϢʔβʔͷख͕ؒൃੜ͢Δํ๏ͳͷͰɺ࣮૷Օॴ ͸ηΩϡϦςΟڧ౓Λ্͍͛ͨՕॴͷΈ
  32. ϨʔτϦϛοτ • όʔνϟϧΧʔυͱ͍͏෺ཧతͳΧʔυ͸ൃߦ͞ΕͣΧʔυ ൪߸͚ͩೖखͰ͖ΔػೳͷൃߦॲཧͰར༻ • όʔνϟϧΧʔυ͸Կ౓Ͱ΋࠶ൃߦͰ͖Δ͕ɺ୹࣌ؒʹԿ౓ ΋࠶ൃߦ͢Δ͜ͱ͸ਖ਼ৗͳঢ়ଶͰ͸ͳ͍ • ؒҧ͑ͯΧʔυൃߦ͕ى͖ͨࡍ͸֎෦αʔϏεଆͷमਖ਼΋ඞ ཁͰӡ༻ίετ͕ߴ͍

    • Χʔυൃߦ͸2ͭͷαʔϏεʹލͬͯॲཧ͞ΕΔ͕ɺΧʔυൃ ߦଆͰϩοΫΛऔಘͰ͖Δద౰ͳϦιʔε͕ଘࡏ͠ͳ͔ͬͨ • Ϣʔβʔຖͷൃߦճ਺Λอଘ͠ɺࢦఆճ਺Λ௒͑ͨΒΤϥʔ ൃੜ͢Δ࢓༷ʹ ϞόΠϧΞϓϦ #'' *TTVJOH"1* $PSF"1* ֎෦αʔϏε
  33. ςʔϒϧઃܭ + Ωϟογϡ • ίϯϏχ / ϖΠδʔͳͲͷೖۚํ๏Ͱ͸ɺϢʔβʔ͕ϨδͰ͓ۚ Λࢧ෷ͬͨޙʹ׬ྃ৘ใ͕WebhookͰૹΒΕΔ • Webhookʹ͸ϦτϥΠػೳ͕ఏڙ͞Ε͍ͯΔ͜ͱ͕ଟ͍

    • λΠϜΞ΢τ͕ൃੜ͢Δͱ֎෦αʔϏεଆʹ͸Τϥʔ൑ผ͞Εͨ ͚Ͳ࣮ࡍʹ͸੒ޭঢ়ଶͱ͍͏σʔλෆ੔߹͕ൃੜ͢Δ • ϦτϥΠ࣌ʹɺςʔϒϧઃܭͰ੔߹ੑΛอ͍ͬͯΔ͔ΒͱΤϥʔ ൃੜͤ͞ΔͱΤϥʔϧʔϓ͕ൃੜ͢Δ • ֎෦αʔϏεΛར༻͍ͯ͠Δͱ͖͸ɺIdempotency-Keyϔομͳ ͲͷΫϥΠΞϯτଆͷมߋ͕Ͱ͖ͳ͍ ֎෦ αʔϏε αʔόʔ POST TIMEOUT RETRY ? DB Table SAVE SUCCESS