Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
PPIIMMPP DDEEIINN AAPPIIGGIILLIITTYY 
Komplexere Strukturen mit Apigility 
 
1 / 46
ÜÜbbeerr mmiicchh 
2 / 46 wwwwww..RRaallffEEggggeerrtt..ddee
[B00] 
PPrroolloogg 
3 / 46
[B01] 
4 / 46 
KKoommpplleexxeerree 
AAPPIIss mmiitt 
AAppiiggiilliittyy??
[B02] 
5 / 46 
GGeehhtt aauucchh!
DDaatteennbbaannkkmmooddeellll 
6 / 46
[B03] 
AAppiiggiilliittyy 
IInn aa NNuuttsshheellll 
7 / 46
RReessttffuull WWeebb SSeerrvviicceess 
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 
8 / 46
RRPPCC WWeebb SSeerrvviicceess 
Local 
CLIENT 
javascript 
RPC 
Client 
JSON 
Method:getUser 
Params:id 
USER DOMAIN 
getUserEntity() 
GET Request 
JSON Result 
Integer 
UserEntity 
RPC 
Server 
/json-rpc.php 
Remote Call 
JSON Result 
javascript 
JSON 
Method:addUser 
Params:name 
addUserEntity() 
POST Request 
JSON Result 
Array 
Boolean 
/json-rpc.php 
Remote Call 
JSON Result 
javascript 
XML 
Method:getUser 
Params:id 
getUserEntity() 
GET Request 
XML Result 
Integer 
UserEntity 
/xml-rpc.php 
Remote Call 
XML Result 
javascript 
XML 
Method:addUser 
Params:name 
addUserEntity() 
POST Request 
XML Result 
Array 
Boolean 
/xml-rpc.php 
Remote Call 
XML Result 
9 / 46
VVeerrssiioonniieerruunngg 
ddeeffaauulltt VVeerrssiioonn ppeerr UURRLL 
VVeerrssiioonn 11 ppeerr UURRLL 
VVeerrssiioonn 22 ppeerr UURRLL 
ddeeffaauulltt VVeerrssiioonn ppeerr CCoonntteenntt NNeeggoottiiaattiioonn 
VVeerrssiioonn 11 ppeerr CCoonntteenntt NNeeggoottiiaattiioonn 
VVeerrssiioonn 22 ppeerr CCoonntteenntt NNeeggoottiiaattiioonn 
10 / 46
JJSSOONN // HHAALL // PPrroobblleemm 
11 / 46
WWEEIITTEERREE FFEEAATTUURREESS 
DDaatteennbbaannkk--bbaassiieerrtt CCooddee--bbaassiieerrtt aauutthheennttiiffiizziieerruunngg 
AAPPII DDookkuummeennttaattiioonn DDaatteennvvaalliiddiieerruunngg DDeeppllooyymmeenntt 
12 / 46 
[B04] [B05] [B06] 
[B07] [B08] [[BB0099]]
[b10] 
EEiinnffaacchhee 
RREESSTT--SSeerrvviicceess 
13 / 46
DDaatteennbbaannkkaaddaapptteerr 
[b11] 
14 / 46
RREESSTT SSEERRVVIICCEE aannlleeggeenn 
[b00] 
15 / 46
AAUUTTHHEENNTTIIFFIIZZIIEERRUUNNGG 
[b06] 
16 / 46
TTeesstteenn mmiitt PPOOSSTTMMAANN 
[[bb1122]] 
1177 // 4466
[B13] 
FFIILLTTEERRNN ++ 
SSOOrrttiieerreenn 
18 / 46
CCoolllleeccttiioonn qquueerryy ssttrriinngg 
[b00] 
19 / 46 
Filter Sort
CCooddiinngg 
[b00] 
20 / 46
UUsseerrss RReessoouurrccee 
// module/User/src/User/V2/Rest/Users/UserResource.php 
namespace UserV2RestUsers; 
use ZendPaginatorAdapterDbTableGateway; 
use ZFApigilityDbConnectedResource; 
class UsersResource extends DbConnectedResource 
{ 
public function fetchAll($data = array()) 
{ 
$where = isset($data['filter']) ? $data['filter'] : array(); 
$order = isset($data['sort']) ? $data['sort'] : array(); 
$adapter = new DbTableGateway($this->table, $where, $order); 
return new $this->collectionClass($adapter); 
} 
} 
21 / 46
KKoonnffiigguurraattiioonn 
// module/User/config/module.config.php 
return array( 
'zf-apigility' => array( 
'db-connected' => array( 
[...], 
'UserV2RestUsersUsersResource' => array( 
'adapter_name' => 'MysqlAdapter', 
'table_name' => 'users', 
'hydrator_name' => 'ZendStdlibHydratorArraySerializable', 
'controller_service_name' => 'UserV2RestUsersController', 
'entity_identifier_name' => 'id', 
'table_service' => 'UserV2RestUsersUsersResourceTable', 
'resource_class' => 'UserV2RestUsersUsersResource', 
), 
), 
), 
); 
22 / 46
TTeesstteenn mmiitt PPOOSSTTMMAANN 
[[bb1122]] 
2233 // 4466
[B14] 
KKoommpplleexxeerree 
RREESSTT--SSeerrvviicceess 
24 / 46
RREESSTT SSEERRVVIICCEE aannlleeggeenn 
[b00] 
25 / 46
CCooddiinngg 
[b00] 
26 / 46
KKoonnffiigguurraattiioonn 
// module/User/config/module.config.php 
return array( 
[...] 
'service_manager' => array( 
'factories' => array( 
'UserV3RestUserProfilesUserProfilesResource' => 
'UserV3RestUserProfilesUserProfilesResourceFactory', 
'UserV3RestUserProfilesTableUserTable' => 
'UserV3RestUserProfilesTableUserTableFactory', 
'UserV3RestUserProfilesTableWebsiteTable' => 
'UserV3RestUserProfilesTableWebsiteTableFactory', 
), 
), 
); 
27 / 46
UUsseerr TTaabbllee II 
// module/User/src/User/V3/Rest/UserProfiles/Table/UserTable.php 
namespace UserV3RestUserProfilesTable; 
use ZendDbAdapterAdapterInterface; 
use ZendDbResultSetResultSetInterface; 
use ZendDbTableGatewayTableGateway; 
class UserTable extends TableGateway 
{ 
public function __construct( 
AdapterInterface $adapter, 
ResultSetInterface $resultSetPrototype = null 
) { 
$table = 'users'; 
parent::__construct($table, $adapter, null, $resultSetPrototype); 
} 
public function fetchUserById($id) 
{ 
$select = $this->getSql()->select(); 
$select->where->equalTo('id', $id); 
return $this->selectWith($select)->current(); 
} 
28 / 46
UUsseerr TTaabbllee IIII 
[...] 
public function fetchContactsById($id) 
{ 
$select = $this->getSql()->select(); 
$select->join('user_contacts', 'user_id_2 = id', array()); 
$select->where->equalTo('user_id_1', $id); 
return $this->selectWith($select)->toArray(); 
} 
public function fetchUsers($params) 
{ 
$select = $this->getSql()->select(); 
return $this->selectWith($select)->toArray(); 
} 
} 
29 / 46
UUsseerr TTaabbllee IIIIII 
// module/User/src/User/V3/Rest/UserProfiles/Table/UserTableFactory.php 
namespace UserV3RestUserProfilesTable; 
use ZendDbResultSetResultSet; 
use ZendServiceManagerFactoryInterface; 
use ZendServiceManagerServiceLocatorInterface; 
class UserTableFactory implements FactoryInterface 
{ 
public function createService(ServiceLocatorInterface $serviceLocator) 
{ 
$dbAdapter = $serviceLocator->get('MysqlAdapter'); 
$resultSet = new ResultSet(ResultSet::TYPE_ARRAY); 
$table = new UserTable($dbAdapter, $resultSet); 
return $table; 
} 
} 
30 / 46
UUsseerr PPrrooffiillee eennttiittyy 
// module/User/src/User/V3/Rest/UserProfiles/UserProfilesEntity.php 
namespace UserV3RestUserProfiles; 
class UserProfilesEntity 
{ 
protected $id; 
protected $firstname; 
protected $lastname; 
protected $email; 
protected $contacts; 
protected $websites; 
public function setId($id) {} 
public function getId() {} 
public function setFirstname($firstname) {} 
public function getFirstame() {} 
public function setLastname($lastname) {} 
public function getLastame() {} 
public function setEmail($email) {} 
public function getEmail() {} 
public function setContacts(array $contacts) {} 
public function getContacts() {} 
public function setWebsites(array $websites) {} 
public function getWebsites() {} 
} 
31 / 46
UUsseerr PPrrooffiillee RReessoouurrccee II 
// module/User/src/User/V3/Rest/UserProfiles/UserProfilesResource.php 
namespace UserV3RestUserProfiles; 
use UserV3RestUserProfileTableUserTable; 
use UserV3RestUserProfileTableWebsiteTable; 
use ZFApiProblemApiProblem; 
use ZFRestAbstractResourceListener; 
class UserProfilesResource extends AbstractResourceListener 
{ 
protected $userTable; 
protected $websiteTable; 
public function setUserTable($userTable) {} 
public function getUserTable() {} 
public function setWebsiteTable($websiteTable) {} 
public function getWebsiteTable() {} 
public function create($data) 
{ 
return new ApiProblem(405, 'The POST method has not been defined'); 
} 
public function delete($id) {} 
public function deleteList($data) {} 
32 / 46
UUsseerr PPrrooffiillee RReessoouurrccee IIII 
public function fetch($id) 
{ 
$user = $this->getUserTable()->fetchUserById($id); 
if (!$user) { 
return new ApiProblem(404, 'User profile for id ' . $id . ' not found'); 
} 
return $this->addContactsAndWebsites($user); 
} 
public function fetchAll($params = array()) 
{ 
$users = $this->getUserTable()->fetchUsers($params); 
if (!$users) { 
return new ApiProblem(404, 'No user profiles found'); 
} 
foreach ($users as $key => $user) { 
$users[$key] = $this->addContactsAndWebsites($user); 
} 
return $users; 
} 
protected function addContactsAndWebsites(array $user) 
{ 
$user['contacts'] = $this->getUserTable()->fetchContactsById($user['id']); 
$user['websites'] = $this->getWebsiteTable()->fetchWebsitesById($user['id']); 
return $user; 
} 
} 
33 / 46
UUsseerr PPrrooffiillee RReessoouurrccee IIIIII 
// module/User/src/User/V3/Rest/UserProfiles/UserProfilesResourceFactory.php 
namespace UserV3RestUserProfiles; 
class UserProfilesResourceFactory 
{ 
public function __invoke($services) 
{ 
$userTable = $services->get( 
'UserV2RestUserProfileTableUserTable' 
); 
$websiteTable = $services->get( 
'UserV2RestUserProfileTableWebsiteTable' 
); 
$resource = new UserProfilesResource(); 
$resource->setUserTable($userTable); 
$resource->setWebsiteTable($websiteTable); 
return $resource; 
} 
} 
34 / 46
TTeesstteenn mmiitt PPOOSSTTMMAANN 
[[bb1122]] 
3355 // 4466
[B13] 
DDaatteeii UUppllooaadd 
36 / 46
CCoonntteenntt--TTyyppee 
[b00] 
37 / 46 
Multipart/form-data
IImmaaggee FFiieelldd eerrggäännzzeenn 
[b00] 
38 / 46
CCooddiinngg 
[b00] 
39 / 46
UUsseerrss RReessoouurrccee 
// module/User/src/User/V4/Rest/Users/UserResource.php 
namespace UserV4RestUsers; 
use ZFApigilityDbConnectedResource; 
class UsersResource extends DbConnectedResource 
{ 
protected function retrieveData($data) 
{ 
if (null !== $filter) { 
$data = $this->getInputFilter()->getValues(); 
} else { 
$data = (array) $data; 
} 
$image = $this->getInputFilter()->getValue('image'); 
$imagePath = '/img/uploads/' . md5(serialize($data)) . '.jpg'; 
$fullPath = APPLICATION_PATH . '/public' . $imagePath; 
copy(APPLICATION_PATH . '/' . $image['tmp_name'], $fullPath); 
unlink(APPLICATION_PATH . '/' . $image['tmp_name']); 
$data['image'] = $imagePath; 
return $data; 
} 
} 
40 / 46
TTeesstteenn mmiitt PPOOSSTTMMAANN 
[[bb1122]] 
4411 // 4466
[B15] 
AAppiiggiilliittyy oohhnnee 
AAppiiggiilliittyy 
((FFaasstt wwiiee KKoocchheenn oohhnnee BBlluummeennkkoohhll)) 
42 / 46
MMoodduullaarreerr AAuuffbbaauu 
ZZff--aappiiggiilliittyy ZZff--aappiiggiilliittyy--aaddmmiinn ZZff--aappiiggiilliittyy--ddooccuummeennttaattiioonn 
ZZff--aappiiggiilliittyy--ddooccuummeennttaattiioonn--sswwaaggggeerr ZZff--aappiiggiilliittyy--pprroovviiddeerr ZZff--aappiiggiilliittyy--WWeellccoommee 
ZZff--aappii--pprroobblleemm ZZff--ccoonnffiigguurraattiioonn ZZff--ccoonntteenntt--nneeggoottiiaattiioonn 
ZZff--ccoonntteenntt--vvaalliiddaattiioonn ZZff--ddeeppllooyy ZZff--ddeevveellooppmmeenntt--mmooddee 
ZZff--hhaall ZZff--mmvvcc--aauutthh ZZff--ooaauutthh22 
ZZff--rreesstt ZZff--RRPPCC ZZff--vveerrssiioonniinngg 
43 / 46
[B00] 
EEPPIILLOOGG 
44 / 46
PPIIMMPP DDEEIINN AAPPIIGGIILLIITTYY 
Komplexere Strukturen mit Apigility 
 
