Save 37% off PRO during our Black Friday Sale! »

Salariesを支えるチーム開発の現場

E990ee82706811d4fa5bcafa1b4eafbf?s=47 techtekt
November 11, 2021

 Salariesを支えるチーム開発の現場

E990ee82706811d4fa5bcafa1b4eafbf?s=128

techtekt

November 11, 2021
Tweet

Transcript

  1. 4BMBSJFTΛࢧ͑ΔνʔϜ։ൃͷݱ৔ ٕҭ$".1ษڧձ c

  2. *OEFY ❏ ಋೖ ❏ ॴଐ෦ॺ঺հ ❏ 4BMBSJFT঺հ ❏ νʔϜ։ൃ ❏

    4BMBSJFTνʔϜͷ։ൃମ੍ͳͲͷ঺հ ❏ νʔϜ։ൃΛࢧ͑ΔϑϩϯτΤϯυ ❏ νʔϜ։ൃΛࢧ͑ΔόοΫΤϯυ
  3. ຊൃදͷ໨ඪ ❏ ࣮ࡍͷ։ൃݱ৔ͰͲͷΑ͏ʹνʔϜ։ൃΛߦ͍ͬͯΔͷ͔Πϝʔδ͕Ͱ͖Δ ❏ ࢖͍ͬͯΔϥΠϒϥϦʢJPUTͳͲʣͷଘࡏΛ஌ͬͯ΋Β͏ ❏ ࣋ͪؼͬͯݸਓ։ൃͳͲͰ࢖͏͖͔͚ͬʹͳΔ ❏ ࠓޙͷνʔϜ։ൃʹ׆͔ͤΔ νʔϜ։ൃͰ࣮ࡍʹ࢖ΘΕ͍ͯΔٕज़΍։ൃख๏ͳͲΛ஌ͬͯ΋Β͏

  4. ࣗݾ঺հ ❏ ࠤ઒ ༤ඈ ❏ ೥݄ ύʔιϧΩϟϦΞೖࣾ ❏ ৬ྺ ❏

    &$γεςϜͷύοέʔδ։ൃ ❏ ҿ৯ళͰͷ଺ࡏ࣌ؒ؅ཧγεςϜ։ൃ ❏ ͓ห౰୐഑αʔϏε։ൃ ❏ ٕज़ ❏ /FYUKT /VYUKT 8FC$PNQPOFOUT
  5. αʔϏε։ൃ෦ ֓ཁ ॴଐ෦ॺ ςΫϊϩδʔຊ෦ ΤϯδχΞϦϯά౷ׅ෦ αʔϏε։ൃ෦ ैۀһ਺ ςΫϊϩδʔຊ෦ ໿໊ αʔϏε։ൃ෦

    ໿໊ ೥݄຤࣌఺ ࣄۀ಺༰ ৽نαʔϏεͷاըɾ։ൃ طଘαʔϏεͷӡ༻ɾอकɾ௥Ճ։ൃ ϛογϣϯ ʮΤϯδχΞϦϯάͷྗͰɺ৽نαʔϏεΛૉૣ͘ఏڙ͢Δʯ
  6. αʔϏεΛಉ࣌։ൃͰ͖Δ૊৫΁

  7. ϦϦʔεࡁΈͷαʔϏε

  8. None
  9. None
  10. None
  11. None
  12. ٕज़ελοΫ 'SPOUFOE "ENJO #BDLFOE *OGSBTUSVDUVSF

  13. νʔϜ։ൃ 4BMBSJFTνʔϜͷ։ൃ঺հ

  14. νʔϜߏ੒ ೥݄຤࣌఺ #VTTJOFTT ໊ ❏اը ❏Ӧۀ ❏ࣄۀࢧԉ ❏ϚʔέςΟϯά &OHJOFFS ໊

    ❏ϑϩϯτΤϯυ ❏όοΫΤϯυ ❏Πϯϑϥ ❏σʔλαΠΤϯε %FTJHOFS ໊ ❏6* ❏69 ❏άϥϑΟοΫ
  15. ։ൃϑϩʔ #VTJOFTT &OHJOFFS ཁ݅ #VTJOFTT &OHJOFFS %FTJHOFS &OHJOFFS &OHJOFFS #VTJOFTT

    &OHJOFFS %FTJHOFS 6*σβΠϯ ٕज़બఆ ։ൃ ϦϦʔε
  16. ։ൃϑϩʔ #VTJOFTT &OHJOFFS ཁ݅ #VTJOFTT &OHJOFFS %FTJHOFS &OHJOFFS &OHJOFFS #VTJOFTT

    &OHJOFFS %FTJHOFS 6*σβΠϯ ٕज़બఆ ։ൃ ϦϦʔε
  17. ։ൃϑϩʔ ։ൃ ։ൃ ։ൃ ։ൃ 'SPOUFOE #BDLFOE *OGSBTUSVDUVSF 6*࣮૷ ੩త

    "1*࢓༷࡞੒ Πϯϑϥߏங ϞοΫ"1*ͱ઀ଓ ϞοΫ"1*࡞੒ "1*࣮૷
  18. ϑϩϯτΤϯυͱόοΫΤϯυ෼͔Εͯͷ։ൃ ❏ ݉೚͢Δ͔෼͔ΕΔ͔͸νʔϜʹΑ༷ͬͯʑ ❏ ։ൃ౰ॳ͸ΤϯδχΞ໊͕ମ੍ ❏ ϑϩϯτΤϯυ୲౰ ❏ όοΫΤϯυ୲౰ ❏

    Πϯϑϥ΍ॾʑͷઃܭ౳ 1K. ❏ ͦΕͧΕ͕ಘҙ෼໺Λ୲౰ͯ͠ૉૣ͍։ൃΛ໨ࢦ͢ ❏ ਓ਺͕૿͖͑ͯͨݱࡏ͸ɺδϣϒϩʔςʔγϣϯΛ࣮ࢪ ❏ ఆظతʹ։ൃϝϯόͷϝΠϯͷ࡞ۀྖҬΛม͑Δ ❏ ݸਓͷεΩϧΞοϓ ❏ ݎ࿚ͳνʔϜ࡞ΓɾଐਓԽͷ཈੍
  19. ϦϦʔε ˠػೳ௥Ճʹ޲͚ͯ ཁ݅ 6*σβΠϯ ٕज़બఆ ։ൃ ϦϦʔε ཁ݅ 6*σβΠϯ ٕज़બఆ

    ։ൃ ϦϦʔε
  20. ϑϩϯτΤϯυ νʔϜ։ൃͰͷϑϩϯτΤϯυ঺հ ❏ "UPNJD%FTJHO ❏ 4UPSZCPPL ❏ "1*ͱͷ઀ଓ ❏ σʔλͷྲྀΕͱςετ

  21. "UPNJD%FTJHO Ҿ༻ IUUQTBUPNJDEFTJHOCSBEGSPTUDPNDIBQUFS ❏ ཁૉʹ෼͚ͯͦΕΒΛ૊Έ߹Θ࣮ͤͯ૷͢Δ6*σβΠϯͷख๏ ❏ খ͍͞ίϯϙʔωϯτͷ߹ମ ❏ "UPNT͔Βॱʹ࣮૷͢Δ ❏

    มߋ͕ଟ͘ͳΓ͕ͪͳ6*࣮૷ΛͰ͖ΔݶΓมߋʹڧ͍ߏ଄Ͱ࣮૷͍ͨ͠
  22. "UPNJD%FTJHOྫ

  23. 4BMBSJFTͰͷ"UPNT import { default as MuiButton, ButtonProps } from '@material-

    ui/core/Button'; import { makeStyles } from '@material-ui/core/styles'; interface IButtonProps extends ButtonProps { width?: string; height?: string; } const useStyles = makeStyles({ root: { width: ({ width }: IButtonProps) => width || '', height: ({ height }: IButtonProps) => height || '', } }); export const Button = (props: IButtonProps): JSX.Element => { const styles = useStyles(props); const classes = { root: styles.root }; return ( <MuiButton classes={classes} {...props}> {props.children} </MuiButton> ); }; ❏ "UPNT͸ͦΕҎ্෼ղ͞Εͯ ࢖༻͞ΕΔ͜ͱ͕ͳ͍ίϯϙʔ ωϯτ ❏ .6*Λϥοϓ ❏ NBLF4UZMFTΛ࢖֦ͬͯு ❏ QSPQTͰTUZMFมߋ ❏ 6*ϥΠϒϥϦΛϥοϓ͢Δཧ༝ ❏ ֦ுͰ͖Δ ❏ มߋରԠ࣌ͷӨڹൣғ
  24. νʔϜ։ൃͰ͸ଞͷϝϯό͕͢Ͱʹ ࣮૷ࡁͷίϯϙʔωϯτ͕͋Δ͔΋͠Εͳ͍ ࣮૷ͨ͠ίϯϙʔωϯτҰཡ͕Έ͍ͨʂ

  25. None
  26. 4UPSZCPPL "UPNT

  27. 4UPSZCPPL 0SHBOJTNT

  28. 4UPSZCPPL ❏ ࢖͍͍ͨίϯϙʔωϯτ͕͢Ͱʹଘࡏ͢Δ͔Λ୳͠΍͘͢ͳΔ ❏ σβΠφͱͷೝࣝ߹ΘͤͳͲʹ΋࢖͑Δ ❏ ΧϥʔύϨοτ ❏ ࠷ۙͰ͸4UPSZCPPLͱ'JHNBͰ੔߹ੑΛऔΔྫ΋͋Δ

  29. ϝϯόͱͷڞ༗ ❏ ࠷৽ΛࣗಈσϓϩΠ ❏ EFWFMPQϒϥϯν΁Ϛʔδ͢Δ࣌ʹ DPNQPOFOUT഑ԼͷϑΝΠϧʹมߋ ͕͋ͬͨ৔߹ʹσϓϩΠΛ࣮ߦ ❏ ߋ৽͞ΕΔͱ4MBDLͰ௨஌ on:

    push: branches: - develop paths: - 'components/**' - name: Slack Notification on SUCCESS if: success() uses: tokorom/action-slack-incoming-webhook@main env: INCOMING_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} with: text: Storyookを更新しました! attachments: | [ { "color": "good", "fields": [ { "title": "Storybook URL", "value": "(Storybookのデプロイ先のURL)" } ] } ]
  30. "1*ͱͷ઀ଓ

  31. "1*ͱͷ઀ଓ ❏ ϑϩϯτΤϯυͷ։ൃʹ͸ϞοΫ"1*ͱ઀ଓ͍ͯ͠Δ ❏ ϞοΫ"1*ͱ͸ ❏ ࢼ࡞Ͱ࡞Δ໛ܕͷΑ͏ͳΠϝʔδ ❏ ࣮ࡍͷ%#ͱ͸઀ଓͤͣʹܾ·ͬͨσʔλΛϨεϙϯε ❏

    ZBNMϑΝΠϧΛௐ੔ͯ͠ཉ͍͠σʔλΛϨεϙϯεͰ͖Δ ❏ ϑϩϯτΤϯυ౎߹ͰϨεϙϯεͷσʔλߏ଄Λมߋͯ͠΋Β͍͍ͨΑ͏ͳ৔߹Ͱ΋ ࣮ࡍͷ"1*Λ࣮૷લʹมߋͰ͖Δ ❏ ؀ڥຖʹ"1*ͷ઀ଓઌΛม͍͑ͯΔ fetch(“https://example.com/api/endpoint”)
  32. ؀ڥʹ͍ͭͯ ❏ ϩʔΧϧ؀ڥ ❏ IUUQMPDBMIPTU ❏ ϩʔΧϧͰͷ։ൃ༻ͷ؀ڥ ❏ ϩʔΧϧͰαʔόΛݐͯͯ։ൃ͢Δ ❏

    ։ൃ؀ڥ ❏ IUUQTEFWFYBNQMFDPN ❏ ຊ൪ʹࣅͤͨߏ੒Ͱߏங ❏ ϑϩϯτΤϯυͱόοΫΤϯυ݁߹ ͯ͠ͷಈ࡞֬ೝ ❏ ϏδωεαΠυ΍σβΠφͱͷ࿈ܞ ❏ εςʔδϯά؀ڥ ❏ IUUQTTUHFYBNQMFDPN ❏ ϦϦʔεલͷςετͰ࢖༻ ❏ ຊ൪؀ڥ ❏ IUUQTFYBNQMFDPN ❏ ࣮ࡍʹϦϦʔεɺՔಇ͍ͯ͠Δ؀ڥ
  33. ؀ڥຖʹ"1*ͷ઀ଓઌΛมߋ͢Δ ❏ FOWϑΝΠϧΛ࡞੒ͯ͠؀ڥม਺Λ༻ҙ͢Δ ❏ ϩʔΧϧ؀ڥͰ͸ϞοΫ"1*ɺ։ൃ؀ڥ͸։ൃ؀ڥͷ"1* ❏ ϩʔΧϧ؀ڥͰ͸ FOWMPDBMɺ։ൃ؀ڥͰ͸FOWEFWͳͲ؀ڥઃఆϑΝΠϧΛ෼͚Δ API_HOST=http://0.0.0.0:4010 PORT=3000

    API_HOST=https://dev.example.com/api PORT=8080 .env.local .env.dev
  34. σʔλͷྲྀΕ

  35. σʔλͷྲྀΕ 4UFQ ϒϥ΢β͔Βೖྗ͞ ΕͨσʔλΛऔಘ ೖྗ ม׵ "1*ίʔϧ ม׵ ඳը 4UFQ

    ೖྗ͞ΕͨσʔλΛ "1*ͷϦΫΤετͷܗ ࣜʹม׵ 4UFQ "1*Λίʔϧ͢Δ 4UFQ "1*͔ΒϨεϙϯε͞ ΕͨσʔλΛ 6*ʹ߹Θͤܗࣜʹม ׵͢Δ 4UFQ ϒϥ΢β΁ඳը͢Δ
  36. σʔλͷྲྀΕ ೖྗ ʙ ม׵ ඳը "1*ίʔϧ ม׵ ೖྗ ม׵ {

    userName: "John", age: "20" } { userName: "John", age: 20, invitationCode: null } 'PSNͷೖྗσʔλ ม׵ޙͷσʔλ
  37. σʔλͷྲྀΕ ೖྗ ʙ ม׵ // 変換 function convertFormToEntity(data: SignupForm): SignupConvertedData

    { const convertedData: SignupConvertedData = { userName: data.userName, age: Number(data.age), invitationCode: data.invitationCode || null }; return convertedData; } // Formのデータの型定義 type SignupForm = { userName: string; age: string; // Formは文字列になる invitationCode?: string; // undefinedまたは文字列 } // リクエストの形式に変換したデータの型定義 type SignupConvertedData = { userName: string; age: number; // 数値に変更 invitationCode: string | null; // 文字列またはnull } ඳը "1*ίʔϧ ม׵ ೖྗ ม׵
  38. σʔλͷྲྀΕ "1*ίʔϧ public async signup(data: SignupConvertedData) { const result =

    await fetch(“/signup”, { method: ‘post’, body: data }); return result; } ඳը "1*ίʔϧ ม׵ ೖྗ ม׵
  39. σʔλͷྲྀΕ ม׵ { userName: "John", createdAt: Thu Oct 28 2021

    18:00:00 GMT+0900 } Ϩεϙϯεͷσʔλ ඳը͢Δσʔλ { userName: "John", createdAt: “2021/10/28 18:00” } ඳը "1*ίʔϧ ม׵ ೖྗ ม׵
  40. ͳͥ͜ΜͳʹͦΕͧΕͷॲཧΛ෼ׂ͍ͯ͠Δͷ͔ 4UFQ ϒϥ΢β͔Βೖྗ͞ ΕͨσʔλΛऔಘ ೖྗ ม׵ "1*ίʔϧ ม׵ ඳը 4UFQ

    ೖྗ͞ΕͨσʔλΛ "1*ͷϦΫΤετͷܗ ࣜʹม׵ 4UFQ "1*Λίʔϧ͢Δ 4UFQ "1*͔ΒϨεϙϯε͞ ΕͨσʔλΛ 6*ʹ߹Θͤܗࣜʹม ׵͢Δ 4UFQ ϒϥ΢β΁ඳը͢Δ
  41. ൚༻తʹ࢖͏͜ͱ͕Ͱ͖ ࢓༷มߋʹ΋ରԠ͠΍͘͢ͳΔ

  42. ϩάΠϯͷ৔߹ʹ΋࢖͍ճͤΔ { userName: "John", createdAt: Thu Oct 28 2021 18:00:00

    GMT+0900 } Ϩεϙϯεͷσʔλ ඳը͢Δσʔλ { userName: "John", createdAt: “2021/10/28 18:00” } ඳը "1*ίʔϧ ม׵ ೖྗ ม׵
  43. ͦΕͧΕ۠੾ͬͯςετΛॻ͘͜ͱ͕Ͱ͖Δ 4UFQ ϒϥ΢β͔Βೖྗ͞ ΕͨσʔλΛऔಘ ೖྗ ม׵ "1*ίʔϧ ม׵ ඳը 4UFQ

    ೖྗ͞ΕͨσʔλΛ "1*ͷϦΫΤετͷܗ ࣜʹม׵ 4UFQ "1*Λίʔϧ͢Δ 4UFQ "1*͔ΒϨεϙϯε͞ ΕͨσʔλΛ 6*ʹ߹Θͤܗࣜʹม ׵͢Δ 4UFQ ϒϥ΢β΁ඳը͢Δ ݁߹ςετ σʔλม׵ͷςετ "1*ίʔϧͷςετ σʔλม׵ͷςετ
  44. ςετͷॏཁੑ ❏ ෆ۩߹ͷૣظൃݟ ❏ Өڹൣғͷߟྀ࿙ΕͰ༧ظͤ͵ՕॴͰͷෆ۩߹ʹ΋ؾͮ͘͜ͱ͕Ͱ͖Δ ❏ ෳࡶͳॲཧͰ΋ςετ͕ॻ͔Εͯ͋Δͱཧղ͠΍͘͢ͳΔ ❏ ʮςετ͸ཪ੾Βͳ͍ʯ

  45. ϑϩϯτΤϯυύʔτ ·ͱΊ ❏ "UPNJD%FTJOH ❏ খ͍͞ίϯϙʔωϯτͷ߹ମ ❏ มߋʹڧ͍ߏ଄ ❏ 4UPSZCPPL

    ❏ ίϯϙʔωϯτͷΧλϩά ❏ σʔλͷྲྀΕ ❏ ॲཧ͝ͱʹ۠੾Δ ❏ ςετ͸ॏཁ
  46. όοΫΤϯυ νʔϜ։ൃͰͷόοΫΤϯυ঺հ ❏ "1*࢓༷ ❏ 0QFO"1* ❏ 5ZQF(VBSE ❏ JPUT

  47. ࣗݾ঺հ ❏ ஑ా ༟ݾ ❏ ೥݄ ύʔιϧΩϟϦΞೖࣾ ❏ ৬ྺ ❏

    ϕϯνϟʔاۀͰ4&.΍όϦϡʔνΣʔϯվળΛ ߦ͏ɻ ❏ ৽نࣄۀͷاըΛߦ͍ɺاըӡӦΛ͓͜ͳͬͨࣄ ۀΛࢠձࣾԽ͠ࣄۀ੹೚ऀʹɻ ❏ αʔϏεΛΤϯδχΞͱͯࣗ͠෼Ͱ࡞Γ͍ͨࢥ͍ ͔Βݱ৬΁ ❏ ٕज़ ❏ /VYUKT &YQSFTTKT 'BTU"1*
  48. όοΫΤϯυͰࠓ೔͓࿩͢͠Δ͜ͱͷςʔϚ ϑϩϯτΤϯυͱͷڠྗ

  49. ΤϯδχΞ͕ҙࣝ͠΍͍͢ ։ൃεϐʔυ ։ൃϑϩʔ ΞϓϦέʔγϣϯ ͷ඼࣭ όϦσʔγϣϯ

  50. ։ൃϑϩʔ

  51. Ұൠతͳ։ൃϑϩʔ όοΫΤϯυ ϑϩϯτΤϯυ ࣮૷ ࣮૷ ϦϦʔε ࣮૷͕ਐ·ͳ͍

  52. εΩʔϚۦಈ։ൃ ❏ ༻ޠ ❏ εΩʔϚ"1*ͷ࢓༷ ❏ "1*࢓༷ԿΛड͚ͱͬͯԿΛ݁Ռͱͯ͠ฦ͢ͷ͔ΛఆΊͨ΋ͷ ❏ ར఺ ❏

    "1*ͷ࣮૷͕ͳ͍ঢ়ଶͰ΋ϑϩϯτΤϯυ͕։ൃ΍ݕূΛߦ͑Δ "1*࢓༷Λ͸͡Ίʹఆٛ͠ɼ "1*࢓༷ΛݩʹόοΫΤϯυɾϑϩϯτΤϯυ͕ಉ࣌ʹ։ൃΛਐΊ͍ͯ͘
  53. εΩʔϚۦಈ։ൃ όοΫΤϯυ ϑϩϯτΤϯυ "1*࢓༷࡞੒ ࣮૷ ϦϦʔε ࣮૷ "1*࢓༷Λݩʹ ϞοΫαʔόΛͨͯΔ

  54. εΩʔϚۦಈ։ൃ όοΫΤϯυ ϑϩϯτΤϯυ "1*࢓༷࡞੒ ࣮૷ ϦϦʔε ࣮૷ "1*࢓༷Λݩʹ ϞοΫαʔόΛͨͯΔ

  55. εΩʔϚۦಈ։ൃͰόοΫΤϯυ։ൃऀ͕ߦ͍ͬͯΔ͜ͱ "1*࢓༷࡞੒ "1*࢓༷Λݩʹ ϞοΫαʔόΛͨͯΔ ❏ "1*࢓༷ͷ࡞੒ ❏ "1*࢓༷Λਓ͕ཧղ͠΍͍͢ܗʹϑΥʔϚοτ͢Δ ❏ "1*࢓༷ΛݩʹϞοΫαʔόΛߏங

  56. 0QFO"1* ❏ 0QFO"1*ͱ͸ ❏ 3&45GVM"1*ͷυΩϡϝϯτΛهड़͢ΔͨΊͷϑΥʔϚοτ࢓༷ "1*࢓༷Λ౷Ұͨ͠ܗࣜͰهࡌ͢Δ͜ͱ͕Ͱ͖Δ

  57. 0QFO"1*ͷϑΥʔϚοτʹैͬͯ࡞੒͞ΕͨZBNM schemes: - "https" - "http" paths: /pet: post: tags:

    - "pet" summary: "Add a new pet to the store" description: "" operationId: "addPet" consumes: - "application/json" - "application/xml" produces: - "application/xml" - "application/json" parameters: - in: "body" name: "body" description: "Pet object that needs to be added to the store" required: true schema: $ref: "#/definitions/Pet" responses: "405": description: "Invalid input" security: - petstore_auth: - "write:pets" - "read:pets"
  58. ͜ͷ··Ͱ͸ಡΈʹ͍͘ 0QFO"1*पลπʔϧͷ4XBHHFS6*Λ࢖͏ͱ

  59. ಡΈ΍͘͢ͳΔʂ

  60. 0QFO"1* ❏ ར఺ ❏ "1*࢓༷Λڞ௨ͷϑΥʔϚοτͰ؆୯ʹهड़Ͱ͖Δ ❏ (*U౳Λ࢖ͬͯιʔείʔυͱಉ༷ʹ؅ཧ͢Δ͜ͱ͕Ͱ͖Δ ❏ पลπʔϧ͕๛෋ ❏

    ࢓༷Λهࡌ͢Δ͚ͩͰ.PDLαʔό͕࡞ΕΔ ❏ ΠϯλϥΫςΟϒͳ8FCυΩϡϝϯτΛ؆୯ʹ࡞੒͢Δ͜ͱ͕Ͱ͖Δ ❏ εΩʔϚۦಈ։ൃʹγφδʔ͕͋Δ ❏ εΩʔϚ "1*࢓༷ ͷఆٛ ❏ .PDLαʔόͷߏங
  61. 4BMBSJFTͰͷ0QFO"1*ΞʔΩςΫνϟ ❏ )5.-ͱͯ͠ϨϯμϦϯά ❏ .PDLαʔόͷߏங

  62. (FOFSBUF)5.- ❏ ਓ͕ݟ΍͍͢Α͏ʹ0QFO"1*ϑΥʔϚοτͷϑΝΠϧ͔Β)5.-Λੜ੒ ❏ 4XBHHFS6*΍3F%PDͱ͍ͬͨπʔϧΛ׆༻͢Δ͜ͱ͕ଟ͍ 4XBHHFS6* 3F%PD

  63. (JU)VCUSFOET ϖΠϯͰͷݟ΍͢͞΍NBSLEPXOΛಡΈࠐΊΔ͜ͱͳͲ͔Β3F%PDΛ࠾༻

  64. SFEPDDMJ ❏ υΩϡϝϯτ࡞੒ ❏ IUNMΛϨϯμϦϯάͯ͘͠ΕΔ $ npx redoc-cli bundle specification.yml

    -o .doc/index.html ❏ υΩϡϝϯταʔόىಈ ❏ "1*%PDVNFOU4FSWFSΛ্ཱͪ͛ͯ͘ΕΔ $ npx redoc-cli server specification.yml
  65. .PDL4FSWFS ❏ 1SJTN ❏ 0QFO"1*ϑΝΠϧΛݩʹϑϩϯτΤϯυ͔Β0QFO"1*Ͱఆٛͨ͠ϞοΫαʔό ΛͨͯΔ͜ͱ͕Ͱ͖Δ ❏ 0QFO"1*ϑΝΠϧΛهड़ͯ͠EPDLFSDPNQPTFZBNMΛ࡞੒ ❏ EPDLFSDPNQPTFVQίϚϯυΛ࢖͏ͱ.PDLαʔό্ཱ͕͕ͪΔ

    version: '3' services: api-mock: image: stoplight/prism volumes: - .:/api command: > mock -h 0.0.0.0 /api/specification.yml ports: - 4010:4010
  66. ͜͜·Ͱ ❏ εΩʔϚۦಈ։ൃΛ׆༻͢ΔͱϑϩϯτΤϯυͱόοΫΤϯυͷ࣮૷Λฏߦͯ͢͢͠ ΊΔ͜ͱ͕Ͱ͖ɺ։ൃ޻਺ͷ࡟ݮͰ͖Δ ❏ εΩʔϚۦಈ։ൃ͸0QFO"1*΍ͦͷपลπʔϧΛ࢖͏͜ͱͰ0QFO"1*ϑΝΠϧΛ࡞੒ ͢Δ͚ͩͰऔΓೖΕΔ͜ͱ͕Ͱ͖·͢

  67. 4BMBSJFTͰͷ0QFO"1*ϑΝΠϧͷѻ͍͔ͨ ❏ ϑΝΠϧ෼ׂ ❏ 0QFO"1*ͷ࢓༷ࣗମʹ͸ϑΝΠϧ෼ׂͷ࢓༷͸ଘࡏ͠·ͤΜ ❏ ZBNMͷ࢓༷ʹଇΓϑΝΠϧ෼ׂΛ͍ͯ͠·͢ ❏ ෼཭ͨ͠ϑΝΠϧ͸ SFGͰࢀর

    0QFO"1*ϑΝΠϧ͸ංେԽ͕ͪ͠
  68. ෼ׂલͷঢ়ଶ paths: /pet/{petId}: get: description: "Returns a single pet" parameters:

    - name: "petId" in: "path" description: "ID of pet to return" type: "integer" responses: "200": description: "successful operation" schema: type: "object" properties: name: type: "string" "1*ͷ1BUI ϝιου ύϥϝʔλ Ϩεϙϯε TQFDJGJDBUJPOZBNM
  69. ෼ׂํ਑ paths: /pet/{petId}: get: description: "Returns a single pet" parameters:

    - name: "petId" in: "path" description: "ID of pet to return" type: "integer" responses: "200": description: "successful operation" schema: type: "object" properties: name: type: "string" TQFDJGJDBUJPOZBNM /api ├── specification.yml ├── models │ └── pet.yml └── paths └── getPet.yml
  70. VTFSNPEFMTQFUZBNM ❏ NPEFMT͸"1*ͷϨεϙϯε΍ϦΫΤετ ͷܕΛఆٛ͢ΔϑΝΠϧ͕ଘࡏ͢Δ title: Pet description: Petの情報 type: "object"

    properties: name: type: "string" QFUZBNM
  71. VTFSQBUITHFU1FUZBNM ❏ QBUITͷதʹ͸"1*͝ͱʹ෼཭͍ͯ͠·͢ ❏ SFGΛ͔ͭͬͯఆٛͨ͠NPEFMΛݺͼग़͠ description: "Returns a single pet"

    parameters: - name: "petId" in: "path" description: "ID of pet to return" type: "integer" responses: "200": description: "successful operation" schema: $ref: "../models/pet.yaml" HFU1FUZBNM
  72. TQFDJGJDBUJPOZBNM ❏ QBUITΛ"1*͝ͱʹݺͼग़͢ paths: /pet/{petId}: get: $ref: “./paths/getPet.yaml” TQFDJGJDBUJPOZBNM

  73. description: "Returns a single pet" parameters: - name: "petId" in:

    "path" description: "ID of pet to return" type: "integer" responses: "200": description: "successful operation" schema: $ref: "../models/pet.yaml" HFU1FUZBNM paths: /pet/{petId}: get: $ref: “./paths/getPet.yaml” TQFDJGJDBUJPOZBNM title: Pet description: Petの情報 type: "object" properties: name: type: "string" QFUZBNM
  74. όϦσʔγϣϯ ˞࢖༻ݴޠ͸5ZQF4DSJQUΛ૝ఆ͍ͯ͠·͢

  75. ͪ͜Β͸ίϯύΠϥʔʹ௨ΔͰ͠ΐ͏͔ const addNum = (a: number, b: number) => {

    console.log(a + b); } addNum('a', 2);
  76. ֎෦͔Βड͚औͬͨ஋Λ࣮ߦ͢Δ৔߹ const body = JSON.parse(request.body); const addNum = (a: number,

    b: number) => { console.log(a + b); } addNum(body.a, body.b); { "a": "string", "b":2 }
  77. 5ZQF(VBSEΛೖΕΔ͜ͱͰ๷͛Δ const body = JSON.parse(request.body); const addNum = (a: number,

    b: number) => { if (typeof a !== 'number' || typeof b !== 'number') { throw new Error('型違いの値を受け取りました'); } console.log(a + b); } addNum(body.a, body.b);
  78. Ҿ਺͕0CKFDUͷ৔߹ const body = JSON.parse(request.body); interface ISchoolNums { studentNum: number;

    teacherNum: number; } const addObj = (a: ISchoolNums) => { if (!('studentNum' in a) || typeof a.studentNum !== 'number' || !('teacherNum' in a) || typeof a.teacherNum !== 'number') { throw new Error('型違いの値を受け取りました'); } console.log(a.studentNum + a.teacherNum); } addObj(body);
  79. ཧ૝ܗͱͯ͠͸ interface ISchoolNums { studentNum: number; teacherNum: number; } const

    addObj = (a: ISchoolNums) => { if (typeof a !== 'ISchoolNums') { throw new Error('型違いの値を受け取りました'); } console.log(a.studentNum + a.teacherNum); }
  80. 5ZQF(VBSEΛJPUTΛ࢖ͬͯॻ͘ import * as t from 'io-ts' import { isLeft

    } from 'fp-ts/Either'; const SchoolNums = t.type({ studentNum: t.number, teacherNum: t.number }) type ISchoolNums = t.TypeOf<typeof SchoolNums>; const addObj = (a: ISchoolNums) => { const either = SchoolNums.decode(a) if (isLeft(either)) { throw new Error('型違いの値を受け取りま した'); } console.log(a.studentNum + a.teacherNum); } interface ISchoolNums { studentNum: number; teacherNum: number; } const addObj = (a: ISchoolNums) => { if (!('studentNum' in a) || typeof a.studentNum !== 'number' || !('teacherNum' in a) || typeof a.teacherNum !== 'number' ) { throw new Error('型違いの値を受け取りま した'); } console.log(a.studentNum + a.teacherNum); } 5ZQF4DSJQUPOMZ VTFJPUT
  81. ཧ૝ܗͱൺ΂ͯΈΔ const addObj = (a: ISchoolNums) => { const either

    = SchoolNums.decode(a) if (isLeft(either)) { throw new Error('型違いの値を受け取りま した'); } console.log(a.studentNum + a.teacherNum); } ཧ૝ܥ const addObj = (a: ISchoolNums) => { if (typeof a !== 'ISchoolNums') { throw new Error('型違いの値を受け取り ました'); } console.log(a.studentNum + a.teacherNum); } ཧ૝ܥ VTFJPUT
  82. JOUFSGBDF෦෼ import * as t from 'io-ts' import { isLeft

    } from 'fp-ts/Either'; const SchoolNums = t.type({ studentNum: t.number, teacherNum: t.number }) type ISchoolNums = t.TypeOf<typeof SchoolNums>; interface ISchoolNums { studentNum: number; teacherNum: number; } 5ZQF4DSJQUPOMZ VTFJPUT
  83. 5ZQF(VBSEΛJPUTΛ࢖ͬͯॻ͘ ❏ EFDPEFͷฦΓ஋͸&JUIFSܕͱ͍͏-FGUܕ͔3JHIUܕΛ࣋ͪ·͢ ❏ 3JHIUܕͷ৔߹͸ൺֱ͍ͨ͠ܕͱಉ͡Ͱ͋Δ͜ͱΛࣔ͢ ❏ -FGUܕͷ৔߹͸ൺֱ͍ͨ͠ܕͱҧ͏͜ͱΛࣔ͠·͢ export declare type

    Either<E, A> = Left<E> | Right<A>; export interface Left<E> { readonly _tag: 'Left'; readonly left: E; } export interface Right<A> { readonly _tag: 'Right'; readonly right: A; }
  84. 5ZQF(VBSEΛJPUTΛ࢖ͬͯॻ͘ const addObj = (a: ISchoolNums) => { const either

    = SchoolNums.decode(a) if (isLeft(either)) { throw new Error('型違いの値を受け取りま した'); } console.log(a.studentNum + a.teacherNum); } const addObj = (a: ISchoolNums) => { if (!('studentNum' in a) || typeof a.studentNum !== 'number' || !('teacherNum' in a) || typeof a.teacherNum !== 'number' ) { throw new Error('型違いの値を受け取りま した'); } console.log(a.studentNum + a.teacherNum); } 5ZQF4DSJQUPOMZ VTFJPUT
  85. Τϥʔϝοηʔδ ❏ JPUTSFQPSUFSTΛ࢖͏͜ͱͰΤϥʔϝοηʔδΛࣗಈతʹ࡞੒ const SchoolNums = t.type({ studentNum: t.number, teacherNum:

    t.number }) type ISchoolNums = t.TypeOf<typeof SchoolNums>; const addObj = (a: ISchoolNums) => { const either = SchoolNums.decode(a) if (isLeft(either)) { console.log(reporter.report(either)); return; } console.log(a.studentNum + a.teacherNum); }
  86. Τϥʔϩά ❏ SFQPSUΛ࢖͏͜ͱͰԿ͕ͲͷΑ͏ʹؒҧ͍ͬͯΔ͔؆୯ʹϝοηʔδΛ࡞੒Ͱ͖Δ ❏ ೔ຊޠ΁ͷม׵΍ϝοηʔδͷܗࣜΛΧελϚΠζ͢Δ͜ͱ΋Ͱ͖Δ Expecting number at studentNum but

    instead got: "30"
  87. JPUTͷར༻Օॴ ❏ JPUTΛ࢖ͬͨόϦσʔγϣϯ͸֎෦͔ΒσʔλΛड͚औΔ৔߹ʹ࢖༻ ❏ "1*͕ड͚औͬͨϦΫΤετ ❏ %#͔Βऔಘͨ͠஋ αʔϏε͸ϑϩϯτΤϯυͱόοΫΤϯυͳͲ͕ϝοηʔδΛૹΓ͋͏͜ͱͰ੒Γཱͬͯ ͍·͢ɻ ͦΕͧΕͷΞϓϦέʔγϣϯίʔυͷதͰ֎෦ͱͷ઀఺෦෼ΛόϦσʔγϣϯ͢Δ͜ͱͰ

    αʔϏεͷ඼࣭Λอͭ͜ͱ͕Ͱ͖·͢ɻ
  88. όοΫΤϯυύʔτ ·ͱΊ ❏ ։ൃϑϩʔ ❏ εΩʔϚۦಈ։ൃΛߦ͏͜ͱͰόοΫΤϯυɾϑϩϯτΤϯυ͕ฏߦͯ͠։ൃ͕ Ͱ͖Δ ❏ 0QFO"1*͸εΩʔϚۦಈ։ൃͱγφδʔ͕ߴ͍ͷͰ͓͢͢ΊͰ͢ ❏

    ඼࣭ ❏ ֎෦ͱͷ઀఺ͰόϦσʔγϣϯΛ͔ͬ͠Γͱߦ͏͜ͱͰαʔϏεͷ඼࣭͕อͯ· ͢ ❏ 5ZQF4DSJQUͰ5ZQF(VBSEॻ͘ͷେมͰ͕͢ɺJPUTΛ࢖͑͹ղܾͰ͖Δ
  89. お知らせ

  90. ຊબߟ͕։͍࢝ͯ͠·͢ʂ ೥݄຤࣌఺Ͱͷ৘ใ ❏ ΤϯδχΞίʔεʢ˞ಛఆͷϙδγϣϯ֬໿Ͱ഑ଐʣ ▪エンジニア ・サービス企画開発本部:新規サービスの開発に上流の企画段階から参画するエンジニア ・事業戦略本部:「EPEB」などの大規模プロダクトの開発を担当するエンジニア ▪データサイエンティスト ・テクノロジー本部:最新技術を活用しながら、データドリブンで新規事業開発を行うデータサイエンティスト ・事業戦略本部:主に「EPEB」に蓄積された個人・法人データを分析し事業に還元するデータサイエンティスト

    ▪*5企画 事業目標達成に向けた*5化の促進を行うために*5戦略の立案から企画・構想、プロジェクトマネジメン トを担当
  91. 5FDIϝσΟΞ ΈΜͳͷʮ͸ͨΒ͘ʯΛςοΫͰͭ͘Δ ࣾ಺ͷςΫϊϩδʔ׆༻ࣄྫ΍ࣾһΠϯλϏϡʔΛൃ৴ʂ *5ɾςΫϊϩδʔਓࡐͷͨΊͷࣾձਓίϛϡχςΟɻษڧ ձ৘ใ΍ɺΠϕϯτϨϙʔτΛൃ৴ʂ

  92. ΫϨδοτ *MMVTUSBUJPOCZ4UPSZTFU IUUQTTUPSZTFUDPN

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