a resource oriented framework using the di/aop/rest triangle

76
A resource orientated framework using the DI /AOP/REST Triangle

Upload: akihito-koriyama

Post on 10-May-2015

4.193 views

Category:

Technology


1 download

DESCRIPTION

https://joind.in/talk/view/9302

TRANSCRIPT

Page 1: A resource oriented framework using the DI/AOP/REST triangle

A resource orientated frameworkusing the DI /AOP/REST Triangle

Page 2: A resource oriented framework using the DI/AOP/REST triangle

About Us

• Akihito Koriyama

• A Tokyo based freelance PHP architect

• BEAR.Sunday lead, Aura PHP member

• Richard McIntyre

• Manchester / leeds based freelance PHP developer

• BEAR.Sunday contributor, Lithium member

Page 3: A resource oriented framework using the DI/AOP/REST triangle

About Us

• Akihito Koriyama

• A Tokyo based freelance PHP architect

• BEAR.Sunday lead, Aura PHP member

• Richard McIntyre

• Manchester / Leeds based freelance PHP developer

• BEAR.Sunday contributor, Lithium member

Page 4: A resource oriented framework using the DI/AOP/REST triangle
Page 5: A resource oriented framework using the DI/AOP/REST triangle

BEAR.Sunday is an application framework.But it offers no libraries.

(We have good stuff)

Page 6: A resource oriented framework using the DI/AOP/REST triangle

instead, it offers three object frameworks.

Page 7: A resource oriented framework using the DI/AOP/REST triangle

What is a framework ?

Page 8: A resource oriented framework using the DI/AOP/REST triangle

“imposes a set of design constraints on end-user code.”

Page 9: A resource oriented framework using the DI/AOP/REST triangle
Page 10: A resource oriented framework using the DI/AOP/REST triangle
Page 11: A resource oriented framework using the DI/AOP/REST triangle

3.hypermedia framework

Page 12: A resource oriented framework using the DI/AOP/REST triangle

DI

AOP

REST

Page 13: A resource oriented framework using the DI/AOP/REST triangle

DI Benefits

• Dependency Inversion Principle

• Clear separation of object instantiation and object usage

• Object delivery

Page 14: A resource oriented framework using the DI/AOP/REST triangle

DIP

• Code should depend on things that are at the same or higher level of abstraction

• High level policy should not depend on low level details

Page 15: A resource oriented framework using the DI/AOP/REST triangle

“The principle of dependency inversion is at the root of many of the benefits claimed for object-oriented technology.

Its proper application is necessary for the creation of reusable frameworks”

Page 16: A resource oriented framework using the DI/AOP/REST triangle

Ray.DI

Dependency Injection Framework

Page 17: A resource oriented framework using the DI/AOP/REST triangle

/** * @Inject */ public function __construct(RenderInterface $renderer) { ...

1.annotate at injection point

class RendererModule extends AbstractModule{ protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON);}

$injector = Inject::create([new RendererModule]];

2 bind abstraction to concretion

3.create an injector

Page 18: A resource oriented framework using the DI/AOP/REST triangle

/** * @Inject */ public function __construct(RenderInterface $renderer) { ...

1.annotate at injection point

class RendererModule extends AbstractModule{ protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON);}

$injector = Inject::create([new RendererModule]];

2. bind abstraction to concretion

3.create an injector

Page 19: A resource oriented framework using the DI/AOP/REST triangle

