spout - building a restful web app with angular.js and bear.sunday

46
BUILDING A RESTFUL WEB APP WITH ANGULAR.JS AND BEAR.SUNDAY

Upload: richard-mcintyre

Post on 27-Aug-2014

1.047 views

Category:

Software


1 download

DESCRIPTION

Spout is a RESTful CMS created with Angular.js and BEAR.Sunday, we are just getting started but here is your your chance to get involved in a new CMS project.

TRANSCRIPT

Page 1: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

BUILDING A RESTFUL WEB APP WITHANGULAR.JS AND BEAR.SUNDAY

Page 2: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

RICHARD MCINTYRE@MACKSTAR

Page 3: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Page 4: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

GOAL RESTFUL CMSFRONT-END ANGULAR.JSBACK-END BEAR.SUNDAY

Page 5: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

WHY ANOTHER CMS?

▸ Building RESOURCES▸ Power through simplicity▸ Easy overrides with AOP▸ Kill plugin culture

▸ Build re-usable libraries

Page 6: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

CONTINUED...

▸ Embed in any PHP project▸ Testable

▸ Relationships between resources / Hypermedia▸ Templating through TWIG

Page 7: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

BEAR.SUNDAY▸ REST▸ DI▸ AOP

Page 8: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

In most MVC application frameworks, CRUD and OOP paradigms are mapped

to HTTP methods and resources. But the opposite is not true. - Akihito Koriyama

Page 9: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

EVERYTHING IS A RESOURCERequest: /api/resources/index?_start=1

Request Method: GETStatus Code: 200 OK

Page 10: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

{ "resources": [ { "id": "16", "slug": "2332", "type": "blog", "title": "2332", "type_name": "Blog", "title_label": "Title" } ], "_model": "resources", "_pager": { "maxPerPage": 5, "current": "1", "total": 1, "hasNext": false, "hasPrevious": false }, "_links": { "self": { "href": "spout/app/resources/index/?_start=1" } }}

Page 11: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

Request: /api/resources/typesRequest Method: POSTStatus Code: 200 OK

Page 12: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

{ "title_label": "Title", "resource_fields": [ { "field_type": { "id": "1", "name": "String", "slug": "string" }, "multiple": 0, "weight": 1, "label": "Body", "slug": "body" } ], "name": "Page", "slug": "page"}

Page 13: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

Request: /api/menus/links?menu=primaryRequest Method: GETStatus Code: 200 OK

Page 14: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

{ "links": [ { "id": "6", "name": "Link 1", "url": "/url1", "type": "url", "resource": null, "resource_type": null, "weight": "999", "depth": null, "parent_id": "0", "menu": "primary" }, { "id": "7", "name": "Link 2", "url": "/url2", "type": "url", "resource": null, "resource_type": null, "weight": "999", "depth": null, "parent_id": "0", "menu": "primary" } ], "_model": "links"}

Page 15: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

namespace Mackstar\Spout\Admin\Resource\App\Resources;

