Dylanã¯ãå°ããªãŠã§ããµã€ããã巚倧ãªåæ£ã·ã¹ãã ãŸã§ã人çã®éã«ããŸããŸãªãããžã§ã¯ãã«åå ããã·ã¹ãã ã¢ãŒããã¯ãããã³éçºè ã§ãã 20幎ã®æŽå²ãæã€ã¬ã¬ã·ãŒããææ°ã®éçºãŸã§ã çŸåšã Spotlightã®ã¢ãŒããã¯ããšããŠåããŠãããä»æ¥ã®åæ£ã·ã¹ãã ã®è€éãªèª²é¡ã«åãçµãã§ããŸãã é©åã§çŸããå¹ççãªHTTP APIãäœæããããšã¯åœŒã®ä»äºã®äžéšã§ããã圌ã¯ãããã«ã€ããŠæ¬åœã«å€ãã®ããšãç¥ã£ãŠããŸãã
Dylanã¯ã 2017幎ã®DotNext Moscowã«ã³ãã¡ã¬ã³ã¹ã§ã©ã€ãã§äŒãããšãã§ããŸããDylanã¯ãæ°ããã¬ããŒãã人çãèªç±ãAPInessã®è¿œæ±ïŒå¹žããªã³ãŒãã®ç§å¯ããåãåããŸã ã 10æ31æ¥ãŸã§ãã±ãããããããäŸ¡æ Œã§è³Œå ¥ã§ããããšããç¥ããããŸãã
ãã®èšäºãããã¹ããã³ãŒãã§èªãïŒããã£ãšèªãããã¿ã³â©ãã¯ãªãã¯ããïŒããå®å šãªãããªã¬ããŒããèŠãããšãã§ããŸãã ç解ã«å¿ èŠãªãã¹ãŠã®ç»åãã¹ã©ã€ããå³ã¯ããããªãšããã¹ããã³ãŒãã®äž¡æ¹ã«ååšãããããäœã倱ãããŸããã
èšäºãžã®ã³ã¡ã³ãã¯å€§æè¿ã§ãããéåžžã«éèŠã§ããDotNextMoscow 2017㧠Dylanã«çŽæ¥æé«ã®è³ªåãããããã«ããŸãã
ä»æ¥ã¯ãçŸå®äžçã®RESTã€ããªãã®ãŒãšãã€ããŒã¡ãã£ã¢ã®å®çšçãªå ·äœåã«ã€ããŠã話ããŸãã
ããããæåã«ãç§ã«ã€ããŠå°ãã
ç§ã®ååã¯ãã£ã©ã³ã»ããŒãã£ãŒã§ãã ã¬ããŒãã«é¢ãã質åãããæè¯ã®æ¹æ³ã¯ãtwitterïŒ@dylanbeattieïŒã§ç§ãèŠã€ããããšã§ãã VKããŒãžã¯æã£ãŠããŸããããã·ã¢èªã¯è©±ããŸããããã®ããããã®ãœãŒã·ã£ã«ãããã¯ãŒã¯ã«ã¯åéãããŸããã
é·ãéãç§ã¯ãŠã§ããµã€ããäœæããŠããŸããã World Wide Webã1æ³ã«ãªã£ã1992幎ã«æåã®WebããŒãžãäœæããŸããã ããã«ãWebã¢ããªã±ãŒã·ã§ã³ãéçºããŠããŸãã
çŸåšãç§ã¯ãã³ãã³ã®Spotlightã®ã·ã¹ãã ã¢ãŒããã¯ãã§ãããæ ç»æ¥çã®ããŸããŸãªãããžã§ã¯ãã«åãçµãã§ããŸã-éåžžã«èå³æ·±ãæ¹åã§ãã
ç§ã®ãŠã§ããµã€ãïŒ dylanbeattie.net ããã§ããœãããŠã§ã¢ã¢ãŒããã¯ãã£ãRESTãããã³ãã®ä»ã®é¡äŒŒã®ãã®ã«é¢ããã¡ã¢ãå ¬éããŸãã ãŸãããã¹ãŠã®ã¹ã©ã€ãã®ã³ãŒããGitHubã«ããããšãèšåããããšæããŸãïŒ github.com/dylanbeattie/dotnext/ ã ããããããŠã³ããŒãããŠãèªåã§ãã¹ãããããšãã§ããŸãã
ããããRESTã«ã€ããŠè©±ããŸãããã
RESTã¯ããªãããç¥ãããæŠå¿µã§ãã å€ãã®äººã圌女ã®ããšãèããŠãããå€ãã®äººã圌女ãšäžç·ã«åããŠããŸãã ãã ããRESTãšã¯äœãããã®æŠå¿µãéèŠã§ããçç±ãããã³RESTã䜿çšããŠåé¡ã解決ããæ¹æ³ã«ã€ããŠã¯ãäŸç¶ãšããŠå€ãã®æ··ä¹±ããããŸãã ä»æ¥ã¯ããããã®è³ªåã®ããã€ãã«å¯ŸããçããèŠãŠãããŸãã ãããããŸãæåã«ãã©ã®ã·ã¹ãã ãRESTã«å¯Ÿå¿ããã®ããæ確ã«èããããšããŸãã ãããã£ãŠãç§ãã¡ã¯æåããå§ããŸã-ãœãŒã¹ã«ç®ãåããŸãã

ããããã€ã»ãã£ãŒã«ãã£ã³ã°ã§ãã ãã€ã¯RESTãçºæãããããäœã§ãããã決å®ããŸããã ãã¹ãŠãã©ã®ããã«æ©èœãããã説æãããœãããŠã§ã¢ããã³ã³ã³ãã¥ãŒã¿ãŒæè¡ã«é¢ããè³æãå€æ°ãããŸãã 䜿çšãããåèªã¯ã人ã«ãã£ãŠæå³ãç°ãªããŸãã ããããRESTã«ã¯éåžžã«æ確ãªå®çŸ©ããããããã«ã€ããŠã¯æåã«èª¬æããŸãã
ãã€ã¯çŸåšãã¢ããã®ã·ãã¢ãã§ããŒã§ãã ãã以åã¯ãApacheã«åãçµãã§ããŸããã å®éã圌ã¯Apache WebãµãŒããŒãããžã§ã¯ãã®åµèšè ã®1人ã§ãããWorld Wide Webããªã³ã¯ããåºæ¬ãããã³ã«ã§ããHTTPã®äœæè ã®1人ã§ããã 2000幎ãRoyã¯è«æããããã¯ãŒã¯ãœãããŠã§ã¢ã¢ãŒããã¯ãã£ã®ã¢ãŒããã¯ãã£ã¹ã¿ã€ã«ãšèšèšããçºè¡šããŸããã ãã®äœåã§ã¯ãWebäžã®ã¹ã±ãŒã©ãã«ãªãœãããŠã§ã¢ã®ã¢ãŒããã¯ãã£ã¹ã¿ã€ã«ã«ã€ããŠèª¬æããŠããŸãã
ããã¯ç解ãããã¹ãæåã®ç¬éã§ãã RESTã¯ãã¬ãŒã ã¯ãŒã¯ã§ãã©ã€ãã©ãªã§ããããŸããã åã«ããŠã³ããŒããŸãã¯ã€ã³ã¹ããŒã«ããããšã¯ã§ããŸããã RESTã¯ãã¢ããªã±ãŒã·ã§ã³ã§çºçããåé¡ã®è§£æ±ºæ¹æ³ã«é¢ããäžé£ã®ã«ãŒã«ãå¶éãæšå¥šäºé ã§ãã
ãã€ã®è«æã¯éåžžã«äººæ°ããããŸãã ããªããæ ¹ã«å°éããããšã«èå³ããããªãã圌ãã¯äžèŠã®äŸ¡å€ããããŸãã 圌ã®äœåã§ã¯ãããã€ãã®æ Œèšã匷調ããããšæããŸãã
ãŸããååãåãåã£ãé¢é£ããäžé£ã®ã¢ãŒããã¯ãã£äžã®å¶éããã¢ãŒããã¯ãã£ã¹ã¿ã€ã«ã«ãªããŸãã 圌ã®æèŠã§ã¯ããã®åé¡ã¯ïŒå»ºèšã®æèã§ïŒå»ºç¯ã®åœ±é¿ãåãã建ç¯æ§åŒã«ã€ããŠãå«ããå€ãã®ããšãèããŸããã 建ç©ã¯ãèšèšã§ã¯ãªããèšèšã§ã¯ãªããã¹ã¿ã€ã«ã§ãã€ãŸãåã ã®æ©èœãšå¶éã®ã»ããã§äºãã«åºå¥ãããŸãã ãããŠãRESTã¯åœŒã«äŒŒãŠããŸãã ããã¯ãã·ã¹ãã ã«é©çšã§ãããã³ãã¬ãŒãã®ã»ããã§ãã
ãŸãããœãããŠã§ã¢éçºã«ãããRESTãäœå幎ãååšããŠããããšãéåžžã«éèŠã ãšèããŠããŸãã ãã¹ãŠã®çŽ°éšããœãããŠã§ã¢ã®é·å¯¿ãšç¬ç«ããé²åãä¿èšŒããŸã ã RESTã¯ãæ°å¹ŽããŸãã¯æ°å幎ã«ããã£ãŠæ©èœããã·ã¹ãã ãäœæããããã«èšèšãããŠããŸãã æ¥æãŸã§ã«è³é調éãçµäºãããšäºæ³ãããå Žåããã®æŠå¿µã®äžã§æ瀺ãããå¶éã®å€ãã¯çæçãªæå¹æ§ãšæ£å察ã§ãããããããããRESTæºæ ã®ã·ã¹ãã ãäœæãã¹ãã§ã¯ãããŸããã
äœæ¥äžã®ãããžã§ã¯ãã§ã¯ãåé¡ã解決ããæ¹æ³ã2ã€ä»¥äžããããšããããããŸãã ãããŠãRESTã«è³ããŸã§ã®éã®ãã¯ãã°ãã°é·ãããããŸãã ãã®ãã¹ã§ã¯ãããªããšããªãã®äŒç€Ÿã«ãšã£ãŠåé¡ã«ãªããªããããããªãå€ãã®ããšãèããå¿ èŠããããŸãã ãšãŠã泚æããŠãã ããã ãŸãã«ããªããéæããããšããŠããããšãèããŠãã ããã é·å¹Žã«ããã£ãŠæ©èœããªããã°ãªããªãã·ã¹ãã ã§äœæ¥ããã®ã«åå幞éã§ããå Žåããã®èšäºã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãç§ãããªãã«åœ¹ç«ã€ããšãé¡ãå€ãã®ã¢ã€ãã¢ãèŠã€ããã§ãããã
ãããã¿ã€ããäœæããäœããæ©èœãããã©ããã確èªããããã«å€ãã®å®éšãè¡ã£ãŠããå Žåãç¶æ³ã¯ãããŸãã§ãã RESTã¯å®³ãåãŒããŸããããèŠä»¶ã«ãã£ãŠã¯é床ãäœäžããå ŽåããããŸãã
RESTå®çŸ©
Roy Fieldingã¯ãRESTã®å®çŸ©ãææ¡ããŸãããããã¯ã調æŽãããã¢ãŒããã¯ãã£äžã®å¶çŽã®ã»ããã§ãã
ã¯ã©ã€ã¢ã³ããµãŒããŒ