/** * @Inject */ public function __construct(RenderInterface $renderer) { ...

1.annotate at injection point

class RendererModule extends AbstractModule{ protected function configure() { $this->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON);}

$injector = Inject::create([new RendererModule]];

2 bind abstraction to concretion

3.create an injector

Page 20: A resource oriented framework using the DI/AOP/REST triangle

$user = $injector->getInstance('UserInterface');

4. Get an object graph from the $injector

User RendererRenderer Interface

depends

A

B

Page 21: A resource oriented framework using the DI/AOP/REST triangle

procedural

object orietnedcompilation

runtime

Implement the structure, not a procedure

Page 22: A resource oriented framework using the DI/AOP/REST triangle

class RendererModule extends AbstractModule{ protected function configure() { $this ->bind('RenderInterface') ->to('HalRenderer') ->in(Scope::SINGLETON); }}

Only use concrete classes in compilation

Page 23: A resource oriented framework using the DI/AOP/REST triangle

Only abstraction in runtime

/** * @Inject */ public function __construct(RenderInterface $renderer) {

Page 24: A resource oriented framework using the DI/AOP/REST triangle

DI Best practice“Your code should deal directly with the Injector as little as possible. Instead, you want to bootstrap your application by injecting one root object.”

Page 25: A resource oriented framework using the DI/AOP/REST triangle

Application = one root object

Page 26: A resource oriented framework using the DI/AOP/REST triangle

Application class

Page 27: A resource oriented framework using the DI/AOP/REST triangle
Page 28: A resource oriented framework using the DI/AOP/REST triangle

Application is root object

retrieved with injector:

$injector = Inject::create([new AppModule($context)]];$app = $injector->getInstance(‘AppInterface’);

Page 29: A resource oriented framework using the DI/AOP/REST triangle

Application has dependency.

Page 30: A resource oriented framework using the DI/AOP/REST triangle
Page 31: A resource oriented framework using the DI/AOP/REST triangle

Dependencies have other dependencies

Each object either contains or belongs to.

Page 32: A resource oriented framework using the DI/AOP/REST triangle

You get a application object graph.

huge, but can be stored one single root value $app

Page 33: A resource oriented framework using the DI/AOP/REST triangle

Application can be serialized.

$app can be serialized and stored

Injection is reused beyond requests.

Page 34: A resource oriented framework using the DI/AOP/REST triangle

$app

Object

i/f

i/f

Objecti/f i/f

ObjectRouter

Response

JSON

XML

1st framework: DI Framework

• annotations based DI framework w/ binding DSL

• compilation / runtime separation

• use only “plug/abstraction” at runtime

• application a single large cached object

• focus on structure not behavior

Page 35: A resource oriented framework using the DI/AOP/REST triangle

Aspect Oriented Programing

Page 37: A resource oriented framework using the DI/AOP/REST triangle

/** * @Cache */ public function onGet($id) { // ... $this->body = $stmt->fetchAll(PDO::FETCH_ASSOC); return $this; }

class Post extends AppModel {

public function newest() { $result = Cache::read('newest_posts', 'longterm'); if (!$result) { $result = $this->find('all'); Cache::write('newest_posts', $result, 'longterm'); } return $result; }}

Page 38: A resource oriented framework using the DI/AOP/REST triangle

MC

I I

AOP

Page 39: A resource oriented framework using the DI/AOP/REST triangle

MC

Cache

Cache is called by method invocation,If the cache is warm the model is never called.

$obj->read(2);

Miss !

Page 40: A resource oriented framework using the DI/AOP/REST triangle

Aspects

Core Concern Cross Cutting Concern

Separation

Page 41: A resource oriented framework using the DI/AOP/REST triangle

Rock Concert Example

Page 42: A resource oriented framework using the DI/AOP/REST triangle

interface MethodInterceptor{ public function invoke(MethodInvocation $invocation); }

$invocation->proceed(); // invoked method$object = $invocation->getThis(); // get source object$args = $invocation->getArgs(); // get arguments

Page 43: A resource oriented framework using the DI/AOP/REST triangle

class Transactional implements MethodInterceptor{ public function invoke(MethodInvocation $invocation) { $object = $invocation->getThis(); $ref = new ReflectionProperty($object, 'db'); $ref->setAccessible(true); $db = $ref->getValue($object); $db->beginTransaction(); try { $invocation->proceed(); $db->commit(); } catch (Exception $e) { $db->rollback(); } }}

`Transactional`interceptor

Core Concern

Cross Cutting Concern

Page 44: A resource oriented framework using the DI/AOP/REST triangle

class CacheInterceptor implements MethodInterceptor{ public function invoke(MethodInvocation $invocation) { $obj = $invocation->getThis(); $args = $invocation->getArguments(); $id = get_class($obj) . serialize($args); $saved = $this->cache->fetch($id); if ($saved) { return $saved; } $result = $invocation->proceed(); $this->cache->save($id, $result); return $result; }}

`Cache`interceptor

Core Concern

Cross Cutting Concern

Page 45: A resource oriented framework using the DI/AOP/REST triangle

Simply annotate,then create your binding

Bind

Page 46: A resource oriented framework using the DI/AOP/REST triangle

Layering by context

• MVC, Is 3 enough ?

Page 47: A resource oriented framework using the DI/AOP/REST triangle

APIClient

Page 48: A resource oriented framework using the DI/AOP/REST triangle

API LogClient Valid Auth

Page 49: A resource oriented framework using the DI/AOP/REST triangle

API Log

@Valid

/admin DELETE

Client Valid Auth

Page 50: A resource oriented framework using the DI/AOP/REST triangle

Aspect layering by context

Model

Cache

FormTransactionAuth

Validation

Page 51: A resource oriented framework using the DI/AOP/REST triangle

<?php class SandboxResourcePageIndexRay0000000071f9ab280000000033fb446fAop extends Sandbox\Resource\Page\Index implements Ray\Aop\WeavedInterface{ private $rayAopIntercept = true; public $rayAopBind; public function onGet() { // native call if (!isset($this->rayAopBind[__FUNCTION__])) { return call_user_func_array('parent::' . __FUNCTION__, func_get_args()); } // proceed source method from interceptor if (!$this->rayAopIntercept) { $this->rayAopIntercept = true; return call_user_func_array('parent::' . __FUNCTION__, func_get_args()); } // proceed next interceptor $this->rayAopIntercept = false; $interceptors = $this->rayAopBind[__FUNCTION__]; $annotation = isset($this->rayAopBind->annotation[__FUNCTION__]) ? $this->rayAopBind->annotation[__FUNCTION__] : null; $invocation = new \Ray\Aop\ReflectiveMethodInvocation(array($this, __FUNCTION__), func_get_args(), $interceptors, $annotation); return $invocation->proceed(); }

Under the hood: Method interception sub class is created in order enable this interception and keep type safety.

Page 52: A resource oriented framework using the DI/AOP/REST triangle

Runtime injection by aspect

• method / parameter lookup

• test friendly

Page 53: A resource oriented framework using the DI/AOP/REST triangle

2nd framework: Aspect Oriented Framework

• AOP alliance standard

• Layering by context

• Type safe

• Runtime injection

Page 54: A resource oriented framework using the DI/AOP/REST triangle
Page 55: A resource oriented framework using the DI/AOP/REST triangle

Hypermedia framework for object as a service

It allows objects to have RESTful web service benefits such as client-server, uniform interface, statelessness, resource expression with mutual connectivity and layered components.

Page 56: A resource oriented framework using the DI/AOP/REST triangle

class Author extends ResourceObject{ public $code = 200; public $headers = []; public $body = [];

/** * @Link(rel="blog", href="app://self/blog/post?author_id={id}") */ public function onGet($id) { ... // change own state return $this; }

public function onPost($name) { $this->code = 201; // created return $this; }

public function onPut($id, $name) { //... }

public function onDelete($id) { //... }

Page 57: A resource oriented framework using the DI/AOP/REST triangle

$user = $resource ->get ->uri('app://self/user') ->withQuery(['id' => 1]) ->eager ->request();

var_dump($user->body);

// Array// (// [name] => John// [age] => 15//)

echo $user;

// <div id=”name”>John</div>// <div id=”age”>15</div>

public function onGet($id) { $this[‘name’] = ‘John’; $this[‘age’] = 15;

return $this; }

User

Profile

Friend

Page 58: A resource oriented framework using the DI/AOP/REST triangle

$order = $resource ->post ->uri('app://self/order') ->withQuery(['drink' => 'latte']) ->eager ->request();

$payment = [ 'credit_card_number' => '123456789', 'expires' => '07/07', 'name' => 'Koriym', 'amount' => '4.00' ];

// Now use a hyperlink to pay $response = $resource->href('pay', $payment);

echo $response->code; // 201

Hypermedia as the Engine of Application State

Page 59: A resource oriented framework using the DI/AOP/REST triangle

class Order extends ResourceObject{ /** * * @Link(rel="pay", method="put", href="app://self/payment{?order_id,card_number,amount}") */ public function onPost($drink) { // data store here $this['drink'] = $drink; $this['order_id'] = $orderId;

// created $this->code = 201;

return $this; }

Hypermedia as the Engine of Application State

Page 60: A resource oriented framework using the DI/AOP/REST triangle

Order Payment

hyper reference: pay

HyperMedia Driven API

Page 61: A resource oriented framework using the DI/AOP/REST triangle

The key of success of web

• URI

• Unified Interface

• Hyperlink

Page 62: A resource oriented framework using the DI/AOP/REST triangle

• API is hub

• API is core value

API driven development

DB Mobile

Web

API

Cloud

Mock

URI

API

API

Page 64: A resource oriented framework using the DI/AOP/REST triangle

Layered Resource

UIMobile

Web

Page Resource

App script

App Resource

Entity

Page 65: A resource oriented framework using the DI/AOP/REST triangle
Page 66: A resource oriented framework using the DI/AOP/REST triangle
Page 67: A resource oriented framework using the DI/AOP/REST triangle
Page 68: A resource oriented framework using the DI/AOP/REST triangle
Page 69: A resource oriented framework using the DI/AOP/REST triangle

Performance

• annotation ? dependency injection ? method interception ? DSL ? named parameter ?

• Fast

• cache all compiled object

• http friendly architecture

Page 70: A resource oriented framework using the DI/AOP/REST triangle

Scale

• “model proxy” pattern

• ‘app://self/blog/entry’ can be anything.

• contextual injection makes db scale easy

Page 71: A resource oriented framework using the DI/AOP/REST triangle

Hard spot / Soft spot

• DI configure hardspot. per system

• Aop configure softspot, change on request

Page 72: A resource oriented framework using the DI/AOP/REST triangle

Connecting frameworks

• DI - object as dependency

• AOP - domain logic to application logic

• Hypermedia - resource to resource

Page 73: A resource oriented framework using the DI/AOP/REST triangle

Abstraction frameworks

• DSL

• Annotation

• URI

• Interface

• Aspects

• Hypermedia

Page 74: A resource oriented framework using the DI/AOP/REST triangle
Page 75: A resource oriented framework using the DI/AOP/REST triangle

“Zen” framework

Page 76: A resource oriented framework using the DI/AOP/REST triangle

Thanks.Arigato

http://www.flickr.com/photos/stevehoad/4678289858/

@mackstar@koriym