OpenAPI x Rails x NextJS ã§IVRyãïŒããäœãçŽãã話
ããã«ã¡ã¯ãé»è©±èªåå¿çãµãŒãã¹IVRyã§ãšã³ãžãã¢ãããŠããå°ç¬ã§ãïŒ
å®ã¯å
æããŠãŒã¶ãŒããã«ã¯äŒãããªã圢ã§å€§å¹
ãªãäœãçŽãããè¡ã£ãŠãããŸããã
äœè«ã§ããããã®ããã°ãæžããŠããæã«ã¡ããã©ãã®ãã€ãŒããããºã£ãŠããã®ãèŠãããŸããã
ïŒæè¡çè² åµãŸã¿ãã®ã³ãŒããªããå šãŠæšãŠãŠãŒãããäœãçŽãã°å šéšç¶ºéºãªã³ãŒãã«ãªãã®ã§ã¯âŠïŒïŒïŒ pic.twitter.com/eg741g1Pdj
â ããé§å (@MinoDriven) June 27, 2022
éå»ã®ã³ãŒããäœãçŽããããã©ãäœãçŽããªããã¿ãããªããšã£ãŠãããããªãã ãªãšæ¹ããŠæããŸããç¬
ä»ååãã¯åæ°ãåºããŠäœãçŽã決æãããŠãéå»ã®ã³ãŒãã¯ã¬ããžããªåäœã§æšãŠãŠãæ°èŠã§APIã100æ¬åŒ±ã2-3ã¶æã»ã©ãããŠç²ã
ãšå®è£
ããŸããã
å®å
šãªäœãæ¿ãã ã£ãã®ã§ããªã¹ã¯ã®é«ãã®ãªãªãŒã¹ã§ããããç¡äºã«é害ãªãä¹ãè¶ããããšãã§ããŸããã
ä»åã¯ãäœãçŽãã®åæ©ãã倱æããªãããã«æ°ãã€ããããšãªã©ãããã°ã«ãŸãšããŠãããããšæããŸãã
ãããªãé£èºã®ããã«ãäžæåæ¢
IVRyã¯ãåããããªãããªæ§æã§äœã£ãããã§ã¯ãªããã©ã¡ãããšèšããšãããã¿ã€ããæçã§äœãããšãç®çãšããæ¹åã®èç©ã«ãã£ãŠä»ãŸã§ã¢ããããŒããããŠããŸããã
äžèšã®ããæ¹ã¯ãµãŒãã¹ãç«ã¡äžããæã«éåžžã«å¹çãè¯ããäŒç€Ÿèšç«åœåã¯ãIVRy以å€ã«ãããŸããŸãªãµãŒãã¹ãå®éšããããšãã§ããŸããã
ãã IVRyã¯æ³å以äžã®æ¥æé·ãéããè³éé¢ã§ãïŒååã®èª¿éãæ±ºãŸãããšã³ãžãã¢ã¡ã³ããŒãå¢ããŠããŸããã
ãã®ãŸãŸããŒã ã§éçºããŠããåºç€ãšããŠã¯è²§åŒ±ã ãšå€æããæãåã£ãŠãã®ã¿ã€ãã³ã°ã§éå»ã®ã³ãŒããæšãŠãäºã«ããŸããã
å ·äœçã«ã©ãäœãæ¿ããã®ã
ä»åäœãçŽãã®å¯Ÿè±¡ã«ãªã£ãã®ã¯ãIVRy ã®webããŒãžã§ããé»è©±åŽã®ããžãã¯ã¯å¯Ÿè±¡å€ã§ãããèšå®ç»é¢ãLPãèšäºãªã©å šãŠããã®å¯Ÿè±¡ã§ãã
以åãŸã§ã®IVRy ã¯Ruby on Rails ã®ãã¬ãŒã ã¯ãŒã¯ã®äžã§ããã¯ãšã³ããšããã³ããšã³ããäž¡æ¹ãåãããŠããŸããã
ããããããã¯ãšã³ãã¯Ruby on Rails ã®APIã¢ãŒãã§REST APIã ããæäŸããããã³ããšã³ãã¯ãã®APIãå©çšããŠèªç±ã«èšèšã§ããããã«ãããã¯ãšã³ããšããã³ããšã³ãã®åãé¢ããè¡ããŸããã

