SlideShare ist ein Scribd-Unternehmen logo
APIs mit ZendExpressive erstellenAPIs mit ZendExpressive erstellen
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
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
Teil 1Teil 1
APIs mit dem Zend FrameworkAPIs mit dem Zend Framework
Ralf EggertRalf Eggert 55 vonvon 5454
Webservices mit dem ZF1Webservices mit dem ZF1
Ralf EggertRalf Eggert 66 vonvon 5454
Webservices mit dem ZF2Webservices mit dem ZF2
Ralf EggertRalf Eggert 77 vonvon 5454
Webservices mit Apigility 1Webservices mit Apigility 1
Ralf EggertRalf Eggert 88 vonvon 5454
Webservices mit Apigility 2Webservices mit Apigility 2
Ralf EggertRalf Eggert 99 vonvon 5454
Webservices mit ZendExpressiveWebservices mit ZendExpressive
Teil 2Teil 2
Überblick ZendExpressiveÜberblick ZendExpressive
Ralf EggertRalf Eggert 1111 vonvon 5454
Zend Framework KomponentenZend Framework Komponenten
ZEND
DIACTOROS
ZENDSTRATIGILITY
ZENDEXPRESSIVE
HTTP MESSAGES / PSR-7
MIDDLEWARE / PSR-15
MIDDLEWARE
APPLICATIONS
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
Ralf EggertRalf Eggert 1313 vonvon 5454
InstallationInstallation
Ralf EggertRalf Eggert 1414 vonvon 5454
Klassischer HTTP RequestKlassischer HTTP Request
CLIENT WEBSERVER
HTTP
REQUEST
HTTP
RESPONSE
Ralf EggertRalf Eggert 1515 vonvon 5454
Middleware-RequestMiddleware-Request
HTTP
Request
HTTP
Response
Middleware-Pipeline
Ralf EggertRalf Eggert 1616 vonvon 5454
Middleware-PipelineMiddleware-Pipeline
HTTP
Request
HTTP
Response
Routing
Middleware
Authorization
Middleware
Dispatching
Middleware
Ralf EggertRalf Eggert 1717 vonvon 5454
Middleware-AktionenMiddleware-Aktionen
HTTP
Request
HTTP
Response
Routing
Middleware
Action
Middleware
Authorization
Middleware
Dispatching
Middleware
Ralf EggertRalf Eggert 1818 vonvon 5454
Beispiele für Action-MiddlewareBeispiele für Action-Middleware
Ralf EggertRalf Eggert 1919 vonvon 5454
BeispielanwendungBeispielanwendung
https://github.com/RalfEggert/entwicklermagazin.api
Teil 3Teil 3
Einfache erste API erstellenEinfache erste API erstellen
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
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;
}
}
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(),
]
);
}
}
Ralf EggertRalf Eggert 2424 vonvon 5454
Check Method mit GET testenCheck Method mit GET testen
Ralf EggertRalf Eggert 2525 vonvon 5454
Check Method mit PATCH testenCheck Method mit PATCH testen
Ralf EggertRalf Eggert 2626 vonvon 5454
Check Method mit OPTIONS testenCheck Method mit OPTIONS testen
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;
}
}
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
Teil 4Teil 4
API für Ausgabe von KundendatenAPI für Ausgabe von Kundendaten
Ralf EggertRalf Eggert 3030 vonvon 5454
MySQL Datenbank einrichtenMySQL Datenbank einrichten
Ralf EggertRalf Eggert 3131 vonvon 5454
Doctrine ORM installierenDoctrine ORM installieren
$ composer install dasprid/container-interop-doctrine
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;
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,
];
}
}
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;
}
}
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(),
]
);
}
}
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);
}
}
Ralf EggertRalf Eggert 3737 vonvon 5454
Kunden-API für Liste testenKunden-API für Liste testen
Ralf EggertRalf Eggert 3838 vonvon 5454
Kunden-API für Entität testenKunden-API für Entität testen
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
Teil 5Teil 5
API zum Ändern von KundendatenAPI zum Ändern von Kundendaten
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;
}
}
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);
}
}
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]);
}
}
Ralf EggertRalf Eggert 4444 vonvon 5454
Kunden-API mit POST testenKunden-API mit POST testen
Ralf EggertRalf Eggert 4545 vonvon 5454
Kunden-API mit PUT testenKunden-API mit PUT testen
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
Teil 6Teil 6
Ausblick in die ZukunftAusblick in die Zukunft
Ralf EggertRalf Eggert 4848 vonvon 5454
Apigility 2 mit ZendExpressiveApigility 2 mit ZendExpressive
Ralf EggertRalf Eggert 4949 vonvon 5454
Komponente ZendExpressiveHalKomponente ZendExpressiveHal
https://docs.zendframework.com/zend-expressive-hal/
Ralf EggertRalf Eggert 5050 vonvon 5454
Komponente Problem DetailsKomponente Problem Details
https://github.com/zendframework/zend-problem-details
Ralf EggertRalf Eggert 5151 vonvon 5454
Neues AuthentifzierungsmodulNeues Authentifzierungsmodul
https://discourse.zendframework.com/t/rfc-authentication-module-for-expressive-and-psr-7-apps/273
Ralf EggertRalf Eggert 5252 vonvon 5454
Neues AutorisierungsmodulNeues Autorisierungsmodul
https://discourse.zendframework.com/t/rfc-authorization-module-for-expressive-and-psr-7/239
Fragen?Fragen?
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!

Weitere ähnliche Inhalte

Ähnlich wie APIs mit Zend\Expressive erstellen

Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
Jens Siebert
 
Rack-Middleware
Rack-MiddlewareRack-Middleware
Rack-Middleware
Hussein Morsy
 
Testing tools
Testing toolsTesting tools
Testing tools
Sebastian Springer
 
Migration zum Zend Framework 3
Migration zum Zend Framework 3Migration zum Zend Framework 3
Migration zum Zend Framework 3
Ralf Eggert
 
Source Code Analyse - Ein praktikabler Ansatz
Source Code Analyse - Ein praktikabler AnsatzSource Code Analyse - Ein praktikabler Ansatz
Source Code Analyse - Ein praktikabler Ansatz
Marc Ruef
 
Source-Code-Analyse – ein praktikabler Ansatz
Source-Code-Analyse – ein praktikabler AnsatzSource-Code-Analyse – ein praktikabler Ansatz
Source-Code-Analyse – ein praktikabler Ansatz
Digicomp Academy AG
 
Vorstellung Open Social Ipc 2009
Vorstellung Open Social Ipc 2009Vorstellung Open Social Ipc 2009
Vorstellung Open Social Ipc 2009fruske
 
OpenSocial und Apache Shindig
OpenSocial und Apache ShindigOpenSocial und Apache Shindig
OpenSocial und Apache Shindig
Mayflower GmbH
 
FLOW3-Workshop F3X12
FLOW3-Workshop F3X12FLOW3-Workshop F3X12
FLOW3-Workshop F3X12
Karsten Dambekalns
 
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
Manfred Steyer
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
gedoplan
 
Open icf (open identity connector framework) @ forgerock deutsch
Open icf (open identity connector framework) @ forgerock   deutschOpen icf (open identity connector framework) @ forgerock   deutsch
Open icf (open identity connector framework) @ forgerock deutsch
Hanns Nolan
 
Die Kunst Des Software Design
Die Kunst Des Software DesignDie Kunst Des Software Design
Die Kunst Des Software Design
Stephan Schmidt
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershellCreasoft AG
 
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperrOracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
Gunther Pippèrr
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
gedoplan
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
msebel
 
IPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
IPC 2017 - Legacy-Anwendungen mit Expressive modernisierenIPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
IPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
Ralf Eggert
 

Ähnlich wie APIs mit Zend\Expressive erstellen (20)

Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Rack-Middleware
Rack-MiddlewareRack-Middleware
Rack-Middleware
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Migration zum Zend Framework 3
Migration zum Zend Framework 3Migration zum Zend Framework 3
Migration zum Zend Framework 3
 
Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1Web Entwicklung mit PHP - Teil 1
Web Entwicklung mit PHP - Teil 1
 
Source Code Analyse - Ein praktikabler Ansatz
Source Code Analyse - Ein praktikabler AnsatzSource Code Analyse - Ein praktikabler Ansatz
Source Code Analyse - Ein praktikabler Ansatz
 
Source-Code-Analyse – ein praktikabler Ansatz
Source-Code-Analyse – ein praktikabler AnsatzSource-Code-Analyse – ein praktikabler Ansatz
Source-Code-Analyse – ein praktikabler Ansatz
 
Vorstellung Open Social Ipc 2009
Vorstellung Open Social Ipc 2009Vorstellung Open Social Ipc 2009
Vorstellung Open Social Ipc 2009
 
OpenSocial und Apache Shindig
OpenSocial und Apache ShindigOpenSocial und Apache Shindig
OpenSocial und Apache Shindig
 
FLOW3-Workshop F3X12
FLOW3-Workshop F3X12FLOW3-Workshop F3X12
FLOW3-Workshop F3X12
 
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
.NET Summit 2016 München: EcmaScript 2015+ with TypeScript
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
 
Open icf (open identity connector framework) @ forgerock deutsch
Open icf (open identity connector framework) @ forgerock   deutschOpen icf (open identity connector framework) @ forgerock   deutsch
Open icf (open identity connector framework) @ forgerock deutsch
 
Die Kunst Des Software Design
Die Kunst Des Software DesignDie Kunst Des Software Design
Die Kunst Des Software Design
 
