Apigility reloaded

44
APIGILITY Reloaded APIGILITY Reloaded Ein frischer Blick auf Apigility 1.1 Repository: https://github.com/RalfEggert/ipc2015-apigility 1 / 44

Transcript of Apigility reloaded

APIGILITY ReloadedAPIGILITY ReloadedEin frischer Blick auf Apigility 1.1

Repository: https://github.com/RalfEggert/ipc2015-apigility

1 / 44

Über michÜber mich

2 / 44www.RalfEggert.dewww.RalfEggert.de

Fragen ans PublikumFragen ans Publikum

3 / 44

[b01][b01]

[B00][B00]

Apigility 1.0Apigility 1.0

4 / 44

Performance LastigPerformance Lastig

5 / 44

[b02][b02]

Bug lastigBug lastig

6 / 44

[b03]

KonfigurationsLastigKonfigurationsLastig

7 / 44

[b00]

Code lastigCode lastig

8 / 44

[b00]

[B04]

9 / 44

Apigility 1.0Apigility 1.0War mir zu War mir zu AufwändigAufwändig

[B05]

10 / 44

Dann schau dir Dann schau dir Apigility 1.1 an!Apigility 1.1 an!

[B06]

Apigility 1.1Apigility 1.1In a NutshellIn a Nutshell

11 / 44

Restful Web ServicesRestful Web Services

12 / 44

CLIENT

Web Browser

PHP

Javascript

RUBY

PYTHON

REST SERVER

/api/user/123

/api/user

/api/user

/api/user/123

/api/user/123

USER DOMAIN

getUserEntity()

getUserCollection()

addUserEntity()

updateUserEntity()

deleteUserEntity()

GET Request

JSON Response

GET Request

JSON Response

POST Request

JSON Response

PUT Request

JSON Response

DELETE Request

JSON Response

Integer

UserEntity

void

UserCollection

Array

Boolean

Integer, Array

Boolean

Integer

Boolean

RPC Web ServicesRPC Web Services

13 / 44

LocalCLIENT

javascript

RPCClient

JSON

Method:getUserParams:id

USER DOMAIN

getUserEntity()

GET Request

JSON Result

Integer

UserEntity

RPCServer

/json-rpc.php

Remote Call

JSON Result

javascriptJSON

Method:addUserParams:name

addUserEntity()

POST Request

JSON Result

Array

Boolean

/json-rpc.php

Remote Call

JSON Result

javascriptXML

Method:getUserParams:id

getUserEntity()

GET Request

XML Result

Integer

UserEntity

/xml-rpc.php

Remote Call

XML Result

javascriptXML

Method:addUserParams:name

addUserEntity()

POST Request

XML Result

Array

Boolean

/xml-rpc.php

Remote Call

XML Result

VersionierungVersionierung

14 / 44

default Version per URLdefault Version per URL

Version 1 per URLVersion 1 per URL

Version 2 per URLVersion 2 per URL

default Version per Content Negotiationdefault Version per Content Negotiation

Version 1 per Content NegotiationVersion 1 per Content Negotiation

Version 2 per Content NegotiationVersion 2 per Content Negotiation

JSON / HAL / ProblemJSON / HAL / Problem

15 / 44

WEITERE FEATURESWEITERE FEATURES

Datenbank-basiertDatenbank-basiert Code-basiertCode-basiert AuthentifizierungAuthentifizierung

API DokumentationAPI Dokumentation DatenvalidierungDatenvalidierung DeploymentDeployment

16 / 44

[B09][B08][B08][B07]

[B12][B12][B11][B10]

[b07]

DB-ConnectedDB-ConnectedServiceService

17 / 44

DatenbankmodellDatenbankmodell

18 / 44

InstallationInstallation

19 / 44

// Konsole

// Projekt anlegen$ cd /home/devhost/$ composer create-project --dev zfcampus/zf-apigility-skeleton apigility.local$ cd apigility.local/

// ggf. Schreibrechte setzen$ sudo chmod 777 -R /home/devhost/apigility.local/

// Development Modus$ php public/index.php development enable

// Composer besorgen (falls benötigt)$ curl -s https://getcomposer.org/installer | php --

// Passwort Datei erstellen$ htpasswd -cs data/users.htpasswd ipc2015

UI: DB-connectedUI: DB-connected

Auth AdapterAuth Adapter Datenbank AdapterDatenbank Adapter Neue User APINeue User API

AuthentifizierungAuthentifizierung Profile ServiceProfile Service User ServiceUser Service

#step1 20 / 44

Testen mit POSTMANTesten mit POSTMAN

2121 / / 4444

[b13][b13]

[B00]

Doctrine-Doctrine-ConnectedConnectedServiceService

22 / 44

DatenbankmodellDatenbankmodell

23 / 44

UI: DOCTRINE-connectedUI: DOCTRINE-connected

Neue User APINeue User API AuthentifizierungAuthentifizierung

24 / 44

Doctrine InstallationDoctrine Installation

25 / 44

// Konsole

