Upgrade to Pro — share decks privately, control downloads, hide ads and more …

2015 ZendCon - Service Oriented Architecture as...

2015 ZendCon - Service Oriented Architecture as a Pattern of Development

Mike Willbanks

October 22, 2015
Tweet

More Decks by Mike Willbanks

Other Decks in Technology

Transcript

  1. I AM MIKE WILLBANKS • Father, Husband, Developer • VP

    of Development at Packet Power • Twitter: @mwillbanks
  2. <html> <head><title>Recent Books</title></head> <body> <ul class="books"> <?php $books = $db->select('...');

    foreach ($books as $book) { echo '<li>' . $book['title'] . '</li>'; } ?> </ul> </body> </html>
  3. <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $db->insert('book', array( 'title' =>

    $_POST['title'], )); } ?> <html> <head><title>Add Book</title></head> <body> <form method="post"> <input type="text" name="title"> <!-- .... --> </form> </body> </html>
  4. WE NEED LIBRARY The boss tells you it’s time for

    the library feature… and we need to update books.
  5. <html> <head><title>My Libraries</title></head> <body> <ul class="libraries"> <?php $libraries = $db->select('...');

    foreach ($libraries as $library) { echo '<li><a href="/library/' . $library['id'] . '">' . $library['name'] . '</a></li>'; } ?> </ul> </body> </html>
  6. <?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $db->insert('library', array( 'name' =>

    $_POST['name'], )); } ?> <html> <head><title>Add Library</title></head> <body> <form method="post"> <input type="text" name="name"> <!-- .... --> </form> </body> </html>
  7. <?php $rs = $db->select('...'); $book = $rs[0]; if ($book &&

    $_SERVER['REQUEST_METHOD'] == 'POST') { $db->update('book', array( 'library_id' => $_POST['library_id'], 'title' => $_POST['title'], ), array( 'book_id' => $book['id'], )); } $libraries = $db->select('...'); ?> <html> <head><title>Update Book</title></head> <body> <form method="post"> <?php displaySelectFromDbResult('library_id', $libraries); ?>
  8. CONTROLLERS • Send commands to the model and sends information

    to the view. • It’s where your request and response are handled.
  9. <?php class BookController extends AbstractController { public function addAction() {

    $book = $this->model->insert(array( 'title' => $this->getPost('title') )); return array( 'book' => $book ); } }
  10. MODELS • Handles the state, persistence, data access and more.

    • Might have mappers and entities, it might not.. • It’s a loaded term.
  11. <?php class BookModel extends AbstractModel { public function insert(array $book)

    { $book['id'] = $this->db->insert('book', $book); return $book; } }
  12. <?php class BookModel extends AbstractModel { public function getId(); public

    function setId($id); public function getTitle(); public function setTitle($title); }
  13. VIEWS • Separating display from business logic • Escaping and

    handling what our controller is providing
  14. <?php $this->layout('main'); ?> <ul> <?php foreach ($books as $book): ?>

    <li><?php $this->escape($book->getTitle());?></ li> <?php endforeach; ?> </ul>
  15. BENEFITS OF A SERVICE LAYER • Better Controllers • Better

    Maintainability • Better Parallelism in Development • Better Testing/Fewer Defects • More Reuse
  16. <?php class BookController extends AbstractController { public function addBookAction() {

    $book = $this->bookService->addBook( $this->getPost('isbn'), $this->getPost('title'), $this->getPost('description') ); return $this->redirect('/book/' . $book- >getId()); } }
  17. SERVICES • Your application logic / business functionality • The

    in-between layer • The internal API to your application
  18. <?php class BookService extends AbstractService { public function addBook($isbn, $title,

    $description) { $book = new BookEntity(); $book->setIsbn($isbn); $book->setTitle($title); $book->setDescription($description); $this->mapper->addBook($book); return $book; } }
  19. DOMAIN MODELS • Describe a “thing” • Data object •

    Domain logic • Generally getters, setters
  20. <?php class Book extends AbstractEntity { public function getId(); public

    function setId($id); public function getIsbn(); public function setIsbn($isbn); public function getTitle(); public function setTitle($title); public function getDescription(); public function setDescription($description); }
  21. <?php class Book extends AbstractEntity { public function getTitle(); public

    function setTitle($title) { $trim = new TrimFilter(); $title = $trim->filter($title); $this->title = title; return $this; } }
  22. <?php class Book extends AbstractEntity { pubic function getTitle(); public

    function setTitle($title) { $trim = new TrimFilter(); $title = $trim->filter($title); $validate = new AlnumValidator(); if (!$validate->isValid($title)) { throw new InvalidArgumentException($validate->getMessage()); } $this->title = title; return $this; } }
  23. <?php class Book extends AbstractEntity { public function getInputFilter() {

    $input = new Input('title'); $input->getFilterChain() ->attachByName('stringtrim') ->attachByName('alphanumeric'); $input->getValidatorChain() ->attachByName('not_empty') ->attachByName('string_length', array('min' => 1, 'max' => 45)); $this->inputFilter->addInput($input); return $this->inputFilter; } }
  24. <?php class Book extends AbstractEntity { public function getTitle(); public

    function setTitle($title) { $inputFilter = $this->getInputFilter()- >getInput('title'); $inputFilter->setValue($title); if ($inputFilter->isValid()) { $this->title = $title; } throw new InvalidArgumentException($inputFilter- >getMessages()); } }
  25. DATA MAPPERS • Separates mapping data to a data store

    as well as your data model. • Data store can be anything or even multiple things.
  26. <?php class Book extends AbstractEntity { public function getId(); public

    function setId($id); public function getIsbn(); public function setIsbn($isbn); public function getTitle(); public function setTitle($title); public function getDescription(); public function setDescription($description); } <?php class Book extends AbstractEntity { public function getId(); public function setId($id); public function getIsbn(); public function setIsbn($isbn); public function getTitle(); public function setTitle($title); public function getDescription(); public function setDescription($description); }
  27. <?php class BookMapper extends AbstractMapper { public function addBook(BookEntity $book)

    { $this->bookRepository->save($book); $this->bookDetails->save($book); } }
  28. <?php class BookService extends AbstractService { public function findRecent() {

    if ($this->cache->has('book.recent')) { return $this->cache->get('book.recent'); } $results = $this->repository->findRecent(); $this->cache->set('book.recent', $results); return $results; } }
  29. DATA ACCESS OBJECTS • Or repositories in this case. •

    Allow us to target other areas to store data. • Allow for far better decoration • Things are looking up.
  30. <?php class BookRepository extends AbstractRepository { public function save($book) {

    if (!$book->getId()) { return $this->insert('book', $book); } return $this->update('book', $book, array( 'id' => $book->getId() )); } }
  31. <?php interface RepositoryInterface { public function save($entity); public function find($id);

    public function findBy($criteria); public function findOneBy($criteria); public function delete($entity); }
  32. DECORATOR PATTERN • Used to extend the functionality of a

    certain object. • Ultimately wrapping
  33. <?php class BookCacheRepository implements BookRepository { public function findRecent() {

    if ($this->cache->has('book.recent')) { return $this->cache->get('book.recent'); } $results = $this->delegateRepository- >findRecent(); $this->cache->set('book.recent', $results); return $results; } }
  34. return array( 'di' => array( 'BookService' => array( 'arguments' =>

    array( 'BookMapper', ), ), 'BookMapper' => array( 'arguments' => array( 'BookCacheRepository', ), ), 'BookCacheRepository' => array( 'arguments' => array( 'BookDbRepository', ), ), 'BookDbRepository' => array( 'arguments' => array( 'TableGateway', ),
  35. SO WHAT DOES THAT DO? • Creates an instance of

    TableGateway • Creates an instance of BookDbRepository • Then an instance of BookCacheRepository • Then an instance of BookMapper • Finally, an instance of BookService <?php $bookService = $container->get( ‘BookService’ );
  36. <?php if (php_sapi_name() == 'cli') { $router = $container->get('cliRouter'); }

    else { $router = $container->get('router'); } class BookCliController extends AbstractCliController { public function addBookAction(); }
  37. <?php class BookService extends AbstractService { public function addBook($isbn, $title,

    $description) { $book = new BookEntity(); $book->setIsbn($isbn); $book->setTitle($title); $book->setDescription($description); $this->mapper->addBook($book); $this->trigger('book.add', array('book' => $book)); return $book; } }
  38. <?php $bookService->attach('book.add', function($e) use ($mq) { $params = $e->getParams(); $book

    = $params['book']; $mq->sendMessage('book.add', array('book' => $book)); });
  39. JEFF BEZOS MANDATE • All teams will henceforth expose their

    data and functionality through service interfaces. • Teams must communicate with each other through these interfaces. • There will be no other form of interprocess communication allowed: no direct linking, no direct reads of another team’s data store, no shared-memory model, no back-doors whatsoever. The only communication allowed is via service interface calls over the network. • It doesn’t matter what technology they use. HTTP, Corba, Pubsub, custom protocols — doesn’t matter. • All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions. • Anyone who doesn’t do this will be fired. • Thank you; have a nice day!
  40. <?php $app->get('/api/book', 'ApiBookController.recentAction'); $app->put('/api/book', 'ApiBookController.addAction'); class ApiBookController extends RestfulController {

    public function recentAction() { return $this->bookService->findRecent(); } public function addAction() { return $this->bookService->addBook(...); } }
  41. <?php $server = new Zend\Json\Server\Server(); $server->setClass('BookService'); $server->handle(); <?php $server =

    new Zend\XmlRpc\Server(); $server->setClass('BookService'); echo $server->handle();
  42. • http://pixabay.com/en/architecture-iron-steel-building-414035/ • http://pixabay.com/en/home-demolition-destroyed-broken-557297/ • http://pixabay.com/en/disassembly-component-parts-336507/ • http://pixabay.com/en/taps-thread-drill-milling-444473/ • http://pixabay.com/en/light-bulb-transparent-light-body-629661/

    • http://pixabay.com/en/church-trappist-georgia-monastery-233564/ • http://pixabay.com/en/lego-site-build-replica-516557/ • http://pixabay.com/en/water-tap-wall-outside-exterior-243046/ • http://pixabay.com/en/question-mark-note-duplicate-457453/ • http://pixabay.com/en/door-entry-stone-opening-grid-208081/ • http://pixabay.com/en/onion-cut-fresh-tears-vegetable-161611/ • http://pixabay.com/en/petronas-towers-skyscraper-433081/ • http://pixabay.com/en/carbine-rope-hook-backup-climbing-7104/ • http://pixabay.com/en/code-program-source-computer-pc-113611/ • http://pixabay.com/en/kitchen-cabinets-countertop-granite-670247/ • http://pixabay.com/en/injecting-medical-shot-veins-519389/ • http://pixabay.com/en/books-shelf-retro-black-and-white-635341/ • http://pixabay.com/en/crayons-pencils-blurred-circle-311062/ • http://pixabay.com/en/soap-curd-soap-bathing-cleaning-390300/ • http://pixabay.com/en/helicopter-model-model-helicopter-195660/ • http://pixabay.com/en/bricks-roofing-house-building-420725/ • http://pixabay.com/en/parrot-ara-zoo-bird-beautiful-bill-655777/ • http://pixabay.com/en/gorilla-silverback-animal-448731/ • http://pixabay.com/en/crash-demolition-site-home-floors-214744/ • http://pixabay.com/en/beetle-beasts-field-insect-431125/ • http://en.wikipedia.org/wiki/File:MVC-Process.svg • http://pixabay.com/en/prairie-dog-small-cute-rodent-keep-320836/ • http://pixabay.com/en/key-lock-door-security-home-565607/ • http://pixabay.com/en/library-inside-wood-book-books-428034/ • http://pixabay.com/en/book-old-antique-pages-empty-pages-657637/ • http://pixabay.com/en/dirt-mess-messy-grungy-face-576491/ • http://pixabay.com/en/antique-box-collectible-electronic-21935/ • http://pixabay.com/en/processor-cpu-board-circuits-540254/ • http://pixabay.com/en/slug-shell-animals-wildlife-87037/ • http://pixabay.com/en/colour-pencils-color-paint-draw-450623/ • http://pixabay.com/en/mount-st-helens-volcanic-eruption-164848/ • http://pixabay.com/en/baby-tears-small-child-sad-cry-443393/ • http://pixabay.com/en/children-win-success-video-game-593313/ • http://pixabay.com/en/peas-pod-pea-pod-green-fresh-580333/ • http://pixabay.com/en/site-construction-work-support-592458/ • http://pixabay.com/en/chimney-sweeper-chimney-sweep-14035/ • https://pixabay.com/en/frog-relaxed-fig-funny-rest-914523/ Image Credits THANK YOU! http://joind.in/talk/view/15635