Creasoft - Windows powershell
Creasoft - Windows powershellCreasoft - Windows powershell
Creasoft - Windows powershell
 
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperrOracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
Oracle oem 12c_plugin_development-doag-konferenz_11_2014_print_gunther_pipperr
 
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
Das Runde muss in das Eckige - Java-Anwendungen für Kubernetes entwickeln und...
 
PHP Sucks?!
PHP Sucks?!PHP Sucks?!
PHP Sucks?!
 
Prototype 1.7
Prototype 1.7Prototype 1.7
Prototype 1.7
 
IPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
IPC 2017 - Legacy-Anwendungen mit Expressive modernisierenIPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
IPC 2017 - Legacy-Anwendungen mit Expressive modernisieren
 

Mehr von Ralf Eggert

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)
Ralf Eggert
 
ChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heuteChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heute
Ralf Eggert
 
Der ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 EditionDer ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 Edition
Ralf Eggert
 
PHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickelnPHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickeln
Ralf Eggert
 
Alexa, what's next?
Alexa, what's next?Alexa, what's next?
Alexa, what's next?
Ralf Eggert
 
Alexa, wohin geht die Reise
Alexa, wohin geht die ReiseAlexa, wohin geht die Reise
Alexa, wohin geht die Reise
Ralf Eggert
 
8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup
Ralf Eggert
 
Welcome Bixby
Welcome BixbyWelcome Bixby
Welcome Bixby
Ralf Eggert
 
Alexa Skill Maintenance
Alexa Skill MaintenanceAlexa Skill Maintenance
Alexa Skill Maintenance
Ralf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
Ralf Eggert
 
Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?
Ralf Eggert
 
Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100
Ralf Eggert
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
Ralf Eggert
 
Alexa for Hospitality
Alexa for HospitalityAlexa for Hospitality
Alexa for Hospitality
Ralf Eggert
 
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Ralf Eggert
 
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche SprachanwendungenFortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Ralf Eggert
 
Die sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice ProjekteDie sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice Projekte
Ralf Eggert
 
Künstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitKünstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und Wirklichkeit
Ralf Eggert
 
Multi-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon AlexaMulti-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon Alexa
Ralf Eggert
 

Mehr von Ralf Eggert (20)

PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)PHP Rewrite: Do the right thing (IPC Berlin 2024)
PHP Rewrite: Do the right thing (IPC Berlin 2024)
 
ChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heuteChatGPT: unser täglich' Bot gib uns heute
ChatGPT: unser täglich' Bot gib uns heute
 
Der ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 EditionDer ultimative PHP Framework Vergleich 2023 Edition
Der ultimative PHP Framework Vergleich 2023 Edition
 
PHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickelnPHP Module als Rundum-Sorglos-Pakete entwickeln
PHP Module als Rundum-Sorglos-Pakete entwickeln
 
Alexa, what's next?
Alexa, what's next?Alexa, what's next?
Alexa, what's next?
 
Alexa, wohin geht die Reise
Alexa, wohin geht die ReiseAlexa, wohin geht die Reise
Alexa, wohin geht die Reise
 
8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup8. Hamburg Voice Interface Meetup
8. Hamburg Voice Interface Meetup
 
Welcome Bixby
Welcome BixbyWelcome Bixby
Welcome Bixby
 
Alexa Skill Maintenance
Alexa Skill MaintenanceAlexa Skill Maintenance
Alexa Skill Maintenance
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
 
Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?Alexa Skills und PHP? Passt das zusammen?
Alexa Skills und PHP? Passt das zusammen?
 
Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100Mit Jovo von 0 auf 100
Mit Jovo von 0 auf 100
 
Vom Zend Framework zu Laminas
Vom Zend Framework zu LaminasVom Zend Framework zu Laminas
Vom Zend Framework zu Laminas
 
Alexa for Hospitality
Alexa for HospitalityAlexa for Hospitality
Alexa for Hospitality
 
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
Alexa, lass uns Geld verdienen – fünf Geschäftsmodelle, die wirklich funktion...
 
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche SprachanwendungenFortgeschrittene Techniken für erfolgreiche Sprachanwendungen
Fortgeschrittene Techniken für erfolgreiche Sprachanwendungen
 
Die sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice ProjekteDie sieben Projektphasen für Voice Projekte
Die sieben Projektphasen für Voice Projekte
 
Künstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und WirklichkeitKünstliche Intelligenz – Traum und Wirklichkeit
Künstliche Intelligenz – Traum und Wirklichkeit
 
Multi-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon AlexaMulti-Modal Voice Development with Amazon Alexa
Multi-Modal Voice Development with Amazon Alexa
 