// Apigility Modul für Doctrine installieren$ php composer.phar require zfcampus/zf-apigility-doctrine "~0.3"

// DoctrineORMModule installieren (falls noch nicht installiert)$ php composer.phar require doctrine/doctrine-orm-module "~0.8"

Module aktivierenModule aktivieren

26 / 44

// Datei /config/application.config.phpreturn array( 'modules' => array( [...] 'DoctrineModule', 'DoctrineORMModule', 'Phpro\DoctrineHydrationModule', 'ZF\Apigility\Doctrine\Server', ),);

// Datei /config/development.config.phpreturn array( 'modules' => array( [...] 'ZF\Apigility\Doctrine\Admin', ),);

Doctrine ConnectionDoctrine Connection

27 / 44

// Datei /config/autoload/user.global.phpreturn array( 'doctrine' => array( 'connection' => array( 'orm_default' => array( 'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver', 'params' => array( 'host' => 'localhost', 'user' => 'ipc2015', 'password' => 'ipc2015', 'dbname' => 'ipc2015.shop', 'charset' => 'utf8', ), ), ), ),);

Doctrine DriverDoctrine Driver

28 / 44

// Datei /module/Shop/config/module.config.phpreturn array( 'doctrine' => array( 'driver' => array( 'shop_driver' => array( 'class' => 'Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver', 'cache' => 'array', 'paths' => array( 0 => __DIR__ . '/../src/Shop/V1/Entity', ), ), 'orm_default' => array( 'drivers' => array( 'Shop\\V1\\Entity' => 'shop_driver', ), ), ), ),);

ENUM Doctrine TYPEENUM Doctrine TYPE

29 / 44

// Datei /module/Application/Module.php[...]use Doctrine\ORM\EntityManager;

class Module{ public function onBootstrap(MvcEvent $e) { [...] $serviceManager = $e->getApplication()->getServiceManager();

$entityManager = $serviceManager->get('Doctrine\ORM\EntityManager'); $platform = $entityManager->getConnection()->getDatabasePlatform();

try { $result = $platform->getDoctrineTypeMapping('enum'); } catch (DBALException $e) { $platform->registerDoctrineTypeMapping('enum', 'string'); } }}

Entities erstellenEntities erstellen

30 / 44

// Entities aus Datenbank generieren$ php public/index.php orm:convert-mapping --namespace="Shop\\V1\\Entity\\" --force --from-database annotation ./module/Shop/srcProcessing entity "Shop\V1\Entity\Address"Processing entity "Shop\V1\Entity\Booking"Processing entity "Shop\V1\Entity\Bookingposition"Processing entity "Shop\V1\Entity\Customer"Processing entity "Shop\V1\Entity\Product"

Exporting "annotation" mapping information to "/home/devhost/apigility.local/module/Shop/src"

// Setter und Getter für Entities generieren$ php public/index.php orm:generate-entities ./module/Shop/src --generate-annotations=trueProcessing entity "Shop\V1\Entity\Bookingposition"Processing entity "Shop\V1\Entity\Booking"Processing entity "Shop\V1\Entity\Address"Processing entity "Shop\V1\Entity\Product"Processing entity "Shop\V1\Entity\Customer"

Entity classes generated to "/home/devhost/apigility.local/module/Shop/src"

UI: Doctrine-connectedUI: Doctrine-connected

Address ServiceAddress Service Customer ServiceCustomer Service Product ServiceProduct Service

Booking ServiceBooking Service Bookingpos. ServiceBookingpos. Service

#step2 31 / 44

Testen mit POSTMANTesten mit POSTMAN

3232 / / 4444

[b13][b13]

Speichern (cascade)Speichern (cascade)// Datei /module/Shop/src/Shop/V1/Entity/Customer.php/** * @var \Shop\V1\Entity\Address * * @ORM\ManyToOne(targetEntity="Shop\V1\Entity\Address", cascade={"persist"}) * @ORM\JoinColumns({ * @ORM\JoinColumn(name="invoice_address", referencedColumnName="id") * }) */private $invoiceAddress;

/** * @var \Shop\V1\Entity\Address * * @ORM\ManyToOne(targetEntity="Shop\V1\Entity\Address", cascade={"persist"}) * @ORM\JoinColumns({ * @ORM\JoinColumn(name="delivery_address", referencedColumnName="id") * }) */private $deliveryAddress;

#step3 33 / 44

[B14]

Many-to-ManyMany-to-Many

34 / 44

Testen mit POSTMANTesten mit POSTMAN

3535 / / 4444

[b13][b13]

Positionen für BookingPositionen für Booking

36 / 44

// Datei /module/Shop/src/Shop/V1/Entity/Booking.php/** * @var ArrayCollection * * @ORM\ManyToMany(targetEntity="Bookingposition") * @ORM\JoinTable(name="bookingposition", * joinColumns={@ORM\JoinColumn(name="booking", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="product", referencedColumnName="id")} * )**/private $positions;

BookingHydratorBookingHydrator

37 / 44