ããã³ããšã³ãã¯NextJS + TypeScript ã®æ§æã§äœãçŽãäºã«ããŸããã
ããã¯ãšã³ãã¯åãRuby on Railsã䜿ã£ãŠããŸãããã¬ããžããªãæ°èŠäœæãã0ããã³ãŒããæžãäºã«ããŸããã
â»SST 㯠Server Side Templating ã®ç¥ã§ã
ãã£ãšè¯ãèšèšã¯ååšããªãã®ãïŒ
æè¿ãäŸãã°GraphQLãGoèšèªãªã©ã䜿ã£ãæ§æãè¯ãèŠãããããã«ãªããŸãããããããååã«ã¯ä»åŸãåžžã«ç®ãåããŠãããããšæã£ãŠããŸãã
äžæ¹ã§ããã³ãã£ãŒäŒæ¥ã«ãšã£ãŠæ°èŠéçºãæ¢ãŸãããšã¯å€§ããªæå€±ã§ãã
ã§ããã ãæ©ã¿ãæ¢ããäºãªãã倧ããªçºå±ãã§ããèšèšãæãæé©ãªèšèšã ãšèããæã«ãRuby on Rails ã§ã®å®è£
ã«ã€ããŠã¯æ¢ã«ç¥èŠãå€ãã£ãããšããREST APIã®å Žåã«ããã³ããšããã¯ãšã³ãå
±ã«èŠéããè¯ãã£ããããä»ã®IVRyã«ãšã£ãŠã¯æè¯ã®èšèšã ãšå€æããŸããã
API仿§æžã絶察ïŒãæ ä¿ããããã«
ãããããéçºæã«æ°ãã€ããŠããããšãæžããŠãããŸãã
ä»åAPI仿§æžããã¹ã¿ãŒãšããç¶æ
ãäœãããšã«ãã ãããŸãããæ¥µè«ã仿§æžããããã°ããã¯ãšããã³ãã¯äŒè©±ããªããŠãè¯ãç¶æ
ãç®æããŸããããã ããããå®çŸããããã«ã¯ä»æ§æžãšã³ãŒããäžèŽããŠããããšãæ
ä¿ããå¿
èŠããããŸããä»åãããã¯ãšã³ãããŒã ã§æ
ä¿ããããã«å·¥å€«ããããšãæžããŠãããŸãã
Swagger(Open API) ã䜿ã
ãŸããAPI仿§æžã«ã¯å®çªã®Swaggerã䜿ããŸããã