ãŸã第äžã«ã圌ã«ãããšããœãããŠã§ã¢ã·ã¹ãã ã¯ã¯ã©ã€ã¢ã³ããšãµãŒããŒã§åäœããããã«æ§ç¯ããå¿ èŠããããŸãã ããã誰ã«ãé©ããªãããšãé¡ã£ãŠããŸãã ç§ãã¡ã®ã»ãšãã©ã¯ããŠã§ããµã€ããã¡ãŒã«ã·ã¹ãã ãFTPãªã©ã®ã¯ã©ã€ã¢ã³ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ãæ¢ã«äœæããŠãããšæããŸãã ä»ã§ã¯éåžžã«äžè¬çã§ãã
詳现ã¯èª¬æããŸããã ãµãŒããŒã¯äœããã®æ¹æ³ã§ã¯ã©ã€ã¢ã³ãéã§åå²ãããããŒã¿ã¹ãã¬ãŒãžãåºæ¬æ©èœãããã³ã»ãã¥ãªãã£ãæäŸããŸãããããã¯äžå 管çãããã®ã§ãã
顧客ã®è¯ãç¹ã®1ã€ã¯ããããããã³ã³ãã¥ãŒã¿ãŒããæ¥ãŠããããšã§ãã ãããã£ãŠãå®è¡ããå¿ èŠãããèšç®ãããå Žåã¯ãããããå€æ°ã®é¡§å®¢ã«é åžã§ããŸãã ãããã£ãŠã顧客ã¯ããŒã¿åŠçããã¬ãŒã³ããŒã·ã§ã³ãããã³ãŠãŒã¶ãŒãšã®å¯Ÿè©±ãæäŸããŸãã
ãµãŒããŒã¯è€æ°ã®ã¯ã©ã€ã¢ã³ãã«ãµãŒãã¹ãæäŸããŸãã ãããŠãããã¯å€§ããªå©ç¹ã§ãã ãã¡ãããã·ã¹ãã ãæ£ããèšèšããã°ã1å°ã®ãµãŒããŒã䜿çšããŠäœå人ãã®ãŠãŒã¶ãŒã«ãµãŒãã¹ãæäŸã§ããŸãã

ç¶æ ãä¿åããªã
2çªç®ã®å¶éã¯ãç¶æ ã®ä¿åã®æåŠã§ãã ASP.NETãPHPãColdFusionããŸãã¯åŸæ¥ã®ASPã§ã¯ãã»ãã·ã§ã³ã®ã¢ã€ãã¢ãæãã€ããŸãã ã»ãã·ã§ã³CookieããããŸãã ãããããã®èãã¯ãã¯ãæ©èœããŸããã ASP.NETã®ãããªãã®ãããã1ã€ã®WebãµãŒããŒãèµ·åãããšãå°ãé ããªãå§ããŸããã ãã®åŸãå¥ã®WebãµãŒããŒãã€ã³ã¹ããŒã«ããŸãããããµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ãããã³ã«ããã®ã¯ã©ã€ã¢ã³ãå°çšã®ã¹ããŒã¹ãã¹ãã¬ãŒãžã«å²ãåœãŠãããããããã¹ãŠãæ©èœããªããªããŸããã ãã®ãããªãã®ïŒ

ãµãŒããŒã¯ãã®ç¶æ ãç¶æããŸããã åæã«ã次ã®äººãå ¥ã£ãŠæ¥ãŸããããã®äººã«ãäœããã®ç æ°ããããŸãã
ãµãŒããŒããã£ã±ãã«ãªããã¯ã©ã€ã¢ã³ãã®1ã€ãé¢è±ãããšã©ããªããŸããïŒ åœŒãæ»ããã©ããããããªãã®ã§ããã°ããã®éãã®ç¶æ ãç¶æããªããã°ãªããŸããã ããããã»ãã·ã§ã³ã®ã¿ã€ã ã¢ãŠãã¯ã©ãããã¹ãã§ããããïŒ 5åã10åã24æéïŒ å€æããã®ã¯éåžžã«å°é£ã§ãã ããããæ倧ã®åé¡ã¯ãããã«å€ãã®æ©èœãæäŸããå¥ã®ãµãŒããŒãèµ·åããã¯ã©ã€ã¢ã³ãã®1ã€ãå¥ã®ãµãŒããŒã«åãæ¿ããããšãããšãã»ãã·ã§ã³æ å ±ãå¥ã®å Žæã«ä¿åããããããæ¥ç¶ãçµäºããããšã§ãã
ãããã£ãŠãç¶æ ã®ä¿åãåé¿ããããšã§ããµãŒãã¹ãæäŸã§ããã¯ã©ã€ã¢ã³ãã®æ°ãšã·ã¹ãã ã®ã¹ã±ãŒãªã³ã°æ¹æ³ã«é¢ããæè»æ§ãé«ãŸããŸãã
ãã£ãã·ã³ã°
Royãå®çŸ©ãã3çªç®ã®å¶éã¯ãã£ãã·ã¥ã§ãã

ãµãŒããŒã«äœããã®ãªãœãŒã¹ããããšããŸãã ã¯ã©ã€ã¢ã³ããèŠæ±ããŸãã ã¯ã©ã€ã¢ã³ããåããªãœãŒã¹ãååºŠå¿ èŠãšããå Žåãå床èŠæ±ããå¿ èŠã¯ãããŸããã 圌ã¯ãã§ã«ããã«ãããã®ã䜿çšã§ããã¯ãã§ãã
ãµãŒããŒã§ã¿ã¹ã¯ãå®è¡ãããšããªãœãŒã¹ãç¡é§ã«ãªããŸãã ãããªãŸãã¯åçãåŠçããŠããå¯èœæ§ããããŸãã ãããŠããªãœãŒã¹ã«èŠåãã ãã®ãã®ãåå©çšããå¿ èŠããããŸãã ãããæåã§ãã æ»ã£ãŠããŠåãããŒã¿ãå床èŠæ±ãã人ãåããªãœãŒã¹ãååŸã§ããããã«ãåŠççµæãä¿åããå¿ èŠããããŸãã
éå±€åã·ã¹ãã
次ã®å¶éã¯ããã£ãã·ã¥ã®æŠå¿µã«çŽæ¥é¢é£ããŠããŸãã ããã¯ããã«ãã¬ãã«ã·ã¹ãã ã®èãæ¹ã§ãã ãã®ã¢ã€ãã¢ã®ç§ã®ãæ°ã«å ¥ãã®äŸã¯ãã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®ãã£ãã·ã¥ãããã·ã§ãã

