Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Zend Expressive Workshop

Adam Culp
October 15, 2016

Zend Expressive Workshop

Large and heavy PHP frameworks are a thing of the past. Modern PHP developers now have a wealth of libraries and packages available to perform specific tasks, and microservices are fast becoming a preferred way to architect applications. But many don't know how to start, and get thrown in the deep end to flounder.

This hands-on workshop will introduce what microservices are, and how to leverage middleware to create them. We will use the Zend Expressive microframework to leverage components of Zend Framework, and other libraries, to quickly create awesome things without requiring an entire framework. Resources for reference and continued learning will also be shared.

Adam Culp

October 15, 2016
Tweet

More Decks by Adam Culp

Other Decks in Programming

Transcript

  1. 2 Zend Expressive Workshop • About me – OSS Contributor

    – PHP Certified – Zend Certification Advisory Board – PHP-Fig voting member (IBM i Toolkit) – Consultant at Zend Technologies – Organizer SoFloPHP (South Florida) – Organizer SunshinePHP (Miami) – Long distance (ultra) runner – Photography Enthusiast – Judo Black Belt Instructor
  2. 3 Zend Expressive Workshop • About me – OSS Contributor

    – PHP Certified – Zend Certification Advisory Board – PHP-Fig voting member (IBM i Toolkit) – Consultant at Zend Technologies – Organizer SoFloPHP (South Florida) – Organizer SunshinePHP (Miami) – Long distance (ultra) runner – Photography Enthusiast – Judo Black Belt Instructor PHP Ninja!!!
  3. 5 Zend Expressive Workshop • Frameworks Suck – Complicated •

    Routing • Databases • Connectivity • Communication (HTTP, API) • Information Container • GUI (html, javascript, templates, CSS,) • Errors and Exceptions • Validation and Cleansing Data • State
  4. 6 Zend Expressive Workshop • Frameworks Web Applications Suck –

    Complicated • Routing • Databases • Connectivity • Communication (HTTP, API) • Information Container • GUI (html, javascript, templates, CSS,) • Errors and Exceptions • Validation and Cleansing Data • State
  5. 8 Zend Expressive Workshop • Microservice – All the buzz

    is “microservices”. – ...complex applications are composed of small, independent processes communicating with each other using language-agnostic APIs. These services are small building blocks, highly decoupled and focused on doing a small task, facilitating a modular approach to system-building. – Wikipedia
  6. 9 Zend Expressive Workshop • But in PHP... – How

    to keep microservices light? – Microservices shouldn’t be heavy I’m a Microservice!!!
  7. 10 Zend Expressive Workshop • Full Stack Frameworks Suck –

    Heavy and bloated – “Kitchen Sink” – “You don’t have to use everything, but its there...”
  8. 11 Zend Expressive Workshop • Need For Speed – What

    does a microservice “need”? • HTTP message layer • Routing capabilities • Dependency injection – Testable – Swappable pieces • Templating – Optional (APIs may not need it, except documentation)
  9. 12 Zend Expressive Workshop • PHP Ecosystem Facilitators – PHP

    7 – Microframeworks – Libraries – Components – Containers – Composer
  10. 13 Zend Expressive Workshop • All The Things!!! – So

    many tools: Monolog Whoops Flysystem IBMiToolkit OAuth2 Server https://github.com/ziadoz/awesome-php
  11. 14 Zend Expressive Workshop • Communication Sucks – Say what!?!

    Monolog Whoops Flysystem IBMiToolkit OAuth2 Server
  12. 15 Zend Expressive Workshop • PSR-7 Doesn’t Suck – Part

    of PHP-Fig.org recommendations – HTTP Messages • Request from client to server • Response from server to client – Interfaces • Psr\Http\Message\MessageInterface – Psr\Http\Message\RequestInterface • Psr\Http\Message\ServerRequestInterface – Psr\Http\Message\ResponseInterface • Psr\Http\Message\StreamInterface • Psr\Http\Message\UploadFileInterface • Psr\Http\Message\UriInterface
  13. 16 Zend Expressive Workshop • Middleware – ...Middleware makes it

    easier for software developers to implement communication and input/output, so they can focus on the specific purpose of their application. – Wikipedia – Lighter applications (only what is needed) – Composed of layers
  14. 17 Zend Expressive Workshop • Zend Expressive – Microframework built

    around middleware – Very lean runtime – Built to consume PSR-7 – Use for building: • APIs • Web applications • Single page sites – Choose your own stack – Great documentation • https://zendframework.github.io/zend-expressive/
  15. 20 Zend Expressive Workshop • Composer Install Script – Minimal

    skeleton or full*? • With or without samples
  16. 21 Zend Expressive Workshop • Composer Install Script – Router

    options • Aura.Router • FastRoute* • Zend Router
  17. 22 Zend Expressive Workshop • Composer Install Script – Container

    options: (container interop) • Aura.Di • Pimple • Zend ServiceManager*
  18. 23 Zend Expressive Workshop • Composer Install Script – Template

    engine options: • Plates • Twig • Zend View • None*
  19. 25 Zend Expressive Workshop • Lab 01 – Install Zend

    Expressive – From within the VM install Zend Expressive • At ‘/home/vagrant/workspace/’ delete the ‘expressive’ folder • Composer is globally installed in the VM, enabling easy project creation. (stick to the defaults) $ composer create-project zendframework/zend-expressive- skeleton expressive • Verify that Zend Expressive Skeleton was properly installed. http://localhost then click on the Expressive link. →
  20. 29 Zend Expressive Workshop • Middleware Addition Approaches – Currently

    uses a config-driven approach to creating/using middleware • Middleware added to services through configuration – With version 1.1 of Zend Expressive the “recommended” will be programmatic/explicit approach versus config-driven. • Middleware information driven by pipes • More on this later – In this workshop the config-driven approach is used in examples
  21. 32 Zend Expressive Workshop • Container Creation – We specified

    Zend ServiceManager (/config/container.php)
  22. 34 Zend Expressive Workshop • Load Dependencies – Items to

    be called as middleware in routes. (/config/autoload/routes.global.php)
  23. 35 Zend Expressive Workshop • Load Routes – Matches path

    to middleware (Dependencies shown earlier) (/config/autoload/routes.global.php cont’d)
  24. 36 Zend Expressive Workshop • Ping Action Anatomy – Creates

    raw JSON response (/src/App/Action/PingAction.php)
  25. 38 Zend Expressive Workshop • Lab 02 – REST Test

    using HTTPie – Within the VM • We will use HTTPie from the command line instead of raw cURL to make requests. • Make a request to the existing ping action we analyzed: $ http http://expressive/api/ping • If doing this from the host browser the URL would be different: $ http http://expressive:8081/api/ping • Observe the response: – Note the Header information – Note the json response object
  26. 39 Zend Expressive Workshop • Lab 02 – REST Test

    using HTTPie (cont’d) – Within the VM • Observe the response: – Note the Header information – Note the json response object
  27. 41 Zend Expressive Workshop • Header Middleware – Create class

    for new middleware (or include someone else’s)
  28. 42 Zend Expressive Workshop • Header Middleware – The class

    to include the very important header (/src/App/Middleware/TheClacksMiddleware.php)
  29. 43 Zend Expressive Workshop • Header Middleware – Add the

    middleware to the container – Set it to always be included (/config/autoload/middleware-pipeline.global.php)
  30. 44 Zend Expressive Workshop • Header Middleware – Header for

    every call now carries our important message
  31. 45 Zend Expressive Workshop • Lab 03 – Create a

    Middleware – Create middleware to add content into ALL response headers • Add an appropriately named middleware class. (Example: TheClacksMiddleware) – Define the namespace (Example: ‘App\Middleware’) – Use Psr\Http\Message\ResponseInterface and ServerRequestInterface. – Return the response withHeader. • Add the new middleware into our middleware services. Remember we want it to ALL responses. • Verify NOTE: Refer to the expressive-final application if you need hints
  32. 47 Zend Expressive Workshop • Database Connected Example With Zend

    Db – First we need a database connection. • Will use Zend-Db for this example, but could be anything. • Composer to the rescue!
  33. 48 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Specify adapter (provided by Zend/Db/ConfigProvider() in this case) (/config/autoload/db.global.php)
  34. 49 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Provide local/instance configuration • This would be driver and credentials • (credentials not needed with sqlite) (/config/autoload/db.local.php)
  35. 50 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Create the action (view 1 of 2 - constructor) (/src/App/Action/UserListAction.php)
  36. 51 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Create the action (view 2 of 2 - __invoke method) (/src/App/Action/UserListAction.php cont’d)
  37. 52 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Create a factory to pass items needed by the action (/src/App/Action/UserListFactory.php)
  38. 53 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Add the new action to dependencies (/config/autoload/routes.global.php)
  39. 54 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Add the new route to dependencies (/config/autoload/routes.global.php cont’d)
  40. 55 Zend Expressive Workshop • Database Connected Example With Zend

    Db – Create the view template (/templates/app/user-list.phtml)
  41. 57 Zend Expressive Workshop • Lab 04 – Database Connected

    Middleware – Create a User middleware allowing management of user records in a database using Zend Db • Using Composer require dependency ‘zendframework/zend-db:2.8.*’ • Create an autoload global config file to provide Zend/Db/ConfigProvider • Create an autoload local config to provide a db container supplying the location to the users.db Sqlite database in the /data directory • Add an appropriately named middleware class (Example: UserListAction) – Define the namespace (Example: ‘App\Action’) – Use Psr\Http\Message\ResponseInterface, ServerRequestInterface, Zend\Diactoros\Response\HtmlResponse, Zend\Expressive\Template, and Zend\Db\Adapter\Adapter. – Define $template and $adapter fields for those objects
  42. 58 Zend Expressive Workshop • Lab 04 – Database Connected

    Middleware (Cont’d) – Create a User middleware (Cont’d • Add a middleware class (Cont’d) – Add a constructor to receive/set $template and $adapter • Typehint $template with Template\TemplateRendererInterface – Add an invoke method leveraging Server\RequestInterface, ResponseInterface, and $next as callable. – Using the Zend Db adapter create the query for Sqlite. • For Sqlite this involves defining a statement, then executing – Return the HtmlResponse rendering the view template. • Add a factory class to prepare the items needed by the Action just created – Use Interop\Container\ContainerInterface, Zend\Expressive\Template\TemplateRendererInterface, and Zend\Db\Adapter\AdapterInterface.
  43. 59 Zend Expressive Workshop • Lab 04 – Database Connected

    Middleware (Cont’d) – Create a User middleware (Cont’d • Add a factory class (Cont’d) – Define the namespace (Example: ‘App\Action’) – In the invoke() method typehint the $container argument using ContainerInterface. – Gain the $template if the $container has the TemplateRenderInterface. – Gain the DB $adapter also from the $container using AdapterInterface. – Return an instantiation of the Action class created earlier by passing the $template and $adapter. • Add the factory to the dependencies in the global routes. • Add a route to access the new middleware • Create a view template to display the user results.
  44. 61 Zend Expressive Workshop • Lab 05 – Create Moar

    Middleware – Create a uuid middleware to add content into all response headers • Using Composer add a dependency ‘ramsey/uuid’ • Add an appropriately named middleware class. (Example: UuidMiddleware) – Define the namespace (Example: ‘App\Middleware’) – Use Psr\Http\Message\ResponseInterface, ServerRequestInterface, and Ramsey\Uuid\Uuid (and maybe Ramsey\Uuid\Exception\UnsatisfiedDependencyException). – Return a uuid in the response withHeader. • Add the new middleware into our middleware services. Remember we want it to ALL responses. • Verify
  45. 62 Zend Expressive Workshop • Lab 05 – Create Moar

    Middleware (cont’d) – Continuing… Create middleware to add response time to ALL response headers • Add an appropriately named middleware class. (Example: RequestTimeMiddleware) – Define the namespace (Example: ‘App\Middleware’) – Use Psr\Http\Message\ResponseInterface and ServerRequestInterface. – Create code returning the time the request took – Return the response withHeader. • Add the new middleware into our middleware services. Remember we want it to ALL responses. • Verify NOTE: Refer to the expressive-final application if you need hints
  46. 64 Zend Expressive Workshop • Database Connected Example With Doctrine

    – First we need a database connection. • Will use Doctrine DBAL for this example, but could be anything. • Composer to the rescue!
  47. 65 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Provide local/instance configuration • This would be driver and credentials • (credentials not needed with sqlite) (/config/autoload/dbal.local.php)
  48. 66 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Create the action (view 1 of 2 - constructor) (/src/App/Action/UserDbalListAction.php)
  49. 67 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Create the action (view 2 of 2 - __invoke method) (/src/App/Action/UserDbalListAction.php cont’d)
  50. 68 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Create a factory to pass items needed by the action (/src/App/Action/UserDbalListFactory.php)
  51. 69 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Add the new action to dependencies, as shown below for the previous action, but with the new namespace for this example (/config/autoload/routes.global.php)
  52. 70 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Add the new route to dependencies (/config/autoload/routes.global.php)
  53. 71 Zend Expressive Workshop • Database Connected Example With Doctrine

    – Create the view template (/templates/app/user-dbal-list.phtml)
  54. 73 Zend Expressive Workshop • Lab 06 – Database Connected

    Middleware – Create a User middleware allowing management of user records in a database using Doctrine Dbal • Using Composer require dependency ‘doctrine\dbal:2.5.*’ • Create an autoload local config to provide a doctrine-connection container supplying the location to the users.db sqlite database in the /data directory • Add an appropriately named middleware class (Example: UserDbalListAction) – Define the namespace (Example: ‘App\Action’) – Use Psr\Http\Message\ResponseInterface, ServerRequestInterface, Zend\Diactoros\Response\HtmlResponse, and Zend\Expressive\Template. – Define $template and $connection fields for those objects
  55. 74 Zend Expressive Workshop • Lab 06 – Database Connected

    Middleware (Cont’d) – Create a User middleware (Cont’d • Add a middleware class (Cont’d) – Add a constructor to receive/set $template and $connection • Typehint $template with Template\TemplateRendererInterface – Add an invoke method leveraging Server\RequestInterface, ResponseInterface, and $next as callable. – Using the Doctrine $connection create the query for Sqlite. – Return the HtmlResponse rendering the view template. • Add a factory class to prepare the items needed by the Action just created – Use Interop\Container\ContainerInterface, Zend\Expressive\Template\TemplateRendererInterface, and Doctrine\DBAL\DriverManager.
  56. 75 Zend Expressive Workshop • Lab 06 – Database Connected

    Middleware (Cont’d) – Create a User middleware (Cont’d • Add a factory class (Cont’d) – Define the namespace (Example: ‘App\Action’) – In the invoke() method typehint the $container argument using ContainerInterface. – Gain the $template if the $container has the TemplateRenderInterface. – Define the DB $credentials also from the $container and kick off Doctrine to return the $connection to users for the view to use. – Return an instantiation of the Action class created earlier by passing the $template and $connection. • Add the factory to the dependencies in the global routes. • Add a route to access the new middleware • Create a view template to display the user results.
  57. 77 Zend Expressive Workshop • Zend Expressive Skeleton Programmatic –

    Version 1.1 of Zend Expressive “recommended” approach to adding more middleware will be with a programmatic/explicit approach. • In Github the repo for expressive-final has an additional branch (name: programmatic) created by Matthew Weier O’Phinney, from the Zend Expressive team, showing the programmatic approach to everything in this workshop. • https://github.com/adamculp/expressive-workshop
  58. 78 Zend Expressive Workshop • Resources – Zend Expressive Site

    - http://zendframework.github.io/zend-expressive/ – MasterZendFramework - http://www.masterzendframework.com – Oscar Otero’s list https://github.com/oscarotero/psr7-middlewares – This github repo https://github.com/adamculp/expressive-workshop – Slides - http://www.slideshare.net/adamculp/zend-expressive-workshop – Code used for the workshop - https://github.com/adamculp/expressive- workshop – More to come!
  59. 79 Zend Expressive Workshop • With Zend Expressive: – Easy

    to build middleware – Lightweight, add what is really needed – Fast – no extra load – Microservices in PHP are better
  60. 80 Zend Expressive Workshop • Give Zend Expressive a Try...Today!!!

    – https://zendframework.github.io/zend-expressive/
  61. • Thank you! • Code at: https://github.com/adamculp/expressive-blastoff • Please rate

    at: https://joind.in/talk/ec545 Adam Culp http://www.rungeekradio.com http://www.geekyboy.com Twitter @adamculp