Swaggerã䜿ããšããã³ããšã³ãã¯ã³ãŒãã®èªåçææ©èœã䜿ãããããå¹çããããã€ãã¹ãå°ãªãå®è£
ããããšããŸãã
ãã ãã仿§æžã®éèŠåºŠã¯ããã«äžããäºã«ãªããŸããã³ãŒããšã¯ç°ãªã仿§æžãæžããŠãããšãèªåçæãããããã³ãã®å®è£
ãäœãçŽãã«ãªã£ãŠããŸããŸãã
RSpec ã®ãã¹ããSwagger ã®ä»æ§æžã䜿ã£ãŠè¡ã
ããã¯ãšã³ãã®ã³ãŒããšä»æ§æžã®æ ä¿ã¯ãRSpecã«ãã£ãŠæ ä¿ããäºã«ããŸããã
å ·äœçã«ã¯
response ã仿§æžãšéãå Žåã¯ãã¹ãã§èœã¡ãããã«
request ã®ãã©ã¡ãŒã¿ã仿§æžãšéãå Žåã¯ãã¹ãã§èœã¡ãããã«
ãã®äºã€ãå®çŸããããã«committee-rails ãšããgem ã䜿ããŸããã
å ·äœçãªã©ã€ãã©ãªãæžãæ¹ã®ã³ããªã©ã¯åœããã°ã§ã¯å²æããŸããããã¡ãã®Offersããã®ããã°ã«è©³ããæžãããŠããŸããã
2022/04/11 ã«ãã®ããã°ãåºãæã«ãåããã»ãŒåãæ¹éã§éçºãé²ããŠããæäžã ã£ãã®ã§ããã®ããã°ãèŠãŠééã£ãŠãªãã£ããã ãªãšå®å¿ãããŠããã ããŸãããç¬
ç¹ã«ããAPI å®çŸ©ããŠããäžã§æäœéå®ãã¹ãã«ãŒã«ãã«æžãããŠãã
å¿ é ããããã£ã«ã¯ required ã¯å¿ ãã€ãã
additionalProperties: false ãã€ãã
ãã®äºã€ã¯ãã¹ããèœãšãäžã§ãšãŠã倧äºãªãã©ã¡ãŒã¿ã§ãã
required ãç¡ããšããã©ã¡ãŒã¿ãã¬ã¹ãã³ã¹ã®äžè¶³ã§èœã¡ãªããªããŸãããadditionalProperties: falseããªããšãéã«ãã©ã¡ãŒã¿ãã¬ã¹ãã³ã¹ã®éå€ã§èœã¡ãªããªããŸãã
åãã¯ãåºæ¬çã«å
šãŠã«required ãã€ããŠãä»»æã®ãã®ã¯ãnullable: true ã«ããæ¹éã§ä»æ§æžãæžããŸããã
å€§èŠæš¡ãªãªãªãŒã¹ã§å€±æããªãããã«æ°ãã€ããäº
ãã€ã³ãâ ïŒå®ç§ãªåŸ©å ã«ã¯ãã ãããªã
IVRyã®æ©èœã¬ãã«ã§ã®ãã°ã¬ã¯èµ·ããªãããã«ãã€ã€ã现ãããã¶ã€ã³ã®éãããUI/UXã®åŸ®åŠãªæåã®å€æŽãªã©ã®åŸ©å ã¯ç®æããŸããã§ãããããã³ãããŒã ã«ã¯æ§IVRyãèžè¥²ãã€ã€ãæ°ãããã¬ãŒã ã¯ãŒã¯ã§äœããããããã«äœã£ãŠããããŸããã现ããå·®åã®ãã§ãã¯ãªã©ãéçºæã«è¡ããªãããšã§å¹ççã«éçºã§ããããšã¯è¯ãã£ãããšããªãšæã£ãŠããŸãã
ãã®çµæãã«ãŒã«ã®åå²ç·šéãªã©ãUI/UXãæ¹åããŠãããããããªã£ãã±ãŒã¹ããããå¹çåãã¯ãããäžã«æ¹åç¹ãå€ãã¿ãããå©çã倧ããã£ãã§ãã

ãã€ã³ãâ¡ïŒæ°èŠæ©èœã¯å ¥ããªã
æ°ããæ§æã«ããã€ãã§ã«ãããããã£ãæ°èŠæ©èœãäžç·ã«å
¥ãã¡ãããã£ãŠããæ°æã¡ã¯ãã¡ãããã£ãã®ã§ãããä»åã¯ãããŸã§ãIVRyã§ã§ããããšã®åçŸãã³ã³ã»ããã«å®è£
ãããŸããã
ãã®ãããã§ãQAãšããŠã¯æ§ç°å¢ãšæ¯èŒããŠãã°ã¬ããªãã確èªããããšããããããããããŒãã«ãªããŸãã
ä»åããã§æ¬²åŒµããªãã£ãããšã¯ããã®å€§ããªãªãªãŒã¹ã§å€±æããªãã£ã倧ããªèŠå ã ãšæããŸãã

è¥å¹²ã®ãã¶ã€ã³å€åã¯ããã倧ããã¯å€ããŠãªã
ãã€ã³ãâ¢ïŒDBã¯èšèšãçŽããªã
ãªãã¡ã¯ã¿ãªã³ã°ãããšDBã®èšèšããèŠçŽããããªããã®ã§ãããDBã®èšèšã¯å€ãããå šãåãDBã䜿ãäºã«ããŸããããã®ã¡ãªããã¯å€§ããäºã€ãããŸãã
ãªãªãŒã¹ã®ã¹ã³ãŒããå°ãããªã
æ§ç°å¢ãšæ°ç°å¢ãå šãåãããŒã¿ã§èŠæ¯ã¹ãããšãã§ãã
ç¹ã«åŸè ã®ã¡ãªããã¯å€§ãããé©åœãªãµããã¡ã€ã³ãåã£ãŠæ°ç°å¢ãdeployããã ãã§ãå šãåãããŒã¿ã䜿ã£ãŠæ§ããŒãžãšã®æ¯èŒæ€èšŒããããšãã§ããŸããã

ããã®ããŒãžæ°ç°å¢ã§éããã©ãæ§ç°å¢ã§ã¯ã©ããªãã ã£ãïŒãã¿ãããªããšã¯å®¹æã«èª¿ã¹ãããšãã§ããŸãã
ã³ãŒãã®å·®åã ãã«æ³šåã§ããããšãããªãªãŒã¹ãæåãã倧ããªèŠå ã ãšæããŸãã
ãã€ã³ãâ£ïŒãã¹ãã¯åºæ¬çã«å šéšæžã
å
šAPIã®ãªã¯ãšã¹ãã¯ãã¡ããã®ããšãvalidation ãã¢ãã«ã¡ãœãããªã©ãåºæ¬çã«å
šãŠã®ã¡ãœããã®RSpecãæžããŸããã
ãã°ã¬ã®ãã§ãã¯ãç°¡åã«ã§ããŠãæ°èŠéçºã®æã«æ©èœã®æ
ä¿ãä¿èšŒã§ããã®ã§ããã¹ãã¯å¿
é ã§ããããã¹ãã¯ä»åŸããã£ãšæžããŠãããŸãã
ãã€ã³ãâ€ïŒå®¹æãªåãæ»ã
ä»åã®ãªãªãŒã¹ã¯DBãå ±éã«ãããããURLã®åãå ãå€ããã ãã®ãªãªãŒã¹ã§ããã

ãã®ããããªãªãŒã¹ã«å€±æãããšããŠãåãå
ãåºã«æ»ãã ãã§DBã®æäœãå¿
èŠããªãã£ãããã倧ããªãªãªãŒã¹ã®å²ã«ã¯äœãªã¹ã¯ã§æããããšã倧ããã£ãã§ãã
(çµæçã«åãæ»ãã¯çºçããŸããã§ããã)
æåã®è£éµã¯CSããŒã ãšã®è¯å¥œãªé¢ä¿æ§
ä»åãæ°ã¶æã®éæ°èŠéçºãæ¢ããäºã«ãªããŸããããã®éãåœç¶CSããŒã ã®æ¹ã«ã¯ã客æ§ããã®èŠæãããããšããããŸããã
ä»åæ¬åœã«è¯ãã£ããªãšæã£ãã®ããCSããŒã ãšãšã³ãžãã¢ããŒã ã®é¢ä¿æ§ãéåžžã«è¯å¥œãªã®ã§ããäºãã«äºæ ã話ãåããªããå šäœæé©ãªæ¹åã«æã£ãŠããããšãã§ããŸããã
ãªãªãŒã¹ã®æã«ã¯ãäžãäžé害ãèµ·ãããšãã®ããã«ãCSããŒã ãæ·±å€ãªãªãŒã¹ã«ç«ã¡äŒã£ãŠãããŸããã

ã¡ãªã¿ã«ãªãã£ã¹ã¯âãã400ã¡ã®ãªãã£ã¹ã«ç§»è»¢ããã®ã§æ¬¡åã¯ããå°ãæ ããåçãèŒããŸããç¬

å è£ ããããåŸã®ä»äžãããæ¥œãã¿ã§ã
CSããŒã ã®çæ§ã«ã¯ãã€ãè¿·æãããããããããªãã®ã§ããã®é¢ä¿æ§ããã£ãšç¶ãããã«ãæ¯æ¥æè¬ãäŒããããªãšæã£ãŠããŸããç¬
ãªãªãŒã¹åœæ¥ã¯å šå¡åæ
ããã¹ãããšã¯å šãŠãã£ããããå人ã«ãé¡ãããŠç¥ç€Ÿã«ãã£ãŠããããåæããŠããããŸããã

ããããŠããã®å€§ãããªãªãŒã¹ã¯ç¡äºæåããããšãã§ããŸããã
IVRyã§ã¯ããããæåãæ ¹ä»ãã€ã€ãããæè¿ã¯ãé¡ãããªããŠãèªäž»çã«çãããç¥ç€Ÿã«åæããããã«ãªã£ãŠããŠããŸããç¬
äœãçŽã广ã¯çµ¶å€§
éå»ã«äœã£ããã®ãäœãçŽããããã£ãšäœ¿ãç¶ããŠããŸããšèšãã®ã¯å²ãšããããã ãšããããŸãã
ä»ååããåæ°ãåºããŠäœãçŽã決æããã3ã¶æåŒ±ã®éæ°æ©èœéçºãã¹ããããããŸããããäºæ³éããã®ã¡ãªããã¯å€§ãããã®ã§ããã
ãããã¯ã飿ºã«ããæ¡åŒµæ§ã®åäž
ãµãŒããŒãAPIåãããããšãšãã¡ã³ããã³ã¹ãããŠãã仿§æžãã§ããããšã«ãããæ¡åŒµæ§ã¯é¥ãã«å€§ãããªããŸãããä»åŸã瀟å å€ã®æ§ã ãªãµãŒãã¹ãšã®é£æºãç©æ¥µçã«åãçµãã§ããããšæã£ãŠãããŸãã

瀟å ã§ã¯æ¢ã«IVRy Media ãšããå¥ã§äœã£ãŠããåãåãããã©ãŒã æ©èœãšã®é£æºãããŒã³ããããŸããã

æ©èœã®è©³çްã¯ãªãªãŒã¹ããŒãã«èšèŒãããŠããŸã
ã¢ãžãªãã£ã®åäž
äœãçŽããããŒã³ããããŠããã以åãããå®å®çãã€å¹ççã«æ°èŠæ©èœã®éçºãè¡ãããšãã§ããŠããŸãã
äŸãã°ã6/23ã«ããŒã³ããããé³å£°åæã®çš®é¡ãéžæã§ããæ©èœãã¯åœ±é¿ç¯å²ã倧ããæ©èœã ã£ãã®ã§ããããã¹ãã«ãã£ãŠãã°ã¬ãèµ·ããŠãªãããšãæ
ä¿ã§ããã®ã§ãå¹ççãã€äžå
·åãåºãããšãªããªãªãŒã¹ããããšãã§ããŸããã

ãã§ã«äœãçŽãæéãå·»ãè¿ããããªããŒã¹ã§æ°æ©èœãéçºã§ããŠããŸãã
ç¥èŠã®ãªã»ãã
ãšã³ãžãã¢ã¡ã³ããŒãå¢ããææã§ããã£ãã®ã§ãéå»ã®ã³ãŒããæšãŠãŠäœãçŽããããšã«ãã£ãŠã¡ã³ããŒå
šå¡ãIVRyã«è©³ããç¶æ
ãäœãããšãã§ããŸããã
äœãçŽãã®ã¿ã€ãã³ã°ãšããŠä»åæãé©åãªã¿ã€ãã³ã°ã ã£ããªãšæã£ãŠããŸãã
IVRyã§äžç·ã«éçºãããšã³ãžãã¢ããåéããŠãŸã
ä»IVRy ã¯ãšã³ãžãã¢ãå¢ãã400ã¡è¶
ã®ãªãã£ã¹ãžã®ç§»è»¢ãäºå®ããŠãŸãã
æ¬åœãä»ãã³ãã£ãŒäŒæ¥ã®äžçªé¢çœãææãªããããªãããšæã£ãŠãŸãã
èå³ããæ¹ã¯æ¯éãå¿åããã«ãžã¥ã¢ã«é¢è«ãªã©ãåŸ
ã¡ããŠãããŸãïŒ