ãã®å³ã®é¡§å®¢ã¯å·ŠåŽã«ãããŸãã ãããã¯ãã¹ããŒããã©ã³ïŒiPhoneãSamsungãAndroidïŒã®ããŸããŸãªãªãã·ã§ã³ã§ãããšæ³å®ããŸãã ãããã·ãµãŒããŒã¯ãã§ãŒã³ã®éäžã«ãããŸãã 倧èŠæš¡ãªéä¿¡äŒç€Ÿã«ãã£ãŠç®¡çãããŠãããšããŸãããã ãµãŒããŒã®ææè ãšããŠããããã·ã®å³åŽã«ãããµãŒããŒã®äœæ¥ã«å¯ŸããŠæéãæ¯æããŸãã çµå±ãã¯ã©ã€ã¢ã³ããããªã¯ãšã¹ããæ¥ããšããµãŒããŒã¯ããã€ãã®èšç®ãå®è¡ããŸãã ãããŠãããã¯ãéãããããŸã-é»æ°ãèšåã®æžäŸ¡ååŽè²»ãªã©ã
éä¿¡äŒç€Ÿãçµæã®ã³ããŒãä¿æããŠããå Žåã誰ãã次ã«æ å ±ãèŠæ±ãããšãã«ããããã·ã³ããŒãåãåããŸãã ãªã¯ãšã¹ãã®å®è¡ã«ãéããããå¿ èŠã¯ãããŸããã ãããã£ãŠããããã·ãã£ãã·ã³ã°ã®ã¢ã€ãã¢ã¯ä¿¡ããããªãã»ã©åªããŠããŸãããªããªããä»ã®äººãè¿œå æè³ãªãã§ãœãããŠã§ã¢ãé«éåããããã«æ¯æãããšãã§ããããã§ãã
ãã«ãã¬ãã«ã·ã¹ãã ã®ã¢ã€ãã¢ã®äžéšãšããŠãäžéã¬ãã«ãããã«è¿œå ã§ããŸãã å€å±€ã·ã¹ãã ã§ã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã¯ãªã¯ãšã¹ããã©ã®ã¬ãã«ãééããããæ°ã«ããŸããã

ãã®äŸã§ã¯ãã¯ã©ã€ã¢ã³ãã¯ãããã·ãµãŒããŒãšå¯Ÿè©±ããŸãã ãããã·ã¯ããµãŒããŒãšå¯Ÿè©±ãããšèããŠããŸãããå®éã«ã¯ãã»ãã¥ãªãã£ã¬ãã«ïŒãã¡ã€ã¢ãŠã©ãŒã«ãªã©ïŒã«èŠæ±ãéä¿¡ããŸãã 次ã«ã圌ã¯ãµãŒããŒãšéä¿¡ããŠãããšèããå®éã«ããŒããã©ã³ãµãŒã«ãªã¯ãšã¹ããéä¿¡ããŸãã
ããŒããã©ã³ãµãŒã¯ãµãŒããŒãšå¯Ÿè©±ãããšèããŠããŸãããå®éã«ã¯5å°ã®ãµãŒããŒã«ã€ããŠè©±ããŠããŸãã æ°ãããã®ããããã€ããå€ããã®ãéããããšãã§ããŸããããŒããã©ã³ãµãŒã®ãããã§ãããã¯ä»ã®ã¬ãã«ã«åœ±é¿ããŸããã
éå±€åã·ã¹ãã ã®æŠå¿µã«ãããã¢ããªã±ãŒã·ã§ã³ãèšç»ããéã®æè»æ§ãå€§å¹ ã«åäžããŸãã
åäžã®ã€ã³ã¿ãŒãã§ãŒã¹
ãªãœãŒã¹èå¥
HTTPããã³RESTãç»å Žããåã«ããµãŒããŒããæ å ±ãååŸããã«ã¯ãGopherãFTPãTelnetãªã©ãæ°åçš®é¡ã®ãããã³ã«ã®ãããããéžæããå¿ èŠããããŸããã ãããã¯ãã¹ãŠç°ãªãã·ã¹ãã ã§ãããããããããªã¢ãŒãæ å ±ããã³ãªã¢ãŒããµãŒãã¹ãšå¯Ÿè©±ããç¬èªã®æ¹æ³ãæ瀺ããŠããŸãã
HTTPãšRESTã¯ãããæšæºåããŸããã ãŸãããªãœãŒã¹ã®èå¥ãæšæºåãããŸãã-URLã衚瀺ãããŸããïŒèª°ããURLãæãã€ãããšæãã®ã¯é¢çœãã§ãïŒã ã¢ãã¬ã¹ã®äžéšã¯ãããã³ã«ïŒHTTPïŒã§å®çŸ©ãããããäžæ¹ã¯ãªãœãŒã¹ãžã®ãã¹ã3çªç®ã¯ããŒãã§ãã ãããã¯ãŒã¯èŠæ±ã«ã¢ã¯ã»ã¹ã§ããã€ã³ã¿ãŒãããäžã®ãã¹ãŠã®ãã®ã¯ããããã®URLã®ããããã䜿çšããŠèå¥ã§ããŸãã
æåºæäœ
è¡šçŸæäœãšã¯ãããŸããŸãªåœ¢åŒã®ããŒã¿ãèŠæ±ã§ããããšãæå³ããŸãã ããŒã¿ãå¿ èŠãªå Žåã¯ãCSVããŒãã«ãExcelãã¡ã€ã«ãããã¹ãããã¥ã¡ã³ããjpegãšããŠååŸã§ããŸãã ãããã¯ãã¹ãŠãããã€ãã®åºæ¬çãªçµæã®å®éã®è¡šçŸã§ãã
èªå·±èšè¿°ã¡ãã»ãŒãž
ãããäžã§äœãèµ·ãã£ãŠããã®ããç解ã§ããã¯ãã§ãã HTTPã«ã¯GETãPUTãPOSTãDELETEãªã¯ãšã¹ãããããŸãã ãããã¯èª¬æçãªãã®ã§ãïŒGETã¯ãäœããæã«å ¥ããããšããæå³ã®è±èªã®åèªã§ãã PUTã¯äœãã眮ãããšãDELETEã¯åé€ããããšãæå³ããŸãã ã€ã³ããªãžã§ã³ããªãããã°çšã®ããŒã«ã§ãããã¯ãŒã¯ãã©ãã£ãã¯ã調ã¹ãŠãå®éã«éä¿¡ããããªã¯ãšã¹ããææ¡ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®ç¶æ ã管çããã¡ã«ããºã ãšããŠã®ãã€ããŒã¡ãã£ã¢
ããã«ã€ããŠããã«è©³ãã説æããŸãã
ãšã³ã³ãŒãã®ãªã¯ãšã¹ã
ãã€ã確èªããæåŸã®å¶éã¯ããªã³ããã³ãã§é¡§å®¢ã«æäŸãããã³ãŒããäœæãããšããã¢ã€ãã¢ã§ãã ãµãŒããŒãã³ãŒããå«ãããŒã¿ãéä¿¡ã§ããå¿ èŠãããããšãæå³ããŸãã ã¯ã©ã€ã¢ã³ãã¯ãã®ã³ãŒããæœåºãããµãŒããŒããåæããŠãåŸã§èµ·åã§ããŸãã
ãããè¡ãAPIãèŠãããšããªãã Googleããã¥ã¡ã³ããªãã©ã€ã³ãGmailããã®ä»å€ãã®1ããŒãžã¢ããªã±ãŒã·ã§ã³ãªã©ãå€ãã®Webã¢ããªã±ãŒã·ã§ã³ãèŠãŠããŸããã åŸã§ã·ã¹ãã ã§èµ·åããããã«ãä»ã®èª°ãã®APIããå®è¡å¯èœã³ãŒããååŸãããšããèãã¯ãµããŒãããŠããŸããã ããããã¯ã©ã€ã¢ã³ãäžã§ãã®ãããªæäœãéå§ãããå¯èœæ§ãããããšãç¥ã£ãŠããããã§ãã
é»åã¡ãŒã«ã¯ã©ã€ã¢ã³ãã§ã¯ãªãæåã®Webãã©ãŠã¶ãäœæããããšãã«ãç§ã¯æ¥çã«æ¥ãŸããã ãã®åŸã誰ããJavaScriptãå®è¡ã§ãããšå€æããJavaScriptã§ã¡ãŒã«ã¯ã©ã€ã¢ã³ããäœæããŠã¯ã©ã€ã¢ã³ãã«éä¿¡ãããã©ãŠã¶ã§å®è¡ã§ããããã«ããŸããã
å¿ é ã®å¶é
éèŠãªããšã¯ããã€ã»ãã£ãŒã«ãã£ã³ã°ãççŽã«èšã£ãŠããããšã§ãïŒ6ã€ã®å¶éãããããã®ãã¡ã®1ã€ã ãããªãã·ã§ã³ã§ãã

