Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

APIs mit Zend\Expressive erstellen

96 Aufrufe

Veröffentlicht am

Das Zend Framework 3 bietet mit seiner MVC-Komponente und mit dem Nebenprojekt Apigility bereits verschiedene Möglichkeiten, ein RESTful API auf Basis von PHP zu entwickeln. Doch auch das neue Microframework Expressive ist für den Betrieb eines RESTful Web Services geeignet. In der simpelsten Variante reichen nach der Installation der Skeleton Application nur wenige Zeilen Code für ein REST-API. Durch das offene Konzept sind jedoch auch komplexere API-Anwendungen flexibel und ohne großen Frameworkballast zu entwickeln. In diesem Vortrag erfahren Sie alles Wissenswerte zu Expressive und dem Aufbau einer RESTful Anwendung mit PHP.

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

APIs mit Zend\Expressive erstellen

  1. 1. APIs mit ZendExpressive erstellenAPIs mit ZendExpressive erstellen
  2. 2. Ralf EggertRalf Eggert CEO Travello GmbH, PHP Entwickler,CEO Travello GmbH, PHP Entwickler, Zend Framework Trainer, Autor & Coach sowieZend Framework Trainer, Autor & Coach sowie Amazon Alexa Skill EntwicklerAmazon Alexa Skill Entwickler
  3. 3. Ralf EggertRalf Eggert 33 vonvon 5454 AgendaAgenda Teil 1: APIs mit dem Zend Framework Teil 2: Überblick ZendExpressive Teil 3: Einfache erste API erstellen Teil 4: API für Ausgabe von Kundendaten Teil 5: API zum Ändern von Kundendaten Teil 6: Ausblick in die Zukunft
  4. 4. Teil 1Teil 1 APIs mit dem Zend FrameworkAPIs mit dem Zend Framework
  5. 5. Ralf EggertRalf Eggert 55 vonvon 5454 Webservices mit dem ZF1Webservices mit dem ZF1
  6. 6. Ralf EggertRalf Eggert 66 vonvon 5454 Webservices mit dem ZF2Webservices mit dem ZF2
  7. 7. Ralf EggertRalf Eggert 77 vonvon 5454 Webservices mit Apigility 1Webservices mit Apigility 1
  8. 8. Ralf EggertRalf Eggert 88 vonvon 5454 Webservices mit Apigility 2Webservices mit Apigility 2
  9. 9. Ralf EggertRalf Eggert 99 vonvon 5454 Webservices mit ZendExpressiveWebservices mit ZendExpressive
  10. 10. Teil 2Teil 2 Überblick ZendExpressiveÜberblick ZendExpressive
  11. 11. Ralf EggertRalf Eggert 1111 vonvon 5454 Zend Framework KomponentenZend Framework Komponenten ZEND DIACTOROS ZENDSTRATIGILITY ZENDEXPRESSIVE HTTP MESSAGES / PSR-7 MIDDLEWARE / PSR-15 MIDDLEWARE APPLICATIONS
  12. 12. Ralf EggertRalf Eggert 1212 vonvon 5454 ZendExpressiveZendExpressive KomponentenKomponenten Router DI Container Template Renderer Error Handler Aura.Router FastRoute ZendRouter Weitere Router Aura.DI Pimple-interop Zend ServiceManager Weitere DI Container Plates Twig ZendView Weitere Template-Engines Whoops Weitere Error-Handler
  13. 13. Ralf EggertRalf Eggert 1313 vonvon 5454 InstallationInstallation
  14. 14. Ralf EggertRalf Eggert 1414 vonvon 5454 Klassischer HTTP RequestKlassischer HTTP Request CLIENT WEBSERVER HTTP REQUEST HTTP RESPONSE
  15. 15. Ralf EggertRalf Eggert 1515 vonvon 5454 Middleware-RequestMiddleware-Request HTTP Request HTTP Response Middleware-Pipeline
  16. 16. Ralf EggertRalf Eggert 1616 vonvon 5454 Middleware-PipelineMiddleware-Pipeline HTTP Request HTTP Response Routing Middleware Authorization Middleware Dispatching Middleware
  17. 17. Ralf EggertRalf Eggert 1717 vonvon 5454 Middleware-AktionenMiddleware-Aktionen HTTP Request HTTP Response Routing Middleware Action Middleware Authorization Middleware Dispatching Middleware
  18. 18. Ralf EggertRalf Eggert 1818 vonvon 5454 Beispiele für Action-MiddlewareBeispiele für Action-Middleware
  19. 19. Ralf EggertRalf Eggert 1919 vonvon 5454 BeispielanwendungBeispielanwendung https://github.com/RalfEggert/entwicklermagazin.api
  20. 20. Teil 3Teil 3 Einfache erste API erstellenEinfache erste API erstellen
  21. 21. Ralf EggertRalf Eggert 2121 vonvon 5454 Jeder API ihr eigenes ModulJeder API ihr eigenes Modul  config  data  public  module  App  Check  src  Action  CheckMethodAction.php  Router  RouterDelegatorFactory.php  ConfigProvider.php  test  vendor  composer.json ZendExpressive Modul
  22. 22. Ralf EggertRalf Eggert 2222 vonvon 5454 RoutingRouting <?php namespace CheckRouter; use CheckActionCheckMethodAction; use InteropContainerContainerInterface; use ZendExpressiveApplication; use ZendServiceManagerFactoryDelegatorFactoryInterface; class RouterDelegatorFactory implements DelegatorFactoryInterface { public function __invoke( ContainerInterface $container, $name, callable $callback, array $options = null ) { /** @var Application $app */ $app = $callback(); $app->route( '/check/method', CheckMethodAction::class, ['get', 'post', 'put', 'delete', 'patch'], 'check.method' ); return $app; } }
  23. 23. Ralf EggertRalf Eggert 2323 vonvon 5454 Action MiddlewareAction Middleware <?php namespace CheckAction; use InteropHttpServerMiddlewareDelegateInterface; use InteropHttpServerMiddlewareMiddlewareInterface; use PsrHttpMessageServerRequestInterface; use ZendDiactorosResponseJsonResponse; class CheckMethodAction implements MiddlewareInterface { public function process(ServerRequestInterface $request, DelegateInterface $delegate) { return new JsonResponse( [ 'check' => 'Der Check der HTTP Methode war erfolgreich.', 'method' => $request->getMethod(), ] ); } }
  24. 24. Ralf EggertRalf Eggert 2424 vonvon 5454 Check Method mit GET testenCheck Method mit GET testen
  25. 25. Ralf EggertRalf Eggert 2525 vonvon 5454 Check Method mit PATCH testenCheck Method mit PATCH testen
  26. 26. Ralf EggertRalf Eggert 2626 vonvon 5454 Check Method mit OPTIONS testenCheck Method mit OPTIONS testen
  27. 27. Ralf EggertRalf Eggert 2727 vonvon 5454 Middleware PipelineMiddleware Pipeline <?php namespace AppPipeline; use InteropContainerContainerInterface; use ZendExpressiveApplication; use ZendExpressiveHelperServerUrlMiddleware; use ZendExpressiveHelperUrlHelperMiddleware; use ZendExpressiveMiddlewareImplicitHeadMiddleware; use ZendExpressiveMiddlewareImplicitOptionsMiddleware; use ZendExpressiveMiddlewareNotFoundHandler; use ZendServiceManagerFactoryDelegatorFactoryInterface; use ZendStratigilityMiddlewareErrorHandler; class PipelineDelegatorFactory implements DelegatorFactoryInterface { public function __invoke(ContainerInterface $container, $name, callable $callback, $options) { $app = $callback(); $app->pipe(ErrorHandler::class); $app->pipe(ServerUrlMiddleware::class); $app->pipeRoutingMiddleware(); $app->pipe(ImplicitHeadMiddleware::class); $app->pipe(ImplicitOptionsMiddleware::class); $app->pipe(UrlHelperMiddleware::class); $app->pipeDispatchMiddleware(); $app->pipe(NotFoundHandler::class); return $app; } }
  28. 28. Ralf EggertRalf Eggert 2828 vonvon 5454 Schritte für erste APISchritte für erste API Eigenes Modul erstellen1 Routing anlegen2 Action Middleware anlegen3 API testen4 OPTIONS Abfrage5
  29. 29. Teil 4Teil 4 API für Ausgabe von KundendatenAPI für Ausgabe von Kundendaten
  30. 30. Ralf EggertRalf Eggert 3030 vonvon 5454 MySQL Datenbank einrichtenMySQL Datenbank einrichten
  31. 31. Ralf EggertRalf Eggert 3131 vonvon 5454 Doctrine ORM installierenDoctrine ORM installieren $ composer install dasprid/container-interop-doctrine
  32. 32. Ralf EggertRalf Eggert 3232 vonvon 5454 Kunden Entitätsklasse IKunden Entitätsklasse I <?php namespace CustomerEntity; use DoctrineORMMapping as ORM; use JsonSerializable; /** * @ORMEntity * @ORMTable(name="customer") */ class Customer implements JsonSerializable { /** * @ORMId * @ORMColumn(name="id", type="integer") * @ORMGeneratedValue(strategy="IDENTITY") * @var int */ private $id; /** * @ORMColumn(name="first_name", type="string", length=64) * @var string */ private $firstName; /** * @ORMColumn(name="last_name", type="string", length=64) * @var string */ private $lastName; /** * @ORMColumn(name="country", type="string", length=2) * @var string */ private $country;
  33. 33. Ralf EggertRalf Eggert 3333 vonvon 5454 Kunden Entitätsklasse IIKunden Entitätsklasse II class Customer implements JsonSerializable { /* ... */ public function __construct( int $id = null, string $firstName, string $lastName, string $country ) { $this->id = $id; $this->firstName = $firstName; $this->lastName = $lastName; $this->country = $country; } public function update(string $firstName, string $lastName, string $country) { $this->firstName = $firstName; $this->lastName = $lastName; $this->country = $country; } public function jsonSerialize(): array { return [ 'id' => $this->id, 'first_name' => $this->firstName, 'last_name' => $this->lastName, 'country' => $this->country, ]; } }
  34. 34. Ralf EggertRalf Eggert 3434 vonvon 5454 RoutingRouting <?php namespace CustomerRouter; use CustomerActionGetCollectionAction; use CustomerActionGetEntityAction; use InteropContainerContainerInterface; use ZendExpressiveApplication; use ZendServiceManagerFactoryDelegatorFactoryInterface; class RouterDelegatorFactory implements DelegatorFactoryInterface { public function __invoke( ContainerInterface $container, $name, callable $callback, array $options = null ) { /** @var Application $app */ $app = $callback(); $idConstraint = ['constraints' => ['id' => '[0-9]+']]; $app->get('/customer', GetCollectionAction::class, 'customer-get-collection'); $app->get('/customer/{id}', GetEntityAction::class, 'customer-get-entity') ->setOptions($idConstraint); return $app; } }
  35. 35. Ralf EggertRalf Eggert 3535 vonvon 5454 Action MiddlewareAction Middleware <?php namespace CustomerAction; use CustomerEntityCustomer; use DoctrineORMEntityManager; use InteropHttpServerMiddlewareDelegateInterface; use InteropHttpServerMiddlewareMiddlewareInterface; use PsrHttpMessageServerRequestInterface; use ZendDiactorosResponseJsonResponse; class GetCollectionAction implements MiddlewareInterface { private $entityManager; public function __construct(EntityManager $entityManager) { $this->entityManager = $entityManager; } public function process(ServerRequestInterface $request, DelegateInterface $delegate) { $customerRepository = $this->entityManager->getRepository(Customer::class); return new JsonResponse( [ 'collection' => $customerRepository->findAll(), ] ); } }
  36. 36. Ralf EggertRalf Eggert 3636 vonvon 5454 Factory für Action MiddlewareFactory für Action Middleware <?php namespace CustomerAction; use DoctrineORMEntityManager; use InteropContainerContainerInterface; use ZendServiceManagerFactoryFactoryInterface; class AbstractActionFactory implements FactoryInterface { public function __invoke( ContainerInterface $container, $requestedName, array $options = null ) { /** @var EntityManager $entityManager */ $entityManager = $container->get('doctrine.entity_manager.orm_default'); return new $requestedName($entityManager); } }
  37. 37. Ralf EggertRalf Eggert 3737 vonvon 5454 Kunden-API für Liste testenKunden-API für Liste testen
  38. 38. Ralf EggertRalf Eggert 3838 vonvon 5454 Kunden-API für Entität testenKunden-API für Entität testen
  39. 39. Ralf EggertRalf Eggert 3939 vonvon 5454 Schritte für Ausgabe KundendatenSchritte für Ausgabe Kundendaten MySQL Datenbank einrichten1 Doctrine per Composer installieren2 Entitätsklasse für Kunden3 Routing definieren4 Action Middleware implementieren5 Factory für Action Middleware6 API testen7
  40. 40. Teil 5Teil 5 API zum Ändern von KundendatenAPI zum Ändern von Kundendaten
  41. 41. Ralf EggertRalf Eggert 4141 vonvon 5454 RoutingRouting <?php namespace CustomerRouter; /* ... */ use CustomerActionDeleteEntityAction; use CustomerActionPostEntityAction; use CustomerActionPutEntityAction; class RouterDelegatorFactory implements DelegatorFactoryInterface { public function __invoke( ContainerInterface $container, $name, callable $callback, array $options = null ) { /** @var Application $app */ $app = $callback(); $idConstraint = ['constraints' => ['id' => '[0-9]+']]; /* ... */ $app->post('/customer', PostEntityAction::class, 'customer-post-entity'); $app->put('/customer/{id}', PutEntityAction::class, 'customer-put-entity') ->setOptions($idConstraint); $app->delete('/customer/{id}', DeleteEntityAction::class, 'customer-delete-entity') ->setOptions($idConstraint); return $app; } }
  42. 42. Ralf EggertRalf Eggert 4242 vonvon 5454 Action Middleware für POSTAction Middleware für POST <?php namespace CustomerAction; use CustomerEntityCustomer; use DoctrineORMEntityManager; use InteropHttpServerMiddlewareDelegateInterface; use InteropHttpServerMiddlewareMiddlewareInterface; use PsrHttpMessageServerRequestInterface; use ZendDiactorosResponseJsonResponse; class PostEntityAction implements MiddlewareInterface { private $entityManager; public function __construct(EntityManager $entityManager) { $this->entityManager = $entityManager; } public function process(ServerRequestInterface $request, DelegateInterface $delegate) { $data = (array)json_decode($request->getBody()->getContents()); $customer = new Customer(null, $data['first_name'], $data['last_name'], $data['country']); $this->entityManager->persist($customer); $this->entityManager->flush(); return new JsonResponse(['entity' => $customer], 201); } }
  43. 43. Ralf EggertRalf Eggert 4343 vonvon 5454 Action Middleware für PUTAction Middleware für PUT <?php namespace CustomerAction; /* ... */ class PutEntityAction implements MiddlewareInterface { public function process(ServerRequestInterface $request, DelegateInterface $delegate) { $customerRepository = $this->entityManager->getRepository(Customer::class); $id = $request->getAttribute('id'); $data = (array) json_decode($request->getBody()->getContents()); $customer = $customerRepository->find($id); if (!$customer) { return new JsonResponse([], 404); } $customer->update($data['first_name'], $data['last_name'], $data['country']); $this->entityManager->persist($customer); $this->entityManager->flush(); return new JsonResponse(['entity' => $customer]); } }
  44. 44. Ralf EggertRalf Eggert 4444 vonvon 5454 Kunden-API mit POST testenKunden-API mit POST testen
  45. 45. Ralf EggertRalf Eggert 4545 vonvon 5454 Kunden-API mit PUT testenKunden-API mit PUT testen
  46. 46. Ralf EggertRalf Eggert 4646 vonvon 5454 Schritte zum Ändern der KundenSchritte zum Ändern der Kunden Routing für POST, PUT und DELETE1 Action Middleware implementieren2 API testen3
  47. 47. Teil 6Teil 6 Ausblick in die ZukunftAusblick in die Zukunft
  48. 48. Ralf EggertRalf Eggert 4848 vonvon 5454 Apigility 2 mit ZendExpressiveApigility 2 mit ZendExpressive
  49. 49. Ralf EggertRalf Eggert 4949 vonvon 5454 Komponente ZendExpressiveHalKomponente ZendExpressiveHal https://docs.zendframework.com/zend-expressive-hal/
  50. 50. Ralf EggertRalf Eggert 5050 vonvon 5454 Komponente Problem DetailsKomponente Problem Details https://github.com/zendframework/zend-problem-details
  51. 51. Ralf EggertRalf Eggert 5151 vonvon 5454 Neues AuthentifzierungsmodulNeues Authentifzierungsmodul https://discourse.zendframework.com/t/rfc-authentication-module-for-expressive-and-psr-7-apps/273
  52. 52. Ralf EggertRalf Eggert 5252 vonvon 5454 Neues AutorisierungsmodulNeues Autorisierungsmodul https://discourse.zendframework.com/t/rfc-authorization-module-for-expressive-and-psr-7/239
  53. 53. Fragen?Fragen?
  54. 54. Fragen anFragen an ralf@travello.deralf@travello.de Im Netz ww.travello.de oder www.travello.audioIm Netz ww.travello.de oder www.travello.audio Danke!Danke!

×