Build a custom (micro)framework with ZF2 Components (as building blocks)

1,503 views

Published on

We will cover how to build a custom microframework using ZF2 components as building blocks.

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,503
On SlideShare
0
From Embeds
0
Number of Embeds
225
Actions
Shares
0
Downloads
11
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Build a custom (micro)framework with ZF2 Components (as building blocks)

  1. 1. ZFDAY - 2014 BUILD A CUSTOM (MICRO)FRAMEWORK WITH ZF2 COMPONENTS AS BUILDING BLOCKS Author Walter Dal Mut / @walterdalmut
  2. 2. WHO AM I? Walter Dal Mut, I work at Corley S.r.l. and also at UpCloo Ltd. You can contact me at: walter.dalmut@gmail.com On Twitter: @walterdalmut On GitHub: wdalmut
  3. 3. WHY A CUSTOM FRAMEWORK? Tipically because we want to solve a particular problem. ZendFramework is a general purpose Web Framework that can fit different problems easily.
  4. 4. IT SOUNDS LIKE REINVENTING THE WHEEL NO, WE DON'T WANT! We will use ZF2 components as building blocks We will drive a personal behaviour
  5. 5. IT COULD WORK!!
  6. 6. REQUIREMENTS Event Driven Design Dependency Inversion Principle TESTABLE/TDD
  7. 7. EVENT DRIVEN DESIGN All framework operations are events (like ZF2)
  8. 8. DEPENDENCY INVERSION We will focus on Service Manager
  9. 9. [ WE WANT TO TEST OUR APPLICATIONS ]
  10. 10. COMPOSE IT! { } "eur" { rqie: "edrmwr/edeetaae" "." znfaeokzn-vnmngr: 2*, "edrmwr/edsrieaae" "." znfaeokzn-evcmngr: 2*, "edrmwr/edmc:"." znfaeokzn-v" 2*, "edrmwr/edht" "." znfaeokzn-tp: 2* } , "eur-e" { rqiedv: "hui/hui" ".." ppntppnt: 37* } ,
  11. 11. LET'S GO TO SCHOOL We have to learn our building blocks!
  12. 12. THE EVENT MANAGER $vnMngr=nwZnvnMngrEetaae(; eetaae e edEetaaevnMngr) / Tigra eet / rge n vn pbi fnto tigr$vn,$agt=nl,$rv=nl) ulc ucin rge(eet tre ul ag ul; / Atc alsee t a eet / tah itnr o n vn pbi fnto atc(eet $alak $roiy; ulc ucin tah$vn, clbc, pirt) There are many other methods (detach, triggerUntil, etc...) See it on Github
  13. 13. HOW EVENT MANAGER WORKS? pbi fnto tsEetaae( ulc ucin etvnMngr) { $v =nwEetaae(; e e vnMngr) $sald=fle iCle as; $v>tah'neet,fnto(eet ue($sald { e-atc(a-vn' ucin$vn) s &iCle) $sald=tu; iCle re }; ) $v>rge(a-vn"; e-tigr"neet) } $hs>setre$sald; ti-asrTu(iCle)
  14. 14. THE SERVICE LOCATOR $evcMngr=nwZnevcMngrSrieaae(; srieaae e edSrieaaeevcMngr) "evcs = [ srie" > "noals = [ ivkbe" > "oraeop = "oraeop, YuNmCm" > YuNmCm" ] , "atre"= [ fcois > "oraeevc"= "oraeevcFcoy, YuNmSrie > YuNmSrieatr" ] , "lae"= [ aiss > "orais = "oraeevc" yu.la" > YuNmSrie, ] ] See it on Github
  15. 15. CONFIGURE S.L. FROM ARRAY $evcMngr=nwZnevcMngrSrieaae(; srieaae e edSrieaaeevcMngr) $ofg=nwZnevcMngrCni( cni e edSrieaaeofg[ "noals = [.] ivkbe" > .., "atre"= [.] fcois > .., "btatfcois = [.] asrc_atre" > .., "lae"= [.] aiss > .. ] ) $ofg>ofgrSrieaae(srieaae) cni-cniueevcMngr$evcMngr;
  16. 16. HOW SERVICE MANAGER WORKS? pbi fnto tsSrieaae( ulc ucin etevcMngr) { $m=nwSrieaae(; s e evcMngr) $hs>ofg>ofgrSrieaae(s) ti-cni-cniueevcMngr$m; $hs>setre$m>a(eape); ti-asrTu(s-hs"xml") } $hs>setae ti-asrSm( $m>e(eape) s-gt"xml", $m>e(eape) s-gt"xml" ) ;
  17. 17. THE ROUTER $t =ZnvotrHtreotSak:atr(ra $ofg; rr edMcRuetpTeRuetc:fcoyary cni) "ots = [ rue" > "otNm"= [ rueae > "ye = "iea" tp" > Ltrl, "pin"= [ otos > "ot"= "pt" rue > /ah, "eals = [ dfut" > "otolr = "Fae, cnrle" > ZNm" "cin =>"cinae, ato" atoNm" ] ] , "a_emnt"= tu, mytriae > re ] ] $otMth=$t-mthRqet$eus) rueac rr>ac(eus rqet;
  18. 18. HOW ROUTER WORKS? pbi fnto tsRueac( ulc ucin etotMth) { $otr=TeRuetc:fcoy$hs>ofg; rue reotSak:atr(ti-cni) $eus =nwRqet"pt"; rqet e eus(/ah) $otMth=$otr>ac(rqet; rueac rue-mth$eus) $otolrae=$otrac-gtaa(cnrle"; cnrleNm rueMth>ePrm"otolr) $cinae=$otMth>ePrm"cin) atoNm rueac-gtaa(ato"; } $hs>setqas"Fae,$otolrae) ti-asrEul(ZNm" cnrleNm) $hs>setqas"cinae,$cinae) ti-asrEul(atoNm" atoNm)
  19. 19. REQUEST / / $eus =nwedHthEvrnetRqet) rqet e ZntpPpniomneus(;
  20. 20. RESPONSE $epne=nwedHthEvrnetRsos(; rsos e ZntpPpniomnepne) $epne>dHaes[.]; rsos-adedr(..) $epne>eCnet"."; rsos-stotn(..) $epne>ed) rsos-sn(;
  21. 21. HYDRATORS pbi fnto etat$bet; ulc ucin xrc(ojc) pbi fnto hdaeary$aa $bet; ulc ucin yrt(ra dt, ojc) $lsMtos=nwedSdiyrtrCasehd(; casehd e ZntlbHdaolsMtos) $betrp=nwedSdiyrtobetrpry) ojcPo e ZntlbHdarrOjcPoet(; $ra =nwedSdiyrtoraSraial(; ary e ZntlbHdarrAryeilzbe)
  22. 22. LET'S START!
  23. 23. EVENTS!
  24. 24. THE FRAMEWORK EVENTS LIST BEGIN The loop begins ROUTE Parse the actual route in order to found a dispatchable action PRE.FETCH Before dispatch the action EXECUTE Dispatch all actions RENDER Render your data FINISH The loop ends
  25. 25. ON ERRORS? BEGIN ROUTE PRE.FETCH 404/500/HALT RENDER FINISH
  26. 26. TEST IT! pbi fnto tsBsAplw) ulc ucin etaepFo( { $eus =Rqetatr:cetRqet"vldul,"E" [) rqet eusFcoy:raeeus(/ai-r" GT, ]; $p =nwAp) ap e p(; $p-steus(rqet; ap>eRqet$eus) $p-stevcMngrnwZnevcMngrSrieaae() ap>eSrieaae(e edSrieaaeevcMngr); $p-stvnMngrnwZnvnMngrEetaae() ap>eEetaae(e edEetaaevnMngr); $epne=$p-rn)>epne) rsos ap>u(-rsos(; } $hs>setqas44 $epne>eSauCd() ti-asrEul(0, rsos-gtttsoe); F FI ( tss 1asrin) AL 1 et, setos
  27. 27. REQUEST pbi fnto steus(eus $eus) ulc ucin eRqetRqet rqet { $hs>eus =$eus; ti-rqet rqet } pbi fnto rqet) ulc ucin eus( { i ($hs>eus){ f !ti-rqet $hs>eus =nwRqet) ti-rqet e eus(; } } rtr $hs>eus; eun ti-rqet
  28. 28. RESPONSE pbi fnto stepneRsos $epne ulc ucin eRsos(epne rsos) { $hs>epne=$epne ti-rsos rsos; } pbi fnto rsos( ulc ucin epne) { i ($hs>epne { f !ti-rsos) $hs>epne=nwRsos(; ti-rsos e epne) } } rtr $hs>epne eun ti-rsos;
  29. 29. EVENT MANAGER pbi fnto stvnMngr$vnMngr ulc ucin eEetaae(eetaae) { $hs>vnMngr=$vnMngr ti-eetaae eetaae; } pbi fnto eet( ulc ucin vns) { rtr $hs>vnMngr eun ti-eetaae; }
  30. 30. EVENT TRIGGER HELPER pbi fnto tigr$ae ary$aas=[) ulc ucin rge(nm, ra prm ] { $vn =nwEet) eet e vn(; $vn-stagt$hs; eet>eTre(ti) $vn-staas$aas; eet>ePrm(prm) } rtr $hs>vns)>rge(nm,$vn) eun ti-eet(-tigr$ae eet;
  31. 31. SERVICE MANAGER pbi fnto stevcMngr$evcMngr ulc ucin eSrieaae(srieaae) { $hs>evcMngr=$evcMngr ti-srieaae srieaae; } pbi fnto srie( ulc ucin evcs) { rtr $hs>evcMngr eun ti-srieaae; }
  32. 32. ENTRY POINT! pbi fnto rn) ulc ucin u( { $hs>rge(bgn) ti-tigr"ei"; $vnsit=$hs>ipthsrcineaeEet(; eetLs ti-dsacUeAtoRltdvns) $hs>rge(rne" [dt"= $vnsit) ti-tigr"edr, "aa > eetLs]; $hs>rge(fns"; ti-tigr"iih) } rtr $hs eun ti;
  33. 33. HEY, CAN YOU DO IT? poetdfnto dsacUeAtoRltdvns) rtce ucin ipthsrcineaeEet( { ty{ r $vnsit=$hs>ipthsreus(; eetLs ti-dsacUeRqet) }cth(atxeto $){ ac HlEcpin e $vnsit=$hs>rge(hl"; eetLs ti-tigr"at) }cth(aeoFudxeto $){ ac PgNtonEcpin e $hs>epne)>eSauCd(0) ti-rsos(-stttsoe44; $vnsit=$hs>rge(44) eetLs ti-tigr"0"; }cth(Ecpin$){ ac xeto e $hs>epne)>eSauCd(0) ti-rsos(-stttsoe50; $vnsit=$hs>rge(50) eetLs ti-tigr"0"; } } rtr $vnsit eun eetLs;
  34. 34. JUST TRY IT! poetdfnto dsacUeRqet) rtce ucin ipthsreus( { $vit=$hs>rge(rue,[rqet = $hs>eus(]; eLs ti-tigr"ot" "eus" > ti-rqet)) $otMth=$vit>at) rueac eLs-ls(; i (ul==$otMth { f nl = rueac) trwnwPgNtonEcpin"aentfud"; ho e aeoFudxeto(Pg o on!) } $hs>epne)>eSauCd(0) ti-rsos(-stttsoe20; $hs>rge(pefth,[rueac"= $otMth) ti-tigr"r.ec" "otMth > rueac]; $otolr =$hs>vns)>rge(eeue,$otMth; cnrles ti-eet(-tigr"xct" rueac) } rtr $otolr; eun cnrles Why the "execute" trigger is different?
  35. 35. NOW IT WORKS! pbi fnto tsBsAplw) ulc ucin etaepFo( { $eus =Rqetatr:cetRqet"apg" "E"; rqet eusFcoy:raeeus(/-ae, GT) $p =nwAp) ap e p(; $p-steus(rqet; ap>eRqet$eus) $p-stevcMngrnwZnevcMngrSrieaae() ap>eSrieaae(e edSrieaaeevcMngr); $p-stvnMngrnwZnvnMngrEetaae() ap>eEetaae(e edEetaaevnMngr); $epne=$p-rn)>epne) rsos ap>u(-rsos(; } $hs>setqas44 $epne>eSauCd() ti-asrEul(0, rsos-gtttsoe); . O ( tss 1asrin) K 1 et, setos See it on Github Gist
  36. 36. EASY TO MOCK! pbi fnto tsORsosORueac( ulc ucin etkepnenotMth) { $p =nwAp) ap e p(; $vnMngr=nwZnvnMngrEetaae(; eetaae e edEetaaevnMngr) $vnmngr>tah"ot" fnto( { eetaae-atc(rue, ucin) rtr nwRueac(] eun e otMth[) }; ) $p-stvnMngr$vnMngr; ap>eEetaae(eetaae) $p-stevcMngrnwZnevcMngrSrieaae() ap>eSrieaae(e edSrieaaeevcMngr); $epne=$p-rn)>epne) rsos ap>u(-rsos(; } $hs>setqas20 $epne>eSauCd() ti-asrEul(0, rsos-gtttsoe); . . O ( tss 2asrin) K 2 et, setos
  37. 37. WE NEED A BOOTSTRAPPER! Or better, something that can prepare the event manager and the service manager from a default configuration!
  38. 38. LINK DEFAULT LISTENERS "itnr"= [ lsees > "ot"= [ rue > [ruelsee" "notEet] "ot.itnr, oRuevn", ] , "edrr = [ rnee" > [rnee.itnr,"edr] "edrrlsee" rne", ] , "iih = [ fns" > [rsos.itnr,"edepne] "epnelsee" snRsos", ] , ]
  39. 39. FRAMEWORK BASE SERVICES CONFIG "lae"= [ aiss > "ot.itnr ruelsee" = "itnrotLsee" > LseeRueitnr, "edrrlsee"= "itnredrrsn, rnee.itnr > LseeRneeJo" "epnelsee"= "itnredepneitnr, rsos.itnr > LseeSnRsosLsee" ] , "atre"= [ fcois > "itnrotLsee"= "evcRueitnratr" LseeRueitnr > SrieotLseeFcoy, ] , "noals = [ ivkbe" > "itnredrrsn LseeRneeJo" = "itnredrrsn, > LseeRneeJo" "itnredepneitnr = "itnredepneitnr, LseeSnRsosLsee" > LseeSnRsosLsee" ] ,
  40. 40. THE ROUTER!
  41. 41. FOLLOW ZF2 IDEAS! rtr [ eun "otr = [ rue" > "ots = [ rue" > "oe = [ hm" > "ye = "iea" tp" > Ltrl, "pin"= [ otos > "ot"= "" rue > /, "eals = [ dfut" > "otolr = "FaIay, cnrle" > ZDytl" "cin = "e21Dy ato" > gt04a" ] ] , 'a_emnt'= tu, mytriae > re ] ] ] ] ;
  42. 42. ROUTE LISTENER casRueitnr ls otLsee { pbi fnto _cntut$otr ulc ucin _osrc(rue) { $hs>otr=$otr ti-rue rue; } } pbi fnto oRuevn(eet {..} ulc ucin notEet$vn) . /Rueitnratr /otLseeFcoy $otr=TeRuetc:fcoy$ofg"otr]; rue reotSak:atr(cni[rue") $otLsee =nwRueitnr$otr; rueitnr e otLsee(rue) $hs>tah"ot" [rueitnr "notEet]; ti-atc(rue, $otLsee, oRuevn")
  43. 43. ON ROUTE EVENT pbi fnto oRuevn(eet ulc ucin notEet$vn) { $agt=$vn-gtagt) tre eet>eTre(; $eus =$vn-gtaa(rqet) rqet eet>ePrm"eus"; $ac =$hs>eRue(-mth$eus) mth ti-gtotr)>ac(rqet; i (mth { f $ac) $c =$ac-gtaa(ato"; at mth>ePrm"cin) $tl=$ac-gtaa(cnrle"; cr mth>ePrm"otolr) i (tre-srie(-hs$tr){ f $agt>evcs)>a(cl) $tl=$agt>evcs)>e(cl) cr tre-srie(-gt$tr; } $agt>vns)>tah"xct" [cr,$c]; tre-eet(-atc(eeue, $tl at) } } rtr $ac; eun mth
  44. 44. CONTROLLERS [ACTION LISTENERS] Controllers are POPO objects that returns serializable data nmsaeZa; aepc FDy casIay ls tl { pbi fnto gt04a( ulc ucin e21Dy) { rtr [ eun "ak"= [ tls > "is"= [ frt > "il"= "utatte." tte > Js il.. ] ] , .. . ] ; } }
  45. 45. BUT, POPOS ARE TOO SIMPLE We want to use other services into actions! pbi fnto tecin) ulc ucin hAto( { /Ine asriehr! / ed evc ee $yevc =$hs>evcs)>e(m.evc"; mSrie ti-srie(-gt"ysrie) } /uei.. /s t. But how to do that?
  46. 46. CONTROLLERS USES casTeotolr ls hCnrle { ueSrieaae; s evcMngr pbi fnto tecin){ ulc ucin hAto( $evc =$hs>evcs)>e(m.evc"; srie ti-srie(-gt"ysrie) } } .. .
  47. 47. TRAITS tatSrieaae( ri evcMngr) { piae$evcMngr rvt srieaae; pbi fnto stevcMngr$evcMngr ulc ucin eSrieaae(srieaae) { $hs>evcMngr=$evcMngr ti-srieaae srieaae; } } pbi fnto srie( ulc ucin evcs) { rtr $hs>evcMngr eun ti-srieaae; }
  48. 48. ZENDSTDLIBHYDRATOR $aa=[ dt "evcMngr = $agt>evcs) srieaae" > tre-srie(, "vnMngr = $agt>vns) eetaae" > tre-eet(, "epne = $agt>epne) rsos" > tre-rsos(, "eus"= $agt>eus(, rqet > tre-rqet) ] ; $yrtr=nwedSdiyrtrCasehd(; hdao e ZntlbHdaolsMtos) $yrtr>yrt(dt,$otolr; hdao-hdae$aa cnrle)
  49. 49. AND ALSO CONTROLLERS AS SERVICES "evcs = [ srie" > "noals = [ ivkbe" > "FaIay = "FaIay, ZDytl" > ZDytl" ] ] "atre"= [ fcois > "FaIay = fnto(evcLctrnefc $l { ZDytl" > ucinSrieoaoItrae s) $otolr=nwFDyIay) cnrle e Zatl(; $otolr>eMSrie$l>e(m.evc") cnrle-styevc(s-gt"ysrie); ] } , .. . rtr $otolr eun cnrle; And all others ZF2 services opportunities
  50. 50. RENDERERS! Serialize your data
  51. 51. JSON RENDERER casJo ls sn { pbi fnto rne(vn $vn) ulc ucin edrEet eet { $agt=$vn-gtagt) tre eet>eTre(; $aaak=$vn-gtaa(dt"-ls( dtPc eet>ePrm"aa)>at) $epne=$agt>epne) rsos tre-rsos(; $epne>dHaes[ rsos-adedr( "otn-ye = "plcto/sn, CnetTp" > apiainjo" ]; ) } } $epne>eCnetjo_noe$aaak) rsos-stotn(snecd(dtPc); / Ap / p $hs>vns)>tah"edr,[rnee,"edr]; ti-eet(-atc(rne" $edrr rne")
  52. 52. SEND RESPONSE TO THE CLIENT It's an event of course!
  53. 53. EMIT! casEi ls mt { pbi fnto sn(eet ulc ucin ed$vn) { $agt=$vn-gtagt) tre eet>eTre(; } } $agt>epne)>ed) tre-rsos(-sn(; /Ap /p $hs>vns)>tah"iih,[eitr "ed]; ti-eet(-atc(fns" $mte, sn") We can remove it or mock it out during testing!
  54. 54. SEE THE FIRST IMPLEMENTATION The first impl
  55. 55. AT LEAST 3 RESPONSIBILITIES BUT EFFECTIVELY MORE... Configure the application Prepare the application Run the application Single Responsibility Principle
  56. 56. REFACTOR THE FRAMEWORK 6d695f6 -> 87ad7e73
  57. 57. OK, RECAP!
  58. 58. EVENTS ANY IDEAS?
  59. 59. PERFORMANCE INSPECTION & TRACKING Symfony2 Stopwatch component casSowthitnr ls tpacLsee pbi fnto sat$vn) ulc ucin tr(eet { $xctoNm =gtcas$vn-gtagt); eeuinae e_ls(eet>eTre() $hs>eSowth)>tr(eeuinae; ti-gttpac(-sat$xctoNm) } pbi fnto lp$vn){..} ulc ucin a(eet . pbi fnto so(eet ulc ucin tp$vn) { $xctoNm =gtcas$vn-gtagt); eeuinae e_ls(eet>eTre() $xcto =$hs>eSowth)>tp$xctoNm) eeuin ti-gttpac(-so(eeuinae; } } /sn t DTDGSRIE LGES. /ed o AAO EVC, OGR.. SmoyCmoetSowthSowth yfnopnntpactpac
  60. 60. PERFORMANCE INSPECTION & TRACKING "itnr"= [ lsees > "ei"= [ bgn > [lsee.tpac" "tr", "itnrsowth, sat] ] , "r.ec"= [ pefth > [lsee.tpac" "a", "itnrsowth, lp] ] , "iih = [ fns" > [lsee.tpac" "tp] "itnrsowth, so", ] , ] "evcs = [ srie" > "lae"= [ aiss > "itnrsowth = "tpacLseeFcoy lsee.tpac" > Sowthitnratr" ] ]
  61. 61. PERFORMANCE INSPECTION & TRACKING
  62. 62. PERFORMANCE INSPECTION & TRACKING
  63. 63. PERSONAL EVENTS pbi fnto cnimusrpincin$otMthvn) ulc ucin ofrSbcitoAto(rueacEet { $sr=nwUe(; ue e sr) $sr>eNm(.) ue-stae..; .. . $niyaae-prit$sr; ettMngr>ess(ue) $niyaae-fuh) ettMngr>ls(; } $hs>vns)>rge(sbcie.e" $sr; ti-eet(-tigr"usrbrnw, ue) "itnr"= [ lsees > "usrbrnw = [ sbcie.e" > [sbcie.ade" "oiyiEal] "usrbrhnlr, ntfVami" [sascutr,"eSbcie" "tt.one" nwusrbr] ] ]
  64. 64. MAINTENANCE PAGES "itnr"= [ lsees > "ot"= [ rue > [mitnnelsees,"aneacPg" "aneac.itnr" mitnneae] ] , "xct"= [ eeue > [mitnnecnrle" "aneacAto" "aneac.otolr, mitnnecin] ] , ] casMitnneotLsee ls aneacRueitnr { pbi fnto mitnneaeEet$vn) ulc ucin aneacPg(vn eet { rtr nwRueac(]; eun e otMth[) } } Don't use this, there are better ways
  65. 65. TRY IT! Fork it on Github https://github.com/wdalmut/upcloo-web-framework
  66. 66. THANKS FOR LISTENING ALWAYS EVENTS? Author Walter Dal Mut / @walterdalmut

×