説æããæ¹æ³ã§ã·ã¹ãã ãæ§ç¯ããŠåé¡ã解決ãããšãã·ã¹ãã ã¯RESTfulã«ãªããŸãã ããããç°ãªãæ¹æ³ã§è§£æ±ºãããšãã·ã¹ãã ã¯RESTfulã«ãªããŸããã ããã¯ã圌女ãè¯ããæªãããæå³ãããã®ã§ã¯ãããŸããã äžèšã®å®çŸ©ã¯ãã·ã¹ãã ã®å質ã«ã€ããŠã¯äœãèšåããŠããŸããã ãã ããå®çŸ©ã«ãã£ãŠRESTful APIãæ§æãããã®ã«ã€ããŠïŒå ã®ãœãŒã¹ã«åŸã£ãŠïŒåæããããšãéåžžã«éèŠã§ãã
ãããã®å¶éãå®éã®ç掻ããŸãã¯ã³ããã¯ããŒããŒã®ç掻ã§ã©ã®ããã«èŠããããèŠãŠã¿ãŸãããã RESTã«åŸã£ãŠãã¹ãŒããŒããŒããŒçšã®ãœãŒã·ã£ã«ãããã¯ãŒã¯ã³ãŒããèšè¿°ããŠã¿ãŸãããã 楜ããã§ãããã
å®éã®REST

ã³ããã¯ïŒããã³ã³ããã¯æ¬ã®æ ç»ïŒã®éåžžã«èå³æ·±ããã£ã©ã¯ã¿ãŒãæãããŠããŸãã 圌ãã®ããã«ãœãŒã·ã£ã«ãããã¯ãŒã¯ãäœæããŠã¿ãŸãããã ãã ããJavaScriptããã¹ãããããªãã®ãšåãããã«ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®éçºã§è¡ãè©°ãŸãããšã¯æã¿ãŸããã ããã§ã¯ãAPIãäœæããŠã¿ãŸãããã
ãšã³ããªãŒãã€ã³ãã¯æ¬¡ã®ãšããã§ãã
GET / HTTP/1.1
å¿çãšããŠã次ã®ãã®ãååŸããŸãã
200 OK Content-Type: application/json { "message": "Welcome to Herobook!" }
here / profilesãšãããšã³ããã€ã³ããäœæããŠã¿ãŸããããããã«ã¯2ã€ã®ã¡ãœããããããŸãã
GET /profiles HTTP/1.1
ãã®ã¡ãœããã¯ããœãŒã·ã£ã«ãããã¯ãŒã¯ã«åå ãããã¹ãŠã®ã¹ãŒããŒããŒããŒã®ãããã¡ã€ã«ããJavaScript-JSONã®é åãè¿ããŸãã
200 OK Content -Type: application/json [ { "username": "ironman", "name": "Tony Stark", } ]
çŸæç¹ã§ã¯ã»ãã¥ãªãã£ã«ã€ããŠå¿é ããŠããŸãããããã®åé¡ã¯äŒè©±ã®ç¯å²ãè¶ ããŠããŸãã
2çªç®ã®æ¹æ³ã¯POSTã§ãã /ãããã¡ã€ã«ã«POSTãéä¿¡ããããšã«ããããã€ããŒããJSONãšããŠæäŸããŸãã
POST /profiles HTTP/1.1 { "username" : "blackwidow" "name": " ", }
çãã¯ããããã¡ã€ã«ãšãã®ã¢ââãã¬ã¹ã®äœæãæåããããšã«é¢ããã¡ãã»ãŒãžã§ãã
201 Created Location: http://api.herobook.local/profiles/blackwidow { "username": "blackwidow", "name": " " }
ãµãŒãã¹ãšãã®APIã®èª¬æãã€ã³ã¿ãŒãããäžã®ã©ããã«æçš¿ããŠã誰ããã·ã¹ãã ã®äœ¿çšæ¹æ³ãç解ã§ããããã«ããŸãã

...ãããŠé±æ«ã¯äŒã¿ã
æææ¥ã«æ»ããšããµãŒãã¹ã«é¢ããæ å ±ããããã¯ãŒã¯å šäœã«åºãã£ãŠããããšãããããŸããã誰ããRedditã«èŒããŠTwitterã«åæçš¿ãã200äžäººã®ãŠãŒã¶ãŒãç²åŸããŸããã ããïŒ
GET /profiles HTTP/1.1 200 OK { "_links" : { ⊠}, "items" : { { "username":"ironman", "name":"Tony Stark" } { "username":"blackwidow", "name":" " }, { "username":"spidey", "name":"Peter Parker" }, { /* +2 million users! Wow! */ }, { "username":"ducky", "name":"Howard the Duck" } } ]
ãããŠãçªç¶é»è©±ã鳎ããŸãã é»è©±ãåããéä¿¡ã®å察åŽã§ãAPIããã£ãã«å šäœããããã¯ããŸããïŒããšèšããŸãã ãããŠãå¥ã®åŒã³åºãïŒãããªãã®ã°ãããAPIãããŒã¿ããŒã¹ããªãŒããŒããŒãããŠããŸããã
ããã§åé¡ã¯äœã§ããïŒ ã©ããã ãªãç§ãã¡å šå¡ãäžå¹žãªã®ã§ããïŒ ãªããªãããªã¯ãšã¹ãã«å¿ããŠ200äžä»¶ã®ã¬ã³ãŒããéä¿¡ããããã§ãã ãšã³ããã€ã³ãã¯1ã€ã ãã§ã-/ãããã¡ã€ã«ã APIã§ã§ããããšã¯ãããŒã¿ãååŸãŸãã¯å ¬éããããšã ãã§ãã ãããŠããããè¡ãããšãããšãæ¯å200äžä»¶ã®ã¬ã³ãŒããåãåããŸãã ãããã£ãŠã誰ããAPIã䜿çšããããšãããã³ã«ãã¡ã¬ãã€ãã®ããŒã¿ãåãåããŸãã ãããã¯ãŒã¯ããããŒã¿ããŒã¹ãããããããŠããŸãã ã·ã¹ãã å šäœã¯ã¹ã±ãŒãªã³ã°ããŸããã
ããã«ã€ããŠäœãã§ããŸããïŒ ãšã³ããã€ã³ããååŸããŠãåå²ããŠã¿ãŸãããã
GET /profiles<b>?page=1</b> HTTP/1.1 200 OK { "_links" : { ⊠}, "items" : [ { "username":"ironman", "name":"Tony Stark" } { "username":"spidey", "name":"Peter Parker" }, { "username":"blackwidow", "name": " " }, { "username":"cap", "name":"Steve Rogers" }, { "username":"storm", "name":"Ororo Munroe" } ] }
次ã«ãããŒãž2ããªã¯ãšã¹ãã§ããŸãã
GET /profiles<b>?page=2</b> HTTP/1.1 200 OK
次ã«3ããŒãžç®
GET /profiles<b>?page=3</b> HTTP/1.1 200 OK
ãªã©ãªã©ïŒ
GET /profiles?page=4 HTTP/1.1 200 OK
GET /profiles?page=5 HTTP/1.1 204 No Content
ããã¯éåžžã«ã·ã³ãã«ã§ãæ©èœããŸãã ç§ãã¡ã®ã»ãšãã©ããããè¡ãã·ã¹ãã ãäœæã§ãããšç¢ºä¿¡ããŠããŸãã ãã³ã³ãã³ããªãããååŸããå Žåããã¹ãŠã®ã·ã¹ãã ãããã¡ã€ã«ãããããšãæå³ããŸãã
ãã ããããã¯RESTã§ã¯ãããŸããã ãããŠãã®çç±ã¯ãAPIãã¢ããªã±ãŒã·ã§ã³ç¶æ ã®ãšã³ãžã³ãšããŠãã€ããŒã¡ãã£ã¢ã䜿çšããªãããã§ãã æåã®ããŒãžãååŸãããšãçè«çã«ã¯ããããããŒãž2ã3ã«ç§»åã§ããŸããããµãŒããŒã®å¿çã«ã¯ãã®å¯èœæ§ã瀺ããã®ã¯äœããããŸããã
ããã§äœãããŸããïŒ
çããåºãåã«ãåäŸã®é ã®äžé£ã®æ¬ãæãââåºããŸãã

ãããã¯ãSelect Your Adventureã·ãªãŒãºã®æ¬ã§ãã ãããã¯ã8ãããã³ã³ãã¥ãŒã¿ãŒã§ãããç¥ããªããã¡ã«ååšããŠããŸããã æåã®ããŒãžã«ã¯ãã¹ããŒãªãŒã®äžéšããããŠæåŸã«ã次ã«äœãããããã®éžæã衚瀺ãããŸãã
äŸãšããŠãç¶æ³ã«åãããŠç¹å¥ãªããã¹ããäœæããŸããã

ãã®ãChoose Your Adventureãã¯ããµã³ã¯ãããã«ãã«ã¯ã®ããããã¯ã¹ãå°çšã§ãã
ããµã³ã¯ãããã«ãã«ã¯ã®DotNextã§çŽ æŽãããåæ¥ãéãããŸããã ããŒãã£ãŒã®åŸãäŒè°ã«åå ããŠããŸãã å¿ããäžæ¥ã§ããã ãã¶ãããªãã¯ããªãã®éšå±ã«è¡ã£ãŠå¯ãã¹ãã§ãã ãããã寿åžã泚æãã人ãããŸãã ãŸãã¯ãããŒãã£ãŒã«æ®ãããŠãŒãžã³ãã«ã©ãªã±ãæãæ§åãèŠãããšãã§ããŸããïŒã
ãã®ã³ã³ãã³ãã¯ç©èªã®å§ãŸãã§ãã ãããŠãçµæã®ãã¬ãŒã³ããŒã·ã§ã³ã«ãã€ããŒã¡ãã£ã¢æäœãçµã¿èŸŒãŸããŠããŸãã
ãéšå±ã«è¡ã£ãŠå¯ãã«ã¯ã23ããŒãžã«é²ãã§ãã ããã
寿åžãé£ã¹ãã«ã¯ã41ããŒãžã«é²ã¿ã
ããŒãã£ãŒã«åå ããŠã«ã©ãªã±ãèŠãã«ã¯ã52ããŒãžã«é²ãã§ãã ããã
ããã¯ãã€ããŒã¡ãã£ã¢ã§ãã çµæã«ã¯ãã·ã¹ãã ãšå¯Ÿè©±ããæ¹æ³ã説æãããã€ããŒã¡ãã£ã¢ã¢ãããŒã·ã§ã³ãå«ãŸããŠããŸãã
å®éã«ã³ãŒãã§ã©ã®ããã«èŠãããèŠãŠã¿ãŸãããã ããã«ã¯hal + json圢åŒã䜿çšããŸãã ããã¯ããã€ããŒã¡ãã£ã¢ã¬ããªã±ãŒã·ã§ã³èšèªçšã®äœåãªããããæã€jsonã§ãã ãã®åœ¢åŒã䜿çšããçç±ã¯ããã®åœ¢åŒãéåžžã«çããããPowerPointã¹ã©ã€ãã«ç°¡åã«é 眮ã§ããããã§ãã
ãããã£ãŠãé åãè¿ãã ãã§ãªããèŠçŽ ã®ã³ã¬ã¯ã·ã§ã³ãäœæããŸãã ã³ã¬ã¯ã·ã§ã³å ã®ãã€ããŒãïŒã³ã³ãã³ãïŒãè¿ãã ãã§ãªããçµæãä»ã®å ŽæïŒãã€ããŒã¡ãã£ã¢ãéããŠå®è£ ãããå©çšå¯èœãªç¶æ é·ç§»ïŒãžã®ãªã³ã¯ã§è£å®ããŸãã
å€æ°ã€ã³ããã¯ã¹ã玹ä»ããŸã-ããã¯ããªããããããŒãžã§ãã åèš-ã³ã¬ã¯ã·ã§ã³å ã®ãšã³ããªã®ç·æ°ã
GET /profiles HTTP/1.1 200 OK Content -Type: application/hal+json { "_links" : { "self" : { "href" : "http://herobook/profiles?index=0" }, "next" : { "href" : "http://herobook/profiles?index=5" }, "last" : { "href" : "http://herobook/profiles?index=220" } }, "count" :5, "index" :0, "total" : 223, "items:" [ { "username":"ironman", "name":"Tony Stark" } { "username":"spidey", "name":"Peter Parker" }, { "username":"blackwidow", "name":"Ì " }, { "username":"pepper", "name":"Pepper Potts" }, { "username":"storm", "name":"Ororo Munroe" } ] }
ã³ãŒããèŠãŠã¿ãŸãããã
ãããããŸãæåã«èŠåãããã®ã¯ãããã§å¥åŠãªãã£ã©ã¯ã¿ãŒã«æ°ä»ããããããŸããã ããã¯CïŒã§ãã ç§ã¯FiraCodeã䜿çšããŠããŸããããã¯æ¬¡ã®ç¥ã§ãã

ããªãã圌ãã«äŒããšããå¿é ããªãã§ãã ããã ãããã¯é¢çœãå°ããªã«ãŒã³æåã§ã¯ãªããæ°åŠçãªèšå·ã§ãã ç§ã¯ãããã奜ãã§ãã FiraCodeã¯ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãã ãã¡ãããããŠã³ããŒãã§ããŸãã
ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ã§ã¯ãäœæããããŒã«ã䜿çšããŠãã®ãããªããšãåŠçããŸãã GitHubãªããžããªã«ãããŸãïŒèšäºã®åé ã®ãªã³ã¯ïŒã

ããã¯ããã©ãŠã¶ãŒå ã§å®è¡ãããAPI ExplorerããŒã«ã«ãããŸããã äžæ¹ã§ã¯ãããªãã¯çŽ æŽãããä»äºãã©ãŠãžã³ã°ããããŠã§ããã©ãŠã¶ãæã£ãŠããŠãAmazonãšEbayã§ç©ãè²·ãã ãããã¯ãã¹ãŠAPIã§éåžžã«ããŸãæ©èœããŸãã äžæ¹ãCallcommandlineã®ãããªããŒã«ããŸãã¯Postmanã®ãããªç¹å¥ãªããŒã«ããããŸãã ãããã¯ãåäžã®èŠæ±ã«é©ããŠããŸãã ãã ãããã€ããŒã¡ãã£ã¢ã·ã¹ãã ãããã²ãŒãããå Žåã¯ã䜿çšããªãã§ãã ããã ç§ã®ããŒã«ã¯ããããã®äž¡æ¥µç«¯ã®ã©ããã«ãããŸãããã©ãŠã¶ãŒã§åäœãïŒãã¹ãŠJavaScriptã§åäœããŸãïŒããã€ããŒã¡ãã£ã¢ãç解ããŸãã
APIã䜿çšããŸãã /ãããã¡ã€ã«ãå ¥åãã[Go]ãæŒããŸãã

ããã«å¿ããŠãæ£åžžã«å®äºããããšã«é¢ããã¡ãã»ãŒãž-200 OK-ããã³200äžä»¶ã®ã¬ã³ãŒããåãåããŸãïŒã€ã³ã¿ãŒãããäžã§åã³ããã¯ããã¯ã®ã¹ãŒããŒããŒããŒãåãããããã倧ããªã¹ãã¬ããã·ãŒãã«å ¥ãããããã§ãç§ãããªããã°ãªããªãã£ãã®ã¯ããã®ãã¹ãŠãã³ããŒããŠã¢ããããŒãããããšã ãã§ããïŒã
ãã®ãããªçããæäŸããã³ãŒããèŠãŠã¿ãŸãããã
Web API
æåã®ãã¢ã¯ãasp.net Web APIã§ãã DotNextã§ã¯ãã»ãšãã©ã®äººã.NETãšASP.NETã«ç²ŸéããŠãããšæããŸãã ãããŠãããã¯åãªãWeb APIã§ããã倧ããããšã§ã¯ãããŸããã
ã³ãŒãã¯æ¬¡ã®ãšããã§ãã