/** * Resources Index * * @Db */class Index extends ResourceObject{

/** * @Link(rel="type", href="app://self/resources/detail?type={slug}&slug={slug}") * @DbPager(5) */ public function onGet() { $sql = "SELECT {$this->table}.*, type.name as type_name, type.title_label FROM {$this->table} "; $sql .= "INNER JOIN resource_types AS type "; $sql .= "ON type.slug = {$this->table}.type";

$stmt = $this->db->query($sql); $this['resources'] = $stmt->fetchAll(PDO::FETCH_ASSOC);

return $this; }

Page 16: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

CUSTOM RESOURCES CAN CALL OTHER RESOURCES

public function onGet($id = null) { $this['types'] = $this->resource->get->uri('app://self/resources/types') }

RESOURCES OF A TYPE HAVE RESOURCE AND RESOURCE INDEX RELATIONSHIPS

Page 17: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

OVERRIDES THROUGH AOP▸ Validation▸ Permissions

▸ Template Switching▸ Other custom events

Page 18: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

DEPENDENCIESINJECTED

Page 19: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

namespace Mackstar\Spout\Admin\Interceptor\Users;

use Ray\Aop\MethodInterceptor;use Ray\Aop\MethodInvocation;use Ray\Di\Di\Inject;use Symfony\Component\HttpFoundation\Session\Session as PhpSession;

class Session implements MethodInterceptor{

private $session;

/** * @Inject */ public function setSession(PhpSession $session) { $this->session = $session; }

public function invoke(MethodInvocation $invocation) { $response = $invocation->proceed(); $response->body['_user'] = $this->session->get('user'); return $response; }

Page 20: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

BIND USING MODULES

Page 21: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

private function installUserSessionAppender() { $session = $this->requestInjection('\Mackstar\Spout\Admin\Interceptor\Users\Session');

$this->bindInterceptor( $this->matcher->subclassesOf('BEAR\Resource\ResourceObject'), $this->matcher->startsWith('onGet'), [$session] ); }

Page 22: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

TESTS

Page 23: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

namespace Mackstar\Spout\Admin\Test\Interceptor\Validators;

use Mackstar\Spout\Admin\Interceptor\Validators\UserValidator;

class UserValidatorTest extends \PHPUnit_Framework_TestCase{

public function testErrorsWhenNoEmailIsPassedIn() { ... }}

Page 24: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

FRONT-END INTEGRATION{{ resource | app://spout/resources/detail?type=photo-gallery&slug=spout-is-live | detail-blog.twig }}

Page 25: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

PAGINATION{{ resource | app://spout/resources/index?type=blog | index-blog.twig | paged(1)}}

Page 26: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

MENU{{ resource | app://spout/menus?slug=primary | primary-menu.twig}}

Page 27: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

ARCHITECTURE

Page 28: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Page 29: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Page 30: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Page 31: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

ANGULAR.JSADMIN

Page 32: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

BE YOUR OWNCONSUMER

Page 33: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

COMPONENTS▸ Routes▸ Directives▸ Controllers▸ Services

Page 34: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

2 WAY DATA BINDING

Page 35: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

TEMPLATE<input type="email" ng-model="login.email" required>

CONTROLLERscope.$watch('login.email', function () { console.log("Login Email Changed To:" + scope.login.email);});

Page 36: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

ROUTESANGULAR-UI ROUTER

Page 37: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

app.config(['$stateProvider', function($stateProvider) {

$stateProvider.state('login', { url: "/login", controller: 'LoginCtrl', templateUrl: '/js/templates/login/index.html', resolve: { authentication: ['Restangular', function (Restangular) { return Restangular.all('users/authenticate'); }] } }) .state('logout', { url: "/logout", controller: "LogoutCtrl", resolve: { authenticate: ['Restangular', function (Restangular) { return Restangular.all('users/authenticate'); }] } });

}]);

Page 38: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

DIRECTIVES<SP-THUMBNAIL />

Page 39: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

app.directive('spThumbnail', function (Restangular) { return { restrict: 'E', template: "<img src='/img/spinner.gif' ng-click='select()' />", scope: { media: "=media"}, replace: true, link: function(scope, element, attrs) {

var src = '/uploads/media/' + scope.media.directory + '/140x140_' + scope.media.file, img = new Image();

function loadImage() { element[0].src = src; }

img.src = src; img.onerror = function() { Restangular.all('media/resize').post( {media: scope.media, height: 140, width: 140} ).then(function() { loadImage(); }); };

...

Page 40: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

DEPENDENCY INJECTION

Page 41: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

Declarevar module = angular.module('restangular', []);module.provider('Restangular', function() {}

Implementvar app = angular.module('myApp', ['restangular']);

app.controller('MyController', ['Restangular', function (Restangular) { Restangular.all('users/authenticate').get().then(function(auth) { ... });}]);

Page 42: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

TESTS

Page 43: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

describe('Roles Directive', function () {

var scope, $element;

beforeEach(function () { module('Application'); angular.mock.inject( function ($rootScope, $compile) { var element = angular.element('<roles-selector></roles-selector>'); scope = $rootScope; scope.roles = [{"id": 1, "name": "Admin"},{"id": 2, "name": "Contributor"}]; $compile(element)(scope); scope.$digest(); $element = $(element); } ); });

it('should have a select menu', function () { expect($element.prop("tagName")).toEqual('SELECT'); expect($element.find("option").length).toBe(2); });

Page 44: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

DEMO

Page 45: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

STUFF TO DO▸ Security

▸ DB/API Schema lock-down▸ Create as composer component / Assetic▸ More field types (locations/times/md etc)

▸ Blocks▸ Get others input

Page 46: Spout - Building a RESTful web app with Angular.js and BEAR.Sunday

GET INVOLVEDGITHUB.COM/MACKSTAR/SPOUT