Slide 1

Slide 1 text

Zend Expressive Workshop By: Adam Culp Twitter: @adamculp https://joind.in/talk/ec545

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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!!!

Slide 4

Slide 4 text

4 Zend Expressive Workshop ● I Help Build The Web

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

7 Zend Expressive Workshop ● Buzzword Bingo – We will mention many buzzwords, but...

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

9 Zend Expressive Workshop ● But in PHP... – How to keep microservices light? – Microservices shouldn’t be heavy I’m a Microservice!!!

Slide 10

Slide 10 text

10 Zend Expressive Workshop ● Full Stack Frameworks Suck – Heavy and bloated – “Kitchen Sink” – “You don’t have to use everything, but its there...”

Slide 11

Slide 11 text

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)

Slide 12

Slide 12 text

12 Zend Expressive Workshop ● PHP Ecosystem Facilitators – PHP 7 – Microframeworks – Libraries – Components – Containers – Composer

Slide 13

Slide 13 text

13 Zend Expressive Workshop ● All The Things!!! – So many tools: Monolog Whoops Flysystem IBMiToolkit OAuth2 Server https://github.com/ziadoz/awesome-php

Slide 14

Slide 14 text

14 Zend Expressive Workshop ● Communication Sucks – Say what!?! Monolog Whoops Flysystem IBMiToolkit OAuth2 Server

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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/

Slide 18

Slide 18 text

18 Zend Expressive Workshop ● Composer Install Script – Done “right” from the start

Slide 19

Slide 19 text

19 Zend Expressive Workshop ● Composer Install Script

Slide 20

Slide 20 text

20 Zend Expressive Workshop ● Composer Install Script – Minimal skeleton or full*? ● With or without samples

Slide 21

Slide 21 text

21 Zend Expressive Workshop ● Composer Install Script – Router options ● Aura.Router ● FastRoute* ● Zend Router

Slide 22

Slide 22 text

22 Zend Expressive Workshop ● Composer Install Script – Container options: (container interop) ● Aura.Di ● Pimple ● Zend ServiceManager*

Slide 23

Slide 23 text

23 Zend Expressive Workshop ● Composer Install Script – Template engine options: ● Plates ● Twig ● Zend View ● None*

Slide 24

Slide 24 text

24 Zend Expressive Workshop ● Composer Install Script – Error handler options: ● Whoops* ● None

Slide 25

Slide 25 text

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. →

Slide 26

Slide 26 text

26 Zend Expressive Workshop ● Skeleton Application

Slide 27

Slide 27 text

27 Zend Expressive Workshop ● Structure – Folder structure of Zend Expressive Skeleton

Slide 28

Slide 28 text

28 Zend Expressive Workshop ● Not MVC – Files and structure focused on Actions

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

30 Zend Expressive Workshop ● The Flow

Slide 31

Slide 31 text

31 Zend Expressive Workshop ● Initial File – Front controller (/public/index.php)

Slide 32

Slide 32 text

32 Zend Expressive Workshop ● Container Creation – We specified Zend ServiceManager (/config/container.php)

Slide 33

Slide 33 text

33 Zend Expressive Workshop ● Load Configs (/config/config.php)

Slide 34

Slide 34 text

34 Zend Expressive Workshop ● Load Dependencies – Items to be called as middleware in routes. (/config/autoload/routes.global.php)

Slide 35

Slide 35 text

35 Zend Expressive Workshop ● Load Routes – Matches path to middleware (Dependencies shown earlier) (/config/autoload/routes.global.php cont’d)

Slide 36

Slide 36 text

36 Zend Expressive Workshop ● Ping Action Anatomy – Creates raw JSON response (/src/App/Action/PingAction.php)

Slide 37

Slide 37 text

37 Zend Expressive Workshop ● JSON Response – Created by action

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

40 Zend Expressive Workshop ● Let’s Create a Middleware!!!

Slide 41

Slide 41 text

41 Zend Expressive Workshop ● Header Middleware – Create class for new middleware (or include someone else’s)

Slide 42

Slide 42 text

42 Zend Expressive Workshop ● Header Middleware – The class to include the very important header (/src/App/Middleware/TheClacksMiddleware.php)

Slide 43

Slide 43 text

43 Zend Expressive Workshop ● Header Middleware – Add the middleware to the container – Set it to always be included (/config/autoload/middleware-pipeline.global.php)

Slide 44

Slide 44 text

44 Zend Expressive Workshop ● Header Middleware – Header for every call now carries our important message

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

46 Zend Expressive Workshop ● Let’s Create a Database Connected Middleware!!! ● With Zend Db

Slide 47

Slide 47 text

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!

Slide 48

Slide 48 text

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)

Slide 49

Slide 49 text

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)

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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)

Slide 52

Slide 52 text

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)

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

55 Zend Expressive Workshop ● Database Connected Example With Zend Db – Create the view template (/templates/app/user-list.phtml)

Slide 56

Slide 56 text

56 Zend Expressive Workshop ● Database Connected Example With Zend Db – Rejoice!

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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.

Slide 59

Slide 59 text

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.

Slide 60

Slide 60 text

60 Zend Expressive Workshop ● Let’s Create Moar Middleware!!!

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

63 Zend Expressive Workshop ● Let’s Create a Database Connected Middleware!!! ● With Doctrine!!!

Slide 64

Slide 64 text

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!

Slide 65

Slide 65 text

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)

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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)

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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)

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

71 Zend Expressive Workshop ● Database Connected Example With Doctrine – Create the view template (/templates/app/user-dbal-list.phtml)

Slide 72

Slide 72 text

72 Zend Expressive Workshop ● Database Connected Example With Doctrine – Rejoice!

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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.

Slide 75

Slide 75 text

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.

Slide 76

Slide 76 text

76 Zend Expressive Workshop ● Let’s Use Programmatic!!!

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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!

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

80 Zend Expressive Workshop ● Give Zend Expressive a Try...Today!!! – https://zendframework.github.io/zend-expressive/

Slide 81

Slide 81 text

● 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