APIs mit Zend\Expressive erstellen

  • 1. APIs mit ZendExpressive erstellenAPIs mit ZendExpressive erstellen
  • 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. 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. Teil 1Teil 1 APIs mit dem Zend FrameworkAPIs mit dem Zend Framework
  • 5. Ralf EggertRalf Eggert 55 vonvon 5454 Webservices mit dem ZF1Webservices mit dem ZF1
  • 6. Ralf EggertRalf Eggert 66 vonvon 5454 Webservices mit dem ZF2Webservices mit dem ZF2
  • 7. Ralf EggertRalf Eggert 77 vonvon 5454 Webservices mit Apigility 1Webservices mit Apigility 1
  • 8. Ralf EggertRalf Eggert 88 vonvon 5454 Webservices mit Apigility 2Webservices mit Apigility 2
  • 9. Ralf EggertRalf Eggert 99 vonvon 5454 Webservices mit ZendExpressiveWebservices mit ZendExpressive
  • 10. Teil 2Teil 2 Überblick ZendExpressiveÜberblick ZendExpressive
  • 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. 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. Ralf EggertRalf Eggert 1313 vonvon 5454 InstallationInstallation
  • 14. Ralf EggertRalf Eggert 1414 vonvon 5454 Klassischer HTTP RequestKlassischer HTTP Request CLIENT WEBSERVER HTTP REQUEST HTTP RESPONSE
  • 15. Ralf EggertRalf Eggert 1515 vonvon 5454 Middleware-RequestMiddleware-Request HTTP Request HTTP Response Middleware-Pipeline
  • 16. Ralf EggertRalf Eggert 1616 vonvon 5454 Middleware-PipelineMiddleware-Pipeline HTTP Request HTTP Response Routing Middleware Authorization Middleware Dispatching Middleware
  • 17. Ralf EggertRalf Eggert 1717 vonvon 5454 Middleware-AktionenMiddleware-Aktionen HTTP Request HTTP Response Routing Middleware Action Middleware Authorization Middleware Dispatching Middleware
  • 18. Ralf EggertRalf Eggert 1818 vonvon 5454 Beispiele für Action-MiddlewareBeispiele für Action-Middleware
  • 19. Ralf EggertRalf Eggert 1919 vonvon 5454 BeispielanwendungBeispielanwendung https://github.com/RalfEggert/entwicklermagazin.api
  • 20. Teil 3Teil 3 Einfache erste API erstellenEinfache erste API erstellen
  • 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. 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. 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. Ralf EggertRalf Eggert 2424 vonvon 5454 Check Method mit GET testenCheck Method mit GET testen
  • 25. Ralf EggertRalf Eggert 2525 vonvon 5454 Check Method mit PATCH testenCheck Method mit PATCH testen
  • 26. Ralf EggertRalf Eggert 2626 vonvon 5454 Check Method mit OPTIONS testenCheck Method mit OPTIONS testen
  • 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. 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. Teil 4Teil 4 API für Ausgabe von KundendatenAPI für Ausgabe von Kundendaten
  • 30. Ralf EggertRalf Eggert 3030 vonvon 5454 MySQL Datenbank einrichtenMySQL Datenbank einrichten
  • 31. Ralf EggertRalf Eggert 3131 vonvon 5454 Doctrine ORM installierenDoctrine ORM installieren $ composer install dasprid/container-interop-doctrine
  • 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. 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. 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. 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. 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. Ralf EggertRalf Eggert 3737 vonvon 5454 Kunden-API für Liste testenKunden-API für Liste testen
  • 38. Ralf EggertRalf Eggert 3838 vonvon 5454 Kunden-API für Entität testenKunden-API für Entität testen
  • 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. Teil 5Teil 5 API zum Ändern von KundendatenAPI zum Ändern von Kundendaten
  • 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. 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. 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. Ralf EggertRalf Eggert 4444 vonvon 5454 Kunden-API mit POST testenKunden-API mit POST testen
  • 45. Ralf EggertRalf Eggert 4545 vonvon 5454 Kunden-API mit PUT testenKunden-API mit PUT testen
  • 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. Teil 6Teil 6 Ausblick in die ZukunftAusblick in die Zukunft
  • 48. Ralf EggertRalf Eggert 4848 vonvon 5454 Apigility 2 mit ZendExpressiveApigility 2 mit ZendExpressive
  • 49. Ralf EggertRalf Eggert 4949 vonvon 5454 Komponente ZendExpressiveHalKomponente ZendExpressiveHal https://docs.zendframework.com/zend-expressive-hal/
  • 50. Ralf EggertRalf Eggert 5050 vonvon 5454 Komponente Problem DetailsKomponente Problem Details https://github.com/zendframework/zend-problem-details
  • 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. Ralf EggertRalf Eggert 5252 vonvon 5454 Neues AutorisierungsmodulNeues Autorisierungsmodul https://discourse.zendframework.com/t/rfc-authorization-module-for-expressive-and-psr-7/239
  • 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!