Repository: https://github.com/RalfEggert/ipc2014-apigility 
45 / 46
BBiillddnnaacchhwweeiiss 
[B00] Fotos von Ralf Eggert 
[B01] Still here https://www.flickr.com/photos/thenovys/3784261365 von Abe Novy - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B02] Young student https://www.flickr.com/photos/audiolucistore/14159712431/ von www.audio-luci-store.it - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B03] Acorns https://www.flickr.com/photos/dno1967b/5431273344 von Daniel Oines - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B04] Fixing the database https://www.flickr.com/photos/dahlstroms/4140461901 von Håkan Dahlström - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B05] Monaco 14pt https://www.flickr.com/photos/polarity/3138680190 von Robert Agthe - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B06] 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/ 
[B07] Shelf of Used Books https://www.flickr.com/photos/thedarkthing/5363586197 von William Ross - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B08] Ticket validator at Nice train station https://www.flickr.com/photos/traveleden/3797157077 von Simon - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B09] Test Lab - Supermicro Storage https://www.flickr.com/photos/jemimus/8533890844 von Robert - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B10] Building blocks https://www.flickr.com/photos/zscheyge/49012397 von Holger Zscheyge - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B11] Bluetooth adapter https://www.flickr.com/photos/razor512/8201846881 von Razor512 - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B12] Busy Postmen https://www.flickr.com/photos/wheatfields/4253690499 von Christian Guthier - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B13] Filters for black and white film https://www.flickr.com/photos/aslakr/96723190 von Aslak Raanes - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B14] Cable closet https://www.flickr.com/photos/adrian_s/8271860 von Adrian Sampson - CC-BY https://creativecommons.org/licenses/by/2.0/ 
[B15] Cauliflower https://www.flickr.com/photos/calliope/54833239 von Liz West - CC-BY https://creativecommons.org/licenses/by/2.0/ 
Alle weiteren Screenshots wurden von Ralf Eggert erstellt. 
46 / 46