// Datei /module/Shop/config/module.config.phpreturn array( 'doctrine-hydrator' => array( [...]

'Shop\\V1\\Rest\\Booking\\BookingHydrator' => array( [...]

'strategies' => array( 'positions' => 'ZF\\Apigility\\Doctrine\\Server\\ Hydrator\\Strategy\\CollectionExtract', ),

[...] ),

[...] ),);

Max_Depth setzenMax_Depth setzen

38 / 44

// Datei /module/Shop/config/module.config.phpreturn array( 'zf-hal' => array( 'metadata_map' => array( 'Shop\\V1\\Entity\\Booking' => array( [...]

'max_depth' => 3, ),

[...]

'Shop\\V1\\Entity\\Bookingposition' => array( [...]

'max_depth' => 2, ), ), ),);

Entities aktualisierenEntities aktualisieren

39 / 44

// Setter und Getter für Entities aktualisieren$ php public/index.php orm:generate-entities ./module/Shop/src --generate-annotations=trueProcessing entity "Shop\V1\Entity\Bookingposition"Processing entity "Shop\V1\Entity\Booking"Processing entity "Shop\V1\Entity\Address"Processing entity "Shop\V1\Entity\Product"Processing entity "Shop\V1\Entity\Customer"

Entity classes generated to "/home/devhost/apigility.local/module/Shop/src"

// Schreibrechte für module/ Verzeichnis neu setzen$ sudo chmod 777 -R /home/devhost/apigility.local/

Testen mit POSTMANTesten mit POSTMAN

4040 / / 4444

[b13][b13]

[B15]

41 / 44

Fazit:Fazit:Apigility 1.1 Apigility 1.1 ist (fast) ist (fast) kinderleichtkinderleicht

Fragen vom Publikum?Fragen vom Publikum?

42 / 44

[b16]

DANKEDANKEFür Ihre / Eure Aufmerksamkeit!

Repository: https://github.com/RalfEggert/ipc2015-apigility

43 / 44

BildnachweisBildnachweis[B00] Fotos von Ralf Eggert

[B01] Frontiers 2011 - Day 2 https://www.flickr.com/photos/frontiersofinteraction/5866676276/ von Frontiersofinteraction - CC-BY https://creativecommons.org/licenses/by/2.0/

[B02] Slow poke - bush gardens https://www.flickr.com/photos/hyku/421609299 von Josh Hallett - CC-BY https://creativecommons.org/licenses/by/2.0/

[B03] Thirsty lady bugs https://www.flickr.com/photos/snowpeak/5897430351/ von John Fowler - CC-BY https://creativecommons.org/licenses/by/2.0/

[B04] Still here https://www.flickr.com/photos/thenovys/3784261365 von Abe Novy - CC-BY https://creativecommons.org/licenses/by/2.0/

[B05] Young student https://www.flickr.com/photos/audiolucistore/14159712431/ von www.audio-luci-store.it - CC-BY https://creativecommons.org/licenses/by/2.0/

[B06] My nuts https://www.flickr.com/photos/lucasincas/6517703315/ von Lucas Incas - CC-BY https://creativecommons.org/licenses/by/2.0/

[B07] Fixing the database https://www.flickr.com/photos/dahlstroms/4140461901 von Håkan Dahlström - CC-BY https://creativecommons.org/licenses/by/2.0/

[B08] Monaco 14pt https://www.flickr.com/photos/polarity/3138680190 von Robert Agthe - CC-BY https://creativecommons.org/licenses/by/2.0/

[B09] RSA Securid Token - Credit Card Style https://www.flickr.com/photos/purpleslog/265657780 von Purple Slog - CC-BY https://creativecommons.org/licenses/by/2.0/

[B10] Shelf of Used Books https://www.flickr.com/photos/thedarkthing/5363586197 von William Ross - CC-BY https://creativecommons.org/licenses/by/2.0/

[B11] Ticket validator at Nice train station https://www.flickr.com/photos/traveleden/3797157077 von Simon - CC-BY https://creativecommons.org/licenses/by/2.0/

[B12] Test Lab - Supermicro Storage https://www.flickr.com/photos/jemimus/8533890844 von Robert - CC-BY https://creativecommons.org/licenses/by/2.0/

[B13] Busy Postmen https://www.flickr.com/photos/wheatfields/4253690499 von Christian Guthier - CC-BY https://creativecommons.org/licenses/by/2.0/

[B14] Network switch and cables https://www.flickr.com/photos/nayukim/3827776580 von Nayu Kim - CC-BY https://creativecommons.org/licenses/by/2.0/

[B15] We are all fan of laptops. https://www.flickr.com/photos/scottvanderchijs/4493248747 von Scott & Elaine van der Chijs - CC-BY https://creativecommons.org/licenses/by/2.0/

[B16] Etech05: Audience https://www.flickr.com/photos/oreilly/6648470 von James Duncan Davidson - CC-BY https://creativecommons.org/licenses/by/2.0/

Alle weiteren Screenshots wurden von Ralf Eggert erstellt.

44 / 44