å ã®èšäºã¯ãJerome's Adventures in Softwareã§èªãããšãã§ããŸãã
DHHïŒDavid Heinemeyer HenssonïŒãã¬ãŒã«ã³ã³ãããŒã©ãæŽçããæ¹æ³
Full Stack Radioãšã®æè¿ã®ã€ã³ã¿ãã¥ãŒã§ãæç¥ã§ããæäžäž»ã§ããDHHã¯ãææ°ããŒãžã§ã³ã®Basecampã§ã³ã³ãããŒã©ãŒã®ã¬ãŒã«æ§é ãã©ã®ããã«æŽçãããã«ã€ããŠèª¬æããŸããã ããã«åœŒã®èãªãèšèã®è»¢åããããŸãïŒ
ã³ã³ãããŒã©ãŒã®äœæã«ãããã»ãŒåç䞻矩è ãšããŠãç§ã¯RESTã«ã³ããããç¶ããŠããŸãã
ã³ã³ãããŒã©ãŒã«äžæºãæãããã³ã«ãããã¯ç§ãã³ã³ãããŒã©ãŒãã»ãšãã©æã£ãŠããªãããã§ãã ç§ã¯ããããéè² è·ã«ããããšããŠããŸãã
ãã®ãããBasecamp 3ã§ã¯ãããçš®ã®ãµããªãœãŒã¹ãååšãããã³ã«ã³ã³ãããŒã©ãŒãè¶ ããŠããŸããã ãããã¯ãã£ã«ã¿ãŒãšããŠæ©èœã§ããŸãã
ãã®ã³ãŒããããã次ã®ããã«ãªã£ãŠãããšããŸãïŒ
class BananasController < ApplicationController def index render plain: '\_(:-))_/' end end
ããã€ãã®ãã£ã«ã¿ãŒãšããããããŠã³ã¡ãã¥ãŒãé©çšããå Žåãããã¯å¥ã®ãã®ã«ãªããŸãã æã ãç§ãã¡ã¯ãããåããããã®ããã«å®å šã«æ°ããã³ã³ãããŒã©ãŒãå®è¡ããŸãã
ç§ãç¹ã«ä»äºã«äœ¿çšãããã¥ãŒãªã¹ãã£ãã¯ã§ãïŒã³ã³ãããŒã©ãŒã«æ°ããã¢ã¯ã·ã§ã³ãè¿œå ããããšãã¯ãã€ã§ãããã®ã¢ã¯ã·ã§ã³ã¯ããã©ã«ãã§5ã€ã®ã¢ã¯ã·ã§ã³ã®1ã€ã«å«ãŸããŠããŸãããã€ãŸãããã®æ¬²æ±ãæºãããæ°ããã³ã³ãããŒã©ãŒãäœæããã ãã§ãã ïŒ ã ããç§ã¯ãããåŒã³åºããŸãã
ãããã£ãŠãInboxControllerïŒã¡ãŒã«ããã¯ã¹ã³ã³ãããŒã©ãŒïŒããããã¡ãŒã«ããã¯ã¹å ã®ãã¹ãŠã衚瀺ããã€ã³ããã¯ã¹ã¢ã¯ã·ã§ã³ããããšããŸãã ãŸãããä¿çäžã®æ°ããã¢ã¯ã·ã§ã³ãè¿œå ãããå Žåã¯ãä¿çäžã®ã¡ãŒã«ãªã©ã®ãããªãã®ã«ãªããŸãããšããå¥ã®ã¢ã¯ã·ã§ã³ãå®è¡ã§ããŸãã
ãããŠããã®ã¢ã¯ã·ã§ã³ä¿çãè¿œå ããŸãïŒ
class InboxesController < ApplicationController def index end def pendings end end
ããã¯éåžžã«äžè¬çãªãã³ãã¬ãŒãã§ãããïŒ ãããŠãç§ã䜿çšãããµã³ãã«ã§ããã«èª¬æã§ããŸãã 次ã«ãããããããããããããããšèšã£ãŠãInboxes :: PendingsControllerãšããæ°ããã³ã³ãããŒã©ãŒãäœæããŸãããã®ã³ã³ãããŒã©ãŒã«ã¯ã1ã€ã®ã€ã³ããã¯ã¹ã¢ã¯ã·ã§ã³ããããŸãã
class InboxesController < ApplicationController def index end end class Inboxes::PendingsController < ApplicationController def index end end
ãããŠãããã§ç§ããã®èªç±ãèŠã€ããã®ã¯ãåã³ã³ãããŒã©ãŒã«ç¬èªã®é©çšåéããããç¬èªã®ãã£ã«ã¿ãŒã»ãããé©çšãããŠãããšããäºå®ã§ã...
ãã®ãããã³ã³ãããŒã©ãŒã®å€§èŠæš¡ãªååžãç¹ã«åå空éã§ã®ã³ã³ãããŒã©ãŒã®ååžããããŸãã MessagesControllerããããMessages :: DraftsControllerã³ã³ãããŒã©ãŒãšMessages :: TrashesControllerããããããããã¹ãŠã®ãµãã³ã³ãããŒã©ãŒãšãµããªãœãŒã¹ãåãã³ã³ãããŒã©ãŒå ã«ãããšä»®å®ããŸãããã ç§ã®æèŠã§ã¯ãããã¯ã¯ãŒã«ã§ãã
ã¢ãŒã¡ã³
åºæ¬çã«ã圌ã¯ã³ã³ãããŒã©ãŒãæšæºã®CRUDã¢ã¯ã·ã§ã³ã®ã€ã³ããã¯ã¹ã衚瀺ãæ°èŠãç·šéãäœæãæŽæ°ãç Žæ£ã®ã¿ãè¡ãã¹ãã ãšèšã£ãã ãã®ä»ã®ã¢ã¯ã·ã§ã³ã¯ãCRUDã¢ã¯ã·ã§ã³ã®ã¿ãæã€ã³ã³ãããŒã©ãŒã®äœæã«ã€ãªããã¯ãã§ãã
ç§ã¯ããã«ã€ããŠã©ãæããŸãã
次ã¯ç§èªèº«ã®ä¿¡å¿µã§ãã 確ãã«ãæèŠã®éããããã€ããããŸãã ç§ã¯ãã ãçä¿¡è ãšã¯åŒã°ãªãã§ãã ããã èœã¡çããŠ
ãããã«ãããç§ã¯ãããç¥ã£ãŠããããããDHHã®æ¹æ³ãïŒDavid Heinmeier Henssonã®æ¹æ³ïŒã䜿çšããŠã³ã³ãããŒã©ãŒã1幎以äžãä»æ¥ãŸã§#DHHFanboyã§ç·šæããŠããŸããã åçŽãªã³ã³ãããŒã©ãŒããžãã¯ã®äŸãåé·ã§ããããšã¯æããã§ããããã£ã«ã¿ãªã³ã°ã®äŸã®ã¿ã«èšåããŠããŸãã RESTã§ãã£ã«ã¿ãŒã䜿çšããäžè¬çãªæ¹æ³ã¯ãããšãã°ãªã¯ãšã¹ããã©ã¡ãŒã¿ãŒã䜿çšããããšã§ãïŒäŸïŒGET / inboxesïŒState = pendingïŒã
äžè¬ã«ãã³ãŒãã¯çããŠã·ã³ãã«ã§ãªããã°ãªããªããšããäºå®ã«åºå·ããŸãïŒé·ãè€éã§ãã¢ã¯ã·ã§ã³ãšé¢ä¿ãéåžžã«è€éã«ãªããšããã«-DavidãšåãããšãããŸãïŒã ããããã³ã³ãããŒã©ãŒãåé¢ãããšããäž»ãªèãã«ã¯åæããŸããããã«ã¯ããã€ãã®çç±ããããŸãã
ããã«ãããç°¡åãªã³ãŒããäœæã§ããŸãã
ãã®ææ³ã䜿çšãããšãå¿ èŠãªæ°ã®ã³ã³ãããŒã©ãŒãäœæã§ããŸãã ãã ããå人çãªä¿¡å¿µã䜿çšããŠãã ããïŒç°¡æœããšã·ã³ãã«ãã«é¢ããããã©ã«ãã®ã³ã³ãããŒã©ãŒïŒCRUDã¢ã¯ã·ã§ã³ä»ãïŒãããå ŽåïŒã¬ãŒã«ã«è¶³å Žã眮ããªã©ïŒãããããåã€ã³ããã¯ã¹/ã·ã§ãŒ/ãªã©ãç¬èªã®ã³ã³ãããŒã©ãŒã«æœåºããå¿ èŠã¯ãããŸããã
ã³ã³ãããŒã©ãŒã®åé¢æè¡ã¯ãCRUDã¢ã¯ã·ã§ã³ãšããå¯äžã®æ¬ ç¹ã«ãããããããã³ã³ãããŒã©ãŒèªäœããã匷åã«ãªããšæ¹åãããŸãã ãã®å Žåã®å¯ŸåŠæ¹æ³ ãã®ã³ãŒãã¯ããã®ããã®ã³ã³ãããŒã©ãŒã§äœæããã ãã§ãã
ããšãã°ãããã§æãæŽç·Žãããã³ã³ãããŒã©ãŒã¯çŸåšã®äŒç€Ÿã®ããã«èŠããŸãïŒå°ããªã¢ãã«ãšããªã倧ããªã³ã³ãããŒã©ãŒãYMMVã䜿çšããŸãïŒYMMV-èµ°è¡è·é¢ã¯ç°ãªãå ŽåããããŸã
class Api::V1::PurchasesController < Api::V1::ApplicationController rescue_from Stripe::StripeError, with: :log_payment_error def create load_product load_device load_or_create_user create_order create_payment authorize_payment confirm_address render json: @order, status: :created end private def load_product @product = Product.find_by!(uuid: params[:product_id]) end # ⊠end
ãããªãã¯CRUDã¡ãœããã¯1ã€ã ãã§ãïŒããã©ã«ãã§ã¯ã¢ã¯ã·ã§ã³ãäœæããŸãïŒãã·ãã¯ãã¢ãã«ã«ã¯ææå°æ©ãªæœè±¡åã¯ãããŸããããµãŒãã¹ã¯ã©ã¹ããªãã¶ãŒããŒããããŸããããŽãããããŸããã ãã¹ãŠãããã«ãããŸãã ã³ã³ãããŒã©ãŒã«äŸ¿å©ã«é 眮ã äœãèµ·ãã£ãŠããã®ããç解ããããã«ããããã®ãã¡ã€ã«ã«ãžã£ã³ãããå¿ èŠã¯ãããŸããã ãšãã£ã¿ã§ãã®åäžã®ãã¡ã€ã«ãéãã ãã§ãã ãŸããã³ã³ãããŒã©ãŒã¯Webã¢ããªã±ãŒã·ã§ã³ã³ãŒãã®ãšã³ããªãã€ã³ãã§ãããããã³ãŒãã£ã³ã°äžã«ãã®ãã¡ã€ã«ãéãå¿ èŠããããŸãã #ObviousCode
ããããããããããªãã¯ããã¹ããã£ããã®ã¯ã©ã¹ã¯ã©ãããã倧ããããäœãè©°ã蟌ãã§ããŸããïŒããšå°ããã§ãããããã¡ãããããã¯éåžžã«å€§ããããŸãã§...èŠããã«å€§ããã§ããïŒ ããããããã144è¡ã§ããããæãè€éãªã³ã³ãããŒã©ãŒã§ãã ææªã®ææªããŸã£ããã«ã ãã¡ãããã³ãŒããå°ããªæçã«åå²ããããšãã§ããŸãããç§ãã¡ã«ãšã£ãŠããã¯éåžžã«æ£åžžã§ãïŒYMMVïŒã æ®ãã®ã³ã³ãããŒã©ãŒã¯ã6ã103è¡ã§ãå¹³åã§1ã€ã®ã³ã³ãããŒã©ãŒã§ãã15è¡ã§ãã¯ããã«åçŽã§ãã ïŒçŸæç¹ã§ã¯150åã®ã³ã³ãããŒã©ãŒããããŸãïŒã
ã³ã³ãããŒã©ãŒã«200è¡ä»¥äžã®ã³ãŒãããããããã¯ãªã¯ãšã¹ãã®ããäžéšã§ãããæ®ãã¯ç¡éã®ãµãŒãã¹ãªããžã§ã¯ããã¢ãã«ããªãã¶ãŒããŒïŒãµãŒãã¹ãªããžã§ã¯ãããªãã¶ãŒããŒãã¢ãã«ïŒã«æ£åšããŠãããããžã§ã¯ããèŠããŠããŸããïŒ ãã®çš®ã®ããšã¯ãã³ã³ãããŒã©ãŒãåçŽãªãã®ïŒ éåžžã¯3ã€ïŒã«åå²ãããã®ææ³ã®ãããã§ãããã§ã¯çºçããŸããã
å®éãè€è£œã¯èª€ã£ãæœè±¡åããã害ãå°ãªããããDRYãšSRCïŒDHHã®æ¹æ³ãå«ãïŒãéåžžã«é倧è©äŸ¡ãããåå£ãªã§ãããã«æºã¡ãŠããŠã
ã³ãŒããããåäžã«ããŸã
ã³ã³ãããŒã©ãŒã«CRUDã¢ã¯ã·ã§ã³ã®æããååšããªãããšãç¥ã£ãŠããå®éã«ã¯åœ¹ã«ç«ã¡ãŸããã ç解ã§ããªãã¢ã¯ã·ã§ã³ãèŠã€ããããã«ã倧ããªã³ã³ãããŒã©ãŒã§æšæž¬ãã¹ã¯ããŒã«ãããå¿ èŠã¯ãããããŸããã éåžžã®ã¢ã¯ã·ã§ã³ãã«ãŒãïŒã«ãŒãïŒã«è¡šç€ºãããå Žåãã©ã®ããã«/èå³æ·±ããã®ã§ã¯ãããŸããã
åçŽãªçµç¹ãäœããšããç§ã¯é©ããªãã®ã奜ãã§ãã ç§ã¯ãã³ãŒãã®çµ±äžæ§ãçµ±äžãããã³ãŒããããã³åŒ·åãªãæ§æããèŠçŽãã奜ãã§ããããããä»ã®Rubyãã¬ãŒã ã¯ãŒã¯ãããRailsã奜ãçç±ã®1ã€ã§ãã ãã¹ãŠãåãããã«ç·šæãããŠãããããæ¥åžžçãªææ決å®ã«è²»ããæéãççž®ããããžãã¹ã«ãšã£ãŠæ¬åœã«éèŠãªåéã§æåããããšãã§ããŸãã
çè«çã«ã¯ãããã¯ãããã³ãŒãããå¥ã®ã³ãŒãã«ç§»åããéåžžã«çãæéã§100ïŒ ã®çç£æ§ãå®çŸã§ããããšãæå³ããŸãã èéã§ã¯ã人ã ã¯ãã²ã©ãRailsã¢ããªã±ãŒã·ã§ã³ããç解ããããã«ãªããŸãã ããäŒç€Ÿã¯ãªãã¶ãŒããŒïŒç§ã®ãè¶ã§ã¯ãããŸããïŒãªã©ã®å»ºç¯ãã¿ãŒã³ã䜿çšã§ããå¥ã®äŒç€Ÿã¯TrailblazerïŒç§ã®ãè¶ã§ã¯ãããŸããããããã«ã€ããŠèå³æ·±ãã¢ã€ãã¢ããããŸãïŒãªã©ã®è¿œå ã®ã¢ãŒããã¯ãã£ã䜿çšã§ããŸãã 4çªç®ã¯äžè¬çã«ç¬èªã®ãã®ãªã©ã§ãã
ããã¯ãã¹ãŠã人ã ãããã©Railsã¢ããªã±ãŒã·ã§ã³ã®ãããããæ§é ã®æ¬ åŠãã«äžæºãšäžæºãæ±ããŠãããšããäºå®ã«ãããã®ã§ãã ããã§åœŒãã¯ä»ã®å Žæã§è¿œå ã®æ§é ãæ¢ããŠããŸãã ã²ã€ãºïŒ 解決çã¯ããªãã®éŒ»ã®äžã«ãããŸãã ã³ã³ãããŒã©ãŒãåé¢ããCRUDã¢ã¯ã·ã§ã³ã®ã¿ã䜿çšããŸãã 2åç°¡åã§ãžã¥ãã¢ãã¬ã³ããªãŒã
Railsã¯ãã³ã³ãããŒã©ãŒã®ãã¥ãŒãªã¹ãã£ãã¯ãªåé¢ãä¿é²ããããè¯ãä»äºãããããšãã§ããŸãã 圌ãã®ããã¥ã¡ã³ãã«ã¯ãã...éåžžã¯INVENTIVEã«ãŒãã£ã³ã°ã䜿çšããå¿ èŠããããŸã...ããšç°¡åã«æžãããŠããŸãããCRUDã¢ã¯ã·ã§ã³ãšRESTfulã®æŠå¿µã¯ãããã¥ã¡ã³ãå ã§é·ãéã¯ã£ãããšããããŸãã
RTFMã䜿çšããŠããå ŽåïŒRTFM-ã¯ãœããã¥ã¢ã«ããèªã¿ãã ããïŒãã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ïŒCRUDãé€ãïŒãè¿œå ããããšã¯ãã¬ãŒã«ã®æ¹æ³ãã§ã¯ãªãããšãå°ãªããšãäžåºŠã¯èããããšããããšæããŸãã
RESTã«ã€ããŠèããããã«ãªããŸãã
RESTã¯ããã®ã¢ãŒããã¯ãã£ã¹ã¿ã€ã«ãçµ±äžãããŠããã·ã³ãã«ã§ãããããå€ãã®äººã ã«æãããŠããŸãã RESTfulãç解ããïŒå®éã«ç解ããïŒãšãããäžæ¹ãç解ãããããªããŸãã
çè«çã«ã¯ãå°ãªããšãïŒå šå¡ã®èªèšŒïŒ ;-)ããžãã¹ããžãã¯ã¯ã¢ããªã±ãŒã·ã§ã³éã§æããã«ç°ãªãããããããç解ããå¿ èŠããããŸãããããžãã¯ã¯ã©ãã§ã䌌ãŠããããšãã©ã®ããã«ç解ããŸããã ã€ãŸããStripeã§è²»çšãäœæãïŒèª°ãã®ãéãåãïŒãTwilioã§SMSãäœæãïŒã€ãŸãéä¿¡ïŒãGithubã§ã¹ãã¬ãŒãžãååŸããŸãã
ã¢ã¯ã·ã§ã³ã®ä»£ããã«åè©ã䜿çšããŠãRESTã䜿çšããããã«æåã«é ãå°ãç·åŒµãããå¿ èŠããããŸãããæ¯æããã§ã¯ãªãããæ¯æããäœæãããã§ã¯ãªããæ®é«ã«è³éãè¿œå ãããã§ã¯ãªãããã©ã³ã¹ã·ãŒãã®è³æ¬ïŒããã©ã³ã¹ã§è³éãäœæãããïŒãªã©ã å°ãå¥åŠãããããŸããããSOAPãWSDLããã®ä»ã®ãã®ã«æ»ããããæ¯é±ãã®äŸ¡æ Œãæ¯æãããšã«ãªããŸãïŒå Java / JEEéçºè ã¯ç§ã話ããŠããããšãç¥ã£ãŠããŸãïŒã
ããã«ãã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¹ãŠã®ããžãã¹ããžãã¯ïŒå¿ ãããå®è£ ã§ããå¿ èŠã¯ãããŸããïŒãRESTã«ãã£ãŠæ±ºå®ãããŸããRESTã¯ãããç°¡æœã§ã·ã³ãã«ãªããžãã¹ããžãã¯çšã«äœæããããã®ã§ããã ã ãããŸã§ã¯ãRESTã§äœã§ãè¡šçŸã§ããããšãç¥ã£ãŠããŸããããã¯æããã§ãã ããã«ãããå¶éããªããªããŸãã
CRUDã¢ã¯ã·ã§ã³ã®ã¿ã䜿çšããŠå ±æã³ã³ãããŒã©ãŒãè¡šãRESTful Railsã«ãŒãã®äŸã次ã«ç€ºããŸãã
resources :purchases, only: :create resources :costs_calculations, only: :create namespace :company do resource :account_details, only: :update resource :website_details, only: :update resource :contact_details, only: :update end namespace :balance do resources :funds, only: :create end resource :bank_account, only: :update
RESTèšèšãæ¹åããããã«ïŒç¹ã«åãªãœãŒã¹ãæ¥ç¶ãããŠããå ŽåïŒãå®è£ ãæ°ã«ããã«ãã¿ã€ã ã¹ã¿ã³ãïŒPOST /æ®é«/è³éïŒã®å é ã«ã¢ã¯ã·ã§ã³+ãªãœãŒã¹ãèšè¿°ãããšãã«ãéåžžRESTãçç¥ããŸãã ãããããååãå²ãåœãŠããããšããç§ã¯èœã¡çããŠããŸãã Railsã¯RESTãé©åã«ãµããŒãããŠããããããã¹ãŠãRailsã«ãŒãã«å€æããŸããããã¯éåžžã«äŸ¿å©ã§ãã
ãããã«
ã³ã³ãããŒã©ãŒã®ã¹ã±ãŒã«ãéåžžã«å€§ãããããžãã¯ãå€ãããããå°é£ãå€ãããå Žåã«ã³ã³ãããŒã©ãŒãåé¢ãããšãã³ãŒãã«è¯ã圱é¿ãäžããå¯èœæ§ããããŸãã
ããã¯ãæœè±¡åãå¿ããããšããæå³ã§ã¯ãããŸããã å°ãäœããªããŸãã äžéšã®ãã€ã³ããšããžãã¯ã«ã¯ãæ··åã³ã³ãããŒã©ãŒãå¿ èŠã§ãã ãããªãã¯ã¢ã¯ã·ã§ã³ã1ã€ãããªãã³ã³ãããŒã©ãåå²ããå Žåã§ã倧ããèŠããå ŽåããããŸãã ããã¯ã¢ãã«ã®ã¡ãœããã«ãåœãŠã¯ãŸããŸããç¥ãç§ãèš±ããŠããããããããŸããããããã§ãµãŒãã¹ãªããžã§ã¯ããç»å ŽããŸãïŒæ®å¿µãªããããµãŒãã¹ãªããžã§ã¯ãã¯æ³šæããŠãã ããã
ã¢ããªã±ãŒã·ã§ã³ã倧ãããªãã°ãªãã»ã©ãã³ãŒããã©ãã ãã¯ãªãŒã³ã§ãã£ãŠãããããç解ããããã«è²»ããæéãé·ããªããŸãã ããããåé¢ã³ã³ãããŒã©ãŒã¯ç©äºãç°¡åã«ããŸãã