More Related Content

ICP2014: Pimp dein Apigility

  • 1. PPIIMMPP DDEEIINN AAPPIIGGIILLIITTYY Komplexere Strukturen mit Apigility  1 / 46
  • 2. ÜÜbbeerr mmiicchh 2 / 46 wwwwww..RRaallffEEggggeerrtt..ddee
  • 4. [B01] 4 / 46 KKoommpplleexxeerree AAPPIIss mmiitt AAppiiggiilliittyy??
  • 5. [B02] 5 / 46 GGeehhtt aauucchh!
  • 7. [B03] AAppiiggiilliittyy IInn aa NNuuttsshheellll 7 / 46
  • 8. RReessttffuull WWeebb SSeerrvviicceess 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 8 / 46
  • 9. RRPPCC WWeebb SSeerrvviicceess Local CLIENT javascript RPC Client JSON Method:getUser Params:id USER DOMAIN getUserEntity() GET Request JSON Result Integer UserEntity RPC Server /json-rpc.php Remote Call JSON Result javascript JSON Method:addUser Params:name addUserEntity() POST Request JSON Result Array Boolean /json-rpc.php Remote Call JSON Result javascript XML Method:getUser Params:id getUserEntity() GET Request XML Result Integer UserEntity /xml-rpc.php Remote Call XML Result javascript XML Method:addUser Params:name addUserEntity() POST Request XML Result Array Boolean /xml-rpc.php Remote Call XML Result 9 / 46
  • 10. VVeerrssiioonniieerruunngg ddeeffaauulltt VVeerrssiioonn ppeerr UURRLL VVeerrssiioonn 11 ppeerr UURRLL VVeerrssiioonn 22 ppeerr UURRLL ddeeffaauulltt VVeerrssiioonn ppeerr CCoonntteenntt NNeeggoottiiaattiioonn VVeerrssiioonn 11 ppeerr CCoonntteenntt NNeeggoottiiaattiioonn VVeerrssiioonn 22 ppeerr CCoonntteenntt NNeeggoottiiaattiioonn 10 / 46
  • 11. JJSSOONN // HHAALL // PPrroobblleemm 11 / 46
  • 12. WWEEIITTEERREE FFEEAATTUURREESS DDaatteennbbaannkk--bbaassiieerrtt CCooddee--bbaassiieerrtt aauutthheennttiiffiizziieerruunngg AAPPII DDookkuummeennttaattiioonn DDaatteennvvaalliiddiieerruunngg DDeeppllooyymmeenntt 12 / 46 [B04] [B05] [B06] [B07] [B08] [[BB0099]]
  • 17. TTeesstteenn mmiitt PPOOSSTTMMAANN [[bb1122]] 1177 // 4466
  • 18. [B13] FFIILLTTEERRNN ++ SSOOrrttiieerreenn 18 / 46
  • 19. CCoolllleeccttiioonn qquueerryy ssttrriinngg [b00] 19 / 46 Filter Sort
  • 21. UUsseerrss RReessoouurrccee // module/User/src/User/V2/Rest/Users/UserResource.php namespace UserV2RestUsers; use ZendPaginatorAdapterDbTableGateway; use ZFApigilityDbConnectedResource; class UsersResource extends DbConnectedResource { public function fetchAll($data = array()) { $where = isset($data['filter']) ? $data['filter'] : array(); $order = isset($data['sort']) ? $data['sort'] : array(); $adapter = new DbTableGateway($this->table, $where, $order); return new $this->collectionClass($adapter); } } 21 / 46
  • 22. KKoonnffiigguurraattiioonn // module/User/config/module.config.php return array( 'zf-apigility' => array( 'db-connected' => array( [...], 'UserV2RestUsersUsersResource' => array( 'adapter_name' => 'MysqlAdapter', 'table_name' => 'users', 'hydrator_name' => 'ZendStdlibHydratorArraySerializable', 'controller_service_name' => 'UserV2RestUsersController', 'entity_identifier_name' => 'id', 'table_service' => 'UserV2RestUsersUsersResourceTable', 'resource_class' => 'UserV2RestUsersUsersResource', ), ), ), ); 22 / 46
  • 23. TTeesstteenn mmiitt PPOOSSTTMMAANN [[bb1122]] 2233 // 4466
  • 27. KKoonnffiigguurraattiioonn // module/User/config/module.config.php return array( [...] 'service_manager' => array( 'factories' => array( 'UserV3RestUserProfilesUserProfilesResource' => 'UserV3RestUserProfilesUserProfilesResourceFactory', 'UserV3RestUserProfilesTableUserTable' => 'UserV3RestUserProfilesTableUserTableFactory', 'UserV3RestUserProfilesTableWebsiteTable' => 'UserV3RestUserProfilesTableWebsiteTableFactory', ), ), ); 27 / 46
  • 28. UUsseerr TTaabbllee II // module/User/src/User/V3/Rest/UserProfiles/Table/UserTable.php namespace UserV3RestUserProfilesTable; use ZendDbAdapterAdapterInterface; use ZendDbResultSetResultSetInterface; use ZendDbTableGatewayTableGateway; class UserTable extends TableGateway { public function __construct( AdapterInterface $adapter, ResultSetInterface $resultSetPrototype = null ) { $table = 'users'; parent::__construct($table, $adapter, null, $resultSetPrototype); } public function fetchUserById($id) { $select = $this->getSql()->select(); $select->where->equalTo('id', $id); return $this->selectWith($select)->current(); } 28 / 46
  • 29. UUsseerr TTaabbllee IIII [...] public function fetchContactsById($id) { $select = $this->getSql()->select(); $select->join('user_contacts', 'user_id_2 = id', array()); $select->where->equalTo('user_id_1', $id); return $this->selectWith($select)->toArray(); } public function fetchUsers($params) { $select = $this->getSql()->select(); return $this->selectWith($select)->toArray(); } } 29 / 46
  • 30. UUsseerr TTaabbllee IIIIII // module/User/src/User/V3/Rest/UserProfiles/Table/UserTableFactory.php namespace UserV3RestUserProfilesTable; use ZendDbResultSetResultSet; use ZendServiceManagerFactoryInterface; use ZendServiceManagerServiceLocatorInterface; class UserTableFactory implements FactoryInterface { public function createService(ServiceLocatorInterface $serviceLocator) { $dbAdapter = $serviceLocator->get('MysqlAdapter'); $resultSet = new ResultSet(ResultSet::TYPE_ARRAY); $table = new UserTable($dbAdapter, $resultSet); return $table; } } 30 / 46
  • 31. UUsseerr PPrrooffiillee eennttiittyy // module/User/src/User/V3/Rest/UserProfiles/UserProfilesEntity.php namespace UserV3RestUserProfiles; class UserProfilesEntity { protected $id; protected $firstname; protected $lastname; protected $email; protected $contacts; protected $websites; public function setId($id) {} public function getId() {} public function setFirstname($firstname) {} public function getFirstame() {} public function setLastname($lastname) {} public function getLastame() {} public function setEmail($email) {} public function getEmail() {} public function setContacts(array $contacts) {} public function getContacts() {} public function setWebsites(array $websites) {} public function getWebsites() {} } 31 / 46
  • 32. UUsseerr PPrrooffiillee RReessoouurrccee II // module/User/src/User/V3/Rest/UserProfiles/UserProfilesResource.php namespace UserV3RestUserProfiles; use UserV3RestUserProfileTableUserTable; use UserV3RestUserProfileTableWebsiteTable; use ZFApiProblemApiProblem; use ZFRestAbstractResourceListener; class UserProfilesResource extends AbstractResourceListener { protected $userTable; protected $websiteTable; public function setUserTable($userTable) {} public function getUserTable() {} public function setWebsiteTable($websiteTable) {} public function getWebsiteTable() {} public function create($data) { return new ApiProblem(405, 'The POST method has not been defined'); } public function delete($id) {} public function deleteList($data) {} 32 / 46
  • 33. UUsseerr PPrrooffiillee RReessoouurrccee IIII public function fetch($id) { $user = $this->getUserTable()->fetchUserById($id); if (!$user) { return new ApiProblem(404, 'User profile for id ' . $id . ' not found'); } return $this->addContactsAndWebsites($user); } public function fetchAll($params = array()) { $users = $this->getUserTable()->fetchUsers($params); if (!$users) { return new ApiProblem(404, 'No user profiles found'); } foreach ($users as $key => $user) { $users[$key] = $this->addContactsAndWebsites($user); } return $users; } protected function addContactsAndWebsites(array $user) { $user['contacts'] = $this->getUserTable()->fetchContactsById($user['id']); $user['websites'] = $this->getWebsiteTable()->fetchWebsitesById($user['id']); return $user; } } 33 / 46
  • 34. UUsseerr PPrrooffiillee RReessoouurrccee IIIIII // module/User/src/User/V3/Rest/UserProfiles/UserProfilesResourceFactory.php namespace UserV3RestUserProfiles; class UserProfilesResourceFactory { public function __invoke($services) { $userTable = $services->get( 'UserV2RestUserProfileTableUserTable' ); $websiteTable = $services->get( 'UserV2RestUserProfileTableWebsiteTable' ); $resource = new UserProfilesResource(); $resource->setUserTable($userTable); $resource->setWebsiteTable($websiteTable); return $resource; } } 34 / 46
  • 35. TTeesstteenn mmiitt PPOOSSTTMMAANN [[bb1122]] 3355 // 4466
  • 37. CCoonntteenntt--TTyyppee [b00] 37 / 46 Multipart/form-data
  • 40. UUsseerrss RReessoouurrccee // module/User/src/User/V4/Rest/Users/UserResource.php namespace UserV4RestUsers; use ZFApigilityDbConnectedResource; class UsersResource extends DbConnectedResource { protected function retrieveData($data) { if (null !== $filter) { $data = $this->getInputFilter()->getValues(); } else { $data = (array) $data; } $image = $this->getInputFilter()->getValue('image'); $imagePath = '/img/uploads/' . md5(serialize($data)) . '.jpg'; $fullPath = APPLICATION_PATH . '/public' . $imagePath; copy(APPLICATION_PATH . '/' . $image['tmp_name'], $fullPath); unlink(APPLICATION_PATH . '/' . $image['tmp_name']); $data['image'] = $imagePath; return $data; } } 40 / 46
  • 41. TTeesstteenn mmiitt PPOOSSTTMMAANN [[bb1122]] 4411 // 4466
  • 42. [B15] AAppiiggiilliittyy oohhnnee AAppiiggiilliittyy ((FFaasstt wwiiee KKoocchheenn oohhnnee BBlluummeennkkoohhll)) 42 / 46
  • 43. MMoodduullaarreerr AAuuffbbaauu ZZff--aappiiggiilliittyy ZZff--aappiiggiilliittyy--aaddmmiinn ZZff--aappiiggiilliittyy--ddooccuummeennttaattiioonn ZZff--aappiiggiilliittyy--ddooccuummeennttaattiioonn--sswwaaggggeerr ZZff--aappiiggiilliittyy--pprroovviiddeerr ZZff--aappiiggiilliittyy--WWeellccoommee ZZff--aappii--pprroobblleemm ZZff--ccoonnffiigguurraattiioonn ZZff--ccoonntteenntt--nneeggoottiiaattiioonn ZZff--ccoonntteenntt--vvaalliiddaattiioonn ZZff--ddeeppllooyy ZZff--ddeevveellooppmmeenntt--mmooddee ZZff--hhaall ZZff--mmvvcc--aauutthh ZZff--ooaauutthh22 ZZff--rreesstt ZZff--RRPPCC ZZff--vveerrssiioonniinngg 43 / 46
  • 45. PPIIMMPP DDEEIINN AAPPIIGGIILLIITTYY Komplexere Strukturen mit Apigility  Repository: https://github.com/RalfEggert/ipc2014-apigility 45 / 46
  • 46. BBiillddnnaacchhwweeiiss [B00] Fotos von Ralf Eggert [B01] Still here https://www.flickr.com/photos/thenovys/3784261365 von Abe Novy - CC-BY https://creativecommons.org/licenses/by/2.0/ [B02] Young student https://www.flickr.com/photos/audiolucistore/14159712431/ von www.audio-luci-store.it - CC-BY https://creativecommons.org/licenses/by/2.0/ [B03] Acorns https://www.flickr.com/photos/dno1967b/5431273344 von Daniel Oines - CC-BY https://creativecommons.org/licenses/by/2.0/ [B04] Fixing the database https://www.flickr.com/photos/dahlstroms/4140461901 von Håkan Dahlström - CC-BY https://creativecommons.org/licenses/by/2.0/ [B05] Monaco 14pt https://www.flickr.com/photos/polarity/3138680190 von Robert Agthe - CC-BY https://creativecommons.org/licenses/by/2.0/ [B06] 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/ [B07] Shelf of Used Books https://www.flickr.com/photos/thedarkthing/5363586197 von William Ross - CC-BY https://creativecommons.org/licenses/by/2.0/ [B08] Ticket validator at Nice train station https://www.flickr.com/photos/traveleden/3797157077 von Simon - CC-BY https://creativecommons.org/licenses/by/2.0/ [B09] Test Lab - Supermicro Storage https://www.flickr.com/photos/jemimus/8533890844 von Robert - CC-BY https://creativecommons.org/licenses/by/2.0/ [B10] Building blocks https://www.flickr.com/photos/zscheyge/49012397 von Holger Zscheyge - CC-BY https://creativecommons.org/licenses/by/2.0/ [B11] Bluetooth adapter https://www.flickr.com/photos/razor512/8201846881 von Razor512 - CC-BY https://creativecommons.org/licenses/by/2.0/ [B12] Busy Postmen https://www.flickr.com/photos/wheatfields/4253690499 von Christian Guthier - CC-BY https://creativecommons.org/licenses/by/2.0/ [B13] Filters for black and white film https://www.flickr.com/photos/aslakr/96723190 von Aslak Raanes - CC-BY https://creativecommons.org/licenses/by/2.0/ [B14] Cable closet https://www.flickr.com/photos/adrian_s/8271860 von Adrian Sampson - CC-BY https://creativecommons.org/licenses/by/2.0/ [B15] Cauliflower https://www.flickr.com/photos/calliope/54833239 von Liz West - CC-BY https://creativecommons.org/licenses/by/2.0/ Alle weiteren Screenshots wurden von Ralf Eggert erstellt. 46 / 46