ProfilesControllerïŒApiControllerãç¶æ¿ïŒããããŸãã DemoDatabaseïŒïŒããŒã¿ããŒã¹ãšãdb.ListProfilesïŒïŒãè¿ããããªãã¯GetïŒïŒãªããžã§ã¯ãããããŸãã
ãã€ããŒã¡ãã£ã¢ã®èŠä»¶ã«åãããŠãã®ã³ãŒããã©ã®ããã«é©åãããããšãã§ããŸããïŒ çµæãããŒãžã«åå²ããããããŒãžããå¥ã®ããŒãžãžã®ãªã³ã¯ãæäŸããŸãã
æåã«è¡ãå¿ èŠãããã®ã¯ãé åãäœãã«ã©ããããããšã§ãã ããŒã¿ã ããè¿ãããšã¯ã§ããŸããã ããã«é©ãã.NETã®æ©èœã®1ã€ã¯ãå¿ååãäœæããæ©èœã§ãã ãã®åŸãããããã·ãªã¢ã«åããŠããããã«å ¥ãããããã®ãšã»ãŒåããã®ãååŸã§ããŸãã ããã¯æ¬åœã«åŒ·åãªããŒã«ã ãšæããŸãã å¿ååã¯ã.NETã³ãŒãã¢ãžã¥ãŒã«éã§æž¡ãããšãããšãå€ãã®åé¡ã解決ããŸãã ãã ããWebãµã€ããäœæããã ãã§ããã°ããããçŽæ¥Jsonã«å€æããŠã·ãªã¢ã«åããäžèŠãªãã®ãç Žæ£ããŠãã ããã
public object Get() { var profiles = db.ListProfiles(); var result = new { items = profiles }; return result; }
ååŸãããã®ã¯æ¬¡ã®ãšããã§ãã

ãŸã 200äžãšã³ããªãåºåããŠããŸãããé åã¯JavaScript JSONãªããžã§ã¯ãå ã«ãããŸãã ããã¯ãããå€ãã®æ©èœãçµ±åã§ããå Žæãããããšãæå³ããŸãã
æåã«ãããããšã¯ãçµè«ãçãããããšã§ãã 1ããŒãžãããã®çµæã®æ°ã瀺ãå®æ°ãå ¥åããã ãã§ãã 10ã«ãªããŸãããããŠãããŒã¿ããŒã¹ã«ç§»åããŠæ¬¡ã®ããã«èšããŸãã
profiles = db.ListProfiles().Take(REULTS_PER_PAGE)
ããŒã¿ããŒã¹ãåç §ãããšããããã¡ã€ã«ã¯10åãããããŸããã å®å šãªGetïŒïŒã³ãŒãã¯æ¬¡ã®ãšããã§ãã
<code>public object Get() { var RESULTS_PER_PAGE = 10; var profiles = db.ListProfiles().Take(RESULTS_PER_PAGE) var result = new { items = profiles }; return result; }
ããŒã«ã«æ»ããããŒãžãæŽæ°ããŸãã 200äžã®ä»£ããã«ã10ã®ãšã³ããªãååŸããŸãïŒããã¯ã¹ã¯ããŒã«ããŒã§ç¢ºèªã§ããŸãïŒã

åé¡ã解決ããŸããã ããã§ããªã¯ãšã¹ã/ãããã¡ã€ã«ãã€ã³ã¿ãŒãããæ¥ç¶ã®é害ãåŒãèµ·ããããšã¯ãªããªããŸãã
次ã«è¡ãããšã¯ãããŒãžããªã¯ãšã¹ãããããã®ãªã³ã¯ã§ãã ç§ãã¡ã®APIã¯é©åãªããŒãžãäœæããã®ã«ååã¹ããŒãã§ãã

ãã ãããŠãŒã¶ãŒã¯ãã®ãããªå¯èœæ§ã«ã€ããŠç¥ããªãããããããŸã§ã®ãšããããã®ã·ã¹ãã ã¯RESTã«æºæ ããŠããŸããã
ã³ãŒãã«æ»ã£ãŠäœããä¿®æ£ããå¿ èŠããããŸãã
å¿ååã®çµæããããŸãã ãããã£ãŠã奜ããªãã®ããã¹ãŠè¿œå ã§ããŸãã ç¹ã«ããªã³ã¯ã ããã§ã¯ãCïŒæååè£éã䜿çšããŸãã
var result = new { _links = new { next = new { href = $"/profiles?index={index+RESULTS_PER_PAGE}" } }, items = profiles }; return result;
ããã§ããããã¡ã€ã«ãèŠæ±ãããšãããŒã¿èªäœã ãã§ãªãããªã³ã¯ã®ã³ã¬ã¯ã·ã§ã³ãååŸããŸãã
API Explorerã«æ»ããŸãã äœãèµ·ãããèŠãŠã¿ãŸãããïŒ

ãããã£ãŠããã€ããŒã¡ãã£ã¢ããµããŒãããAPIãšåŒã°ãããã®ã«åããæåã®ã¹ããããèžã¿ãŸããã
ããŒãž0ããããããŒãžéã移åã§ããŸãã
ãã ããAPIã«ã¯ãŸã ããã€ãã®åé¡ããããŸãã ããã²ãŒã·ã§ã³ãå¿ èŠã§ããããŒãžãååŸã«ç§»åã§ãããªã¹ãã®æåãŸãã¯æåŸã«ç§»åã§ããå¿ èŠããããŸãã APIã¯ããããµããŒãããŠããŸãããã ããã«ãã³ã¬ã¯ã·ã§ã³ã®æåŸã«å°éãããšãã·ã¹ãã ã¯ç©ºã®é åãè¿ãå§ããŸãã
APIãRESTã®æŠå¿µãšå®å šã«äžèŽãããã«ã¯ãçŸåšã®ããŒãžããã©ãã«è¡ãããšãã§ããããèšç®ããããã®ããžãã¯ãè¿œå ããå¿ èŠããããŸãã
ãã®ããã«ãç§ã¯å°ããªãã«ããŒã¯ã©ã¹ã䜿çšããŸãã

ããã§ãéçã¡ãœããã¯åçãªããžã§ã¯ããè¿ããŸãã 圌ã¯äœãããŠããŸããïŒ çŸåšã®ããŒãžã®ã€ã³ããã¯ã¹ãåããŒãžã®èŠçŽ æ°ãããã³èŠçŽ ã®åèšæ°ãæå®ããããã€ãã®èšç®ãå®è¡ããŸã-æåãšæåŸã®ããŒãžã®çªå·ãååŸããŸãã æåã®ãã®ã¯åžžã«ãŒãã«ãªããæåŸã®ãã®ã«ã¯åžžã«ã³ã¬ã¯ã·ã§ã³å ã®æ倧ã€ã³ããã¯ã¹ãæã€ãããã¡ã€ã«ãå«ãŸããŸãã ããã«ãã€ã³ããã¯ã¹ããŒããã倧ããå Žåãæ»ãããšãã§ããŸãã ãã ããæ»ãããšã¯ã§ããŸããããŸããindex-countãæå°ã€ã³ããã¯ã¹ããå°ããå Žåã åé²ããããšãã§ããŸãããçµãããè¶ããããšã¯ã§ããŸããã
ã¡ãœããã¯ãªã³ã¯ãè¿ããŸãã ã³ãŒãã«æ»ãã次ã®ããã«æžãçŽããŸãã
public object Get(index = 0) { var RESULTS_PER_PAGE = 10; var profiles = db.ListProfiles() .Skip(index) .Take(RESULTS_PER_PAGE); var total = db.CountProfiles(); var result = new { _links = Hal.Paginate("/profiles", index, RESULTS_PER_PAGE, total), items = profiles }; return result; }
å®è¡ããŠãã ããïŒ

ããã§ãæåãæåŸã次ãåã®ããŒãžãžã®ãªã³ã¯ãã§ããŸããã åé²ãŸãã¯åŸéã§ããŸãã ããã²ãŒã·ã§ã³ã«äœ¿çšã§ãããªã³ã¯ã¯ãæåã®ããŒãžã«å°éãããæåŸã®ããŒãžã«å°éããããèæ ®ããŸãïŒæåã®ããŒãžããæ»ãããšã¯ã§ãããæåŸããé²ãããšãã§ããŸãïŒã
ãããã£ãŠããœãŒã·ã£ã«ãããã¯ãŒã¯ã«ã¯200äžä»¶ã®æçš¿ããããŸããã ããŒã¿ãåå¥ã®ããŒãžã«åå²ãããã€ããŒã¡ãã£ã¢ã䜿çšããŠããªãœãŒã¹ã«ã¢ã¯ã»ã¹ãããã¹ãŠã®ãŠãŒã¶ãŒãã³ã¬ã¯ã·ã§ã³å ãããã²ãŒãããæ¹æ³ãèªèã§ããããã«ããŸããã
ãªãœãŒã¹ã®å±é
ãœãŒã·ã£ã«ãããã¯ãŒã¯ã§ã¯ã人ã ã¯å人ãšæ å ±ãå ±æããŸãã 圌ãã¯åæ ã確ç«ããæŽæ°ãæçš¿ããŸãã ç§ãããå ŽæãèŠãŠãã ãããã
ãããã¯ãŒã¯ã«Iron ManããããšããŸã-Tony Starkã ãããŠåœŒã«ã¯å人ãã«ã¯ãã¹ãã€ããŒãã³ããã¿ãŒã·ã£ã»ãããããããŸãã
ãããŒã¯ã¹ããŒã¿ã¹ãæŽæ°ããŸãã
GET /profiles/ironman HTTP/1.1 200 OK Content-Type: application/json { "username": "ironman", "name": "Tony Stark", "friends" : [ { "username":"hulk", "name":"Bruce Banner" }, { "username":"spidey", "name":"Peter Parker" }, { "username":"blackwidow", "name":"Ì " }, /* another 500 friends here... */ ] "updates" : [ { "id" : 1234, "update" : "Working a new Iron Man suit!", "posted" : "2016-02-23T18:25:43.511Z"}, { "id" : 1543, "update" : "New suit's gonna have a selfie stick! Oh yeah!", "posted" : "2016-04-16T18:25:43.511Z"}, { "id" : 1782, "update" : "Selfie stick broke. Oh well. Back to the drawing board", "posted" : "2016-04-17T08:26:13.511Z"} ] }
圌ã®æåã®æŽæ°ïŒããããç§ã¯æ°ããã¢ã€ã¢ã³ãã³ã®ã³ã¹ãã¥ãŒã ãäœã£ãŠããŸããã次ã¯ããšãŽã€ã¹ããçŽ æŽãããã®ã§ãèªæ®ãæ£ãä¹ããŸãã ãããŠã圌ã¯å¥ã®ã¢ããããŒããå ¬éããŸãããã»ã«ãã¹ãã£ãã¯ãå£ããŸããã ç§ã¯å³é¢ã«æ»ããç 究宀ã«æ»ããŸããã
ãã¡ããã圌ã®å人ã«ããããã£ãŒã«ããããŸãã ãããã£ãŠããããã®åæŽæ°ã«ã¯å人ã®ãªã¹ããããããããã®åå人ã«ã¯ç¬èªã®æŽæ°ããããŸãã

ããããå人ã«ã¯å人ãããŠããããã«ã¯ç¬èªã®æŽæ°ãªã©ããããŸãã

ããã§ãããã°ããŒã¿ãšåŒã°ãããã®ã«å°éããŸãã

ããã°ããŒã¿ã¯ããã®ããŒã¿ã®JSONãPowerPointã¹ã©ã€ãã«é 眮ããã«ã¯å€§ããããããã§ãã ãããç§ã®å®çŸ©ã«ããŸãããã
ã¹ããŒã¿ã¹ãšãã®æŽæ°ã®ãµããŒããå®è£ ããŸããã ãããŠãé»è©±ã鳎ããŸãïŒãããªãã®APIã¯ãã£ãã«å šäœããããã¯ããŸãã...åã³ïŒãããããªãã®APIã¯ããŒã¿ããŒã¹ããªãŒããŒããŒãããŠããŸãã ç¹°ãè¿ããŸãïŒ..ç§ã¯ãPHPã䜿çšããå¿ èŠããããšèšããŸãã...ïŒPHPã®ä»¥åã¯ããã®ãããªåé¡ãèããããšã¯ãªãã£ãã§ãããïŒïŒ
ãããã©ã®ããã«ä¿®æ£ããŸããïŒ ãã®åé¡ã解決ããããã«äœãããŸããïŒ åã³ããŒã¿ãå ±æããŸãã åäžã®ã¬ã³ãŒãã«é¢é£ä»ããããã°ã©ãå šäœãè¿ã代ããã«ããªã³ã¯ãæäŸããŸãã ãªã³ã¯ã䜿çšããŠååŸã«ç§»åããæ¹æ³ã«ã€ããŠã¯ãã§ã«èª¬æããŸããã 次ã«ããã®ã¢ã€ãã¢ãæ¡å€§ããŸãã
GET /profiles/ironman HTTP/1.1 200 OK Content-Type: application/hal+json { "_links": { "self": { "href" "/profiles/ironman" }, "friends": { "href" : "/profiles/ironman/friends" }, "photos": { "href" : "/profiles/ironman/photos" }, "updates": { "href" : "/profiles/ironman/updates" } }, "username" : "ironman", "name" : "Tony Stark" }
self-衚瀺ããŠãããããã¡ã€ã«ã瀺ããŸãããããã¡ã€ã«ãå¥ã®ã«ãŒãã«æ®ããŠãããã«æ»ãããšãã§ããããã«ãããããã§ãïŒããã¯ãã®ãããªã·ã¹ãã ã®äžè¬çãªæ¹æ³ã§ãïŒã ãŸããå人ãåçãã¢ããããŒãã«ãã°ããã¢ã¯ã»ã¹ã§ããŸã-å人ãåçãã¢ããããŒãã
GET /profiles/ironman HTTP/1.1 200 OK
ãŸãã¯
GET /profiles/ironman/friends HTTP/1.1 200 OK GET /profiles/ironman/updates HTTP/1.1 200 OK GET /profiles/ironman/photos HTTP/1.1 200 OK
åçããªã¯ãšã¹ãããŠã¿ãŸãããã
GET /profiles/ironman/photos/1234 HTTP/1.1 200 OK
誰ãããã®åçã«ã³ã¡ã³ãããŸããïŒ
GET /profiles/ironman/photos/1234/comments HTTP/1.1 200 OK
åç1345ããªã¯ãšã¹ãããŸãããïŒ
GET /profiles/ironman/photos/1345 HTTP/1.1 200 OK
ãããŠãããã«ãã誰ãã®ã³ã¡ã³ãããããŸãïŒ
GET /profiles/ironman/photos/1345/comments HTTP/1.1 200 OK GET /profiles/ironman/photos/1456 HTTP/1.1 200 OK GET /profiles/ironman/photos/1456/comments HTTP/1.1 200 OK
ãããŠãé»è©±ãåã³é³ŽããŸãïŒã1ããŒãžãäžããããã ãã«50åAPIåŒã³åºããè¡ãå¿ èŠããããŸãã?? !!!ãã ãIISãã°ãCïŒãã©ã€ãããã£ã±ãã«ãããããWebãµãŒããŒãã¯ã©ãã·ã¥ããŸããïŒPHPã§ãã®ãããªåé¡ã¯äžåºŠããããŸããã§ããïŒã-å®éãããã¯ãµãŒãã¹ãã¯ã©ãã·ã¥ããæãäžè¬çãªçç±ã®1ã€ã§ãã
ã©ãããïŒ
ç§ãã¡ã¯å€§éã®ããŒã¿ãååŸãããããåé¡ãåŒãèµ·ããããããå ±æããŸããã ãããŠä»ãå°ããªããŒã¿ã¯ä»ã®åé¡ãåŒãèµ·ãããŸãã
ãããããªãœãŒã¹å±éã¯ããããã®åé¡ã®è§£æ±ºã«åœ¹ç«ã¡ãŸãã ORMã®ãããªãã®ã«ç²ŸéããŠããå Žåã¯ãããŒãããã»ã¹äžã«ç¹å®ã®ãªããžã§ã¯ããèŠæ±ããããã«å¥ã®ãªããžã§ã¯ããå«ããããšãã§ããããšãããããŸãã
ãªãœãŒã¹ã®å±éã¯ããã€ããŒã¡ãã£ã¢APIã®åæ§ã®ã¢ã€ãã¢ã§ãã ãã®ããã«ããŠãIron Manãããã¡ã€ã«ãèŠæ±ãããã®æŽæ°ãå±éã§ããŸãã
GET /profiles/ironman?expand=updates HTTP/1.1 200 OK Content-Type: application/json { "_links": { "self" : { "href": "/profiles/ironman" }, "friends" : { "href": "/profiles/ironman/friends" }, "photos" : { "href": "/profiles/ironman/photos" }, "updates" : { "href": "/profiles/ironman/updates" } }, "username" : "ironman", "name" : "Tony Stark" "_embedded" : { "updates" : [ { "update" : "Working a new Iron Man suit â with a built-in selfie stick!", "posted" : "2016-02-23T18:25:43.511Z" }, { "update" : "Selfie stick broke. Oh well. Back to the drawing board", "posted" : "2016-04-17T08:26:13.511Z" } ] } }
ç¹°ãè¿ããŸããããããå®è£ ããæ¹æ³ã瀺ãã³ãŒãã®ãã¢ãè¡ããŸãã 2çªç®ã®ãã¢ã§ã¯ãå®éã«å¥ã®ãµãŒããŒ-ãã³ã·ãŒã䜿çšããŸãã

ãããè¡ãã³ãŒãã¯Nancyã¢ãžã¥ãŒã«ã§ãã

ã¢ããªã±ãŒã·ã§ã³ã®ProfileModulesã«ç§»åããŸãã ãã³ã·ãŒãšäžç·ã«ä»äºãããããšããªã人ã®ããã«ãããã«ã¯çŽ æŽãããæ©èœãããããšã«æ³šæããŠãã ãã-GETãPUTãPOSTãDELETEã®åHTTPã¡ãœããã®èŸæžã§ãã
ã«ãŒããã¿ãŒã³ã«äžèŽãããã¹ãŠãå«ãåçãªåŒæ°ãæã€ãªããžã§ã¯ããååŸããŸãã 次ã¯ãåŒã³åºãå¿ èŠãããã¡ãœããã§ãã

ãŠãŒã¶ãŒåãååŸããdb.loadProfileã«ç§»åããŠãããã¡ã€ã«ãè¿ããŸãã
ãã€ããŒã¡ãã£ã¢ãè¿œå ããããã«äœããããã§ããïŒ ããã«ãªã³ã¯ã®éžæãè¿œå ããŸãã ããããdb.loadProfileã¯ç§ãã¡ãåŒãæ»ãã®ã§ãã§ããŸãããããŸããŸãªäŒæ¥ã®çç±ã§ãªã³ã¯ãè¿œå ããããšã¯ã§ããŸããã ãã®ãããããŒã¿ããŒã¹ãå€æŽããã«ãªã³ã¯ãè¿œå ããŸãã
Stackoverflowã§ãããŸã§ã«åãåã£ãæãã¯ãŒã«ãªã³ãŒãã玹ä»ããŸãã ToDynamicã¡ãœãããåŒã³åºããšãåé¡ã解決ããŸãã
using System.Collections.Generic; using System.ComponentModel; using System.Dynamic; using System.Linq; namespace RealWorldRest.NancyFX.Modules { public static class ObjectExtensions { public static dynamic ToDynamic(this object value) { IDictionary<string, object> expando = new ExpandoObject(); var properties = TypeDescriptor.GetProperties(value.GetType()); foreach (PropertyDescriptor property in properties) { expando.Add(property.Name, property.GetValue(value)); } return (ExpandoObject)expando; } public static IDictionary<string, object> ToDictionary(this object d) { return d.GetType().GetProperties() .ToDictionary(x => x.Name, x => x.GetValue(d, null)); } } }
ããã¯ãCïŒã«çµã¿èŸŒãŸããæ¡åŒµã¡ãœããã§ãã 圌ã¯ãªããžã§ã¯ããåãåããåå°ã䜿çšããŸãã CïŒã®åºæ¬çãªåçåã§ããExpandableãªããžã§ã¯ãã«ã©ããããŸãã 次ã«ããªãã¬ã¯ã·ã§ã³ã䜿çšããŠãå ã®ãªããžã§ã¯ãã®ãã¹ãŠã®ããããã£ãååŸããŸãã ãããã®ããããã£ããšã«ããã£ã¯ã·ã§ããªã«ç§»åããããããã£ã®ååãšå€ãè¿œå ããŸãã ãããŠãæ¡åŒµãªããžã§ã¯ããè¿ããŸãïŒåçïŒã
ãªããããå¿ èŠãªã®ã§ããïŒ ããŒã¿ããŒã¹ããååŸãããã¹ãŠã®ãã®ãååŸããToDynamicãåŒã³åºããŸãã çŸåšããããã®ãªããžã§ã¯ãã¯åçã§ããããéããŠããŸãã è¿œå ã®ã¯ã©ã¹ãšã¡ãœããã䜿çšã§ããŸãã ãããã¯ãã¹ãŠå®è¡æã«è§£æ±ºãããŸãã èªå·±ãåçãã¢ããããŒããæäŸã§ããŸãã

ç¹°ãè¿ããŸãããå³å¯ã«å žåçãªCïŒäŒæ¥ãœãããŠã§ã¢ã®éçºã«å察åŽããã¢ãããŒãããJSONã«å€ããŸãã ããã¯ã2ã€ã®ç°ãªããœãããŠã§ã¢ã·ã¹ãã ã¢ããªã³ã°ãã©ãã€ã ã䜿çšããéåžžã«è¯ãäŸã§ãã
ããã§äœãåŸãããŸããïŒ


ãããæåã®ã¹ãããã§ãããããã®ãã€ããŒã¡ãã£ã¢ããã²ãŒã·ã§ã³ããŒã«ãäœæããŸããã ã¢ã€ã¢ã³ãã³ã®èŠªåãèŠãããšãã§ããŸãã ãã ããå±éã¯å®è£ ããŸããã§ããã
RESTã·ã¹ãã ãäœæããããã»ã¹ãçªç¶ä»æ§ãè¶ ããŸããã RFC , , . . , . , . . Nancy, , .
( string unnullable, ). : « friends ».

, API Explorer, :

expand=friends, .

, , .NET, C# .. , . JavaScript â , JSON â . .
. , , . .
GET /profiles/ironman HTTP/1.1 200 OK Content-Type: application/json { "_links": { "self" : { "href": "/profiles/ironman" }, "friends" : { "href": "/profiles/ironman/friends" }, "photos" : { "href": "/profiles/ironman/photos" }, "updates" : { "href": "/profiles/ironman/updates" } }, "name": "Tony Stark", "username": "ironman",
, , . , , . . :
- ? â ;
- ? ? ?
- ?
- ?
- ? ?
- ?
- ?
, , , , .
GET /profiles/ironman HTTP/1.1 200 OK Content-Type: application/json { "_links": { "self" : { "href": "/profiles/ironman" }, "friends" : { "href": "/profiles/ironman/friends" }, "photos" : { "href": "/profiles/ironman/photos" }, "updates" : { "href": "/profiles/ironman/updates" } }, "name": "Tony Stark", "username": "ironman", "height": 192, "weight": 85, "location": { "latitude": 59.93, "longitude": 30.33 }, "status": "Out saving the world. Again.", "hometown": "Malibu, USA" "email": "tony@stark.com", "website": "//w.ironman.com", "last_modified" : "2015-08-12T19:45:43.511Z" }
, : « »:
PUT /profiles/ironman HTTP/1.1 Content-Type: application/json { "name": "Tony Stark", "username": "ironman", "height": 192, "weight": 85, "location": { "lat": 34.02, "lon": -118.77 }, "status" : "Just got back from saving the world. Again.", "hometown": "Malibu, USA" "email": "<a href="mailto:tony@stark.com">tony@stark.com</a>", "website": "//w.ironman.com", "birthdate": "1972-01-24" } 409 Conflict
, , Apple GPS, . , , .
, : PUT , ?
, , . , . â : PUT, , . :
PUT /profiles/ironman HTTP/1.1 Content-Type: application/json { "status" : "Thinking about a disco Iron Man suit." /* : JSON // }
åäœããŸãã , . PUT PUT, .
ãã®çµæïŒ
204 No Content
, , â .
PUT /profiles/ironman/status HTTP/1.1 "Finished saving the world. I need a drink." 204 No Content
API. . , , , .
â HTTP- PATCH. , .
PATCH , Request URI, , . , «patch document» ( -).
ããªãã¡ , PATCH.
? (: «PATCH Method for HTTP» â http://tools.ietf.org/html/rfc5789 ) , . ãããå®è£ ããæ¹æ³ã¯ïŒ .
PATCH /file.txt HTTP/1.1 Host: //w.example.com Content-Type: application/example If-Match: "e0023aa4e" Content-Length: 100 [description of changes]
. . , PATCH, .
.
Linux. , , patch-, patch.
Content-type (x , ).
, . JSON, «» «», .
PATCH /profiles/ironman HTTP/1.1 Content-Type: application/x-unix-diff 11c11 < "status": "Just got home from saving the world.", --- > "status": "World saved. I need a drink.", 200 OK
, , , Json-patch. , .
PATCH /profiles/ironman HTTP/1.1 Content-Type: application/json-patch+json If-Match: "abc123" [ { "op": "replace", "path": "/status", "value": "Finished saving the world. I need a drink." }, { "op": "move", "from": "/friends/hulk", "path": "/friends[0]" } ] 200 OK
, , : , â .
, , â , HTTP-patch.
conferences/dotnext/
PATCH /conferences/dotnext HTTP/1.1 Content-Type: image/epic.selfie+png
Content-Type â epic.selfie+png. , , â . , . , «202 ». , « », , , DOTNEXT .

, DotNext 2017 Moscow â Life, liberty and the pursuit of APIness: the secret to happy code . , .
, . :
.