Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

@endel twitter.com/endel github.com/endel endel.dreyer@gmail.com

Slide 3

Slide 3 text

The problem • Projets with short delivery time (<1 month) • Repetitive back-end code • Lack of front-end integration standards

Slide 4

Slide 4 text

Backend as a Service • baasbox/baasbox - Java • deployd/deployd - NodeJS / MongoDB • hoodiehq/hoodie.js - NodeJS / CouchDB • parse.com - Closed source / $$$$$ • doubleleft/hook - PHP / MySQL

Slide 5

Slide 5 text

hook • REST API • Data persistance (CRUD) • MySQL / PostgreSQL / MSSQL / MongoDB • User authentication • Extensible

Slide 6

Slide 6 text

Installation • Dependencies: PHP 5.5+ / node 0.12+ • github.com/doubleleft/hook $ curl -sSL https:// raw.githubusercontent.com/ doubleleft/hook/master/scripts/ install.sh | bash

Slide 7

Slide 7 text

WTF backend?

Slide 8

Slide 8 text

Static Web Apps • “Static Web Applications run independently of the need for server-side dynamic processing.” • “Static web architecture eases common web development headaches without introducing additional complexity.” • http://www.staticapps.org/

Slide 9

Slide 9 text

Static Web Apps

Slide 10

Slide 10 text

Getting started • Back-end (doubleleft/hook) • Command-line Interface (doubleleft/hook- cli) • Front-end (doubleleft/hook-javascript)

Slide 11

Slide 11 text

Getting started $ hook app:new tdc2015

Slide 12

Slide 12 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully.

Slide 13

Slide 13 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Collection’s exposure level

Slide 14

Slide 14 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Back-end dependencies (Composer)

Slide 15

Slide 15 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Crontab

Slide 16

Slide 16 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Database migration

Slide 17

Slide 17 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Back-end configurations (smtp, oauth, etc)

Slide 18

Slide 18 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Configurations per environment (“development”)

Slide 19

Slide 19 text

Getting started $ hook app:new tdc2015 create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.development.yaml create hook-ext/credentials/development/cli.json create hook-ext/credentials/development/browser.json create hook-ext/credentials/development/device.json create hook-ext/credentials/development/server.json Application created successfully. Application credentials (“development”)

Slide 20

Slide 20 text

Getting started $ hook app:new tdc2015 —environment production create hook-ext/security.yaml create hook-ext/packages.yaml create hook-ext/schedule.yaml create hook-ext/schema.yaml create hook-ext/config/config.yaml create hook-ext/config/config.production.yaml create hook-ext/credentials/production/cli.json create hook-ext/credentials/production/browser.json create hook-ext/credentials/production/device.json create hook-ext/credentials/production/server.json Application created successfully. Environment-specific files (“production”)

Slide 21

Slide 21 text

App Credentials • cli - deploy, seed, full-access • browser - for web applications • device - for mobile applications • server - for server-to-server communication

Slide 22

Slide 22 text

App Credentials • cli - deploy, seed, full-access • browser - para uso em webapps • device - para uso em mobiles • server - para comunicação server-to-server KEEP IT SAFE!!!!!1111

Slide 23

Slide 23 text

Front-end • Friendly API • HTTP Requests • Status Codes

Slide 24

Slide 24 text

JavaScript Client var hook = new Hook.Client({ endpoint: "http://localhost:4665/", app_id: 1, key: "c2cee0f2575e3547315e123ddfbe8029" });

Slide 25

Slide 25 text

JavaScript Client var hook = new Hook.Client({ endpoint: process.env.HOOK_ENDPOINT, app_id: process.env.HOOK_APP_ID, key: process.env.HOOK_BROWSER_KEY });

Slide 26

Slide 26 text

Collections • Database table • Typed attributes • Automatic migrations • File upload • Security rules (security.yaml)

Slide 27

Slide 27 text

Collections API • #create • #where • #update • #remove • #then / #first

Slide 28

Slide 28 text

collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford" })

Slide 29

Slide 29 text

collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford" }) Promise

Slide 30

Slide 30 text

collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford" }).then(function(book) { console.log(book._id, book.name) console.log(book.author) console.log(book.created_at) }).otherwise(function(error) { console.log(error) })

Slide 31

Slide 31 text

collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford" }).then(function(book) { console.log(book._id, book.name) console.log(book.author) console.log(book.created_at) }).otherwise(function(error) { console.log(error) }) Success

Slide 32

Slide 32 text

collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford" }).then(function(book) { console.log(book._id, book.name) console.log(book.author) console.log(book.created_at) }).otherwise(function(error) { console.log(error) }) Error

Slide 33

Slide 33 text

collection().where hook.collection('books'). where("author", "Douglas Crockford")

Slide 34

Slide 34 text

collection().where hook.collection('books'). where("author", "Douglas Crockford") Hook.Collection

Slide 35

Slide 35 text

collection().where hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%") Hook.Collection

Slide 36

Slide 36 text

collection().then hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). then(function(rows) { console.log(rows.length) // => 1 console.log(rows[0].name) // => "JavaScript: The Good Parts" })

Slide 37

Slide 37 text

collection().then hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). then(function(rows) { console.log(rows.length) // => 1 console.log(rows[0].name) // => "JavaScript: The Good Parts" }) Array

Slide 38

Slide 38 text

collection().first hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). first(function(row) { console.log(row.name) // => "JavaScript: The Good Parts" console.log(row._id) // => 1 })

Slide 39

Slide 39 text

collection().first hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). first(function(row) { console.log(row.name) // => "JavaScript: The Good Parts" console.log(row._id) // => 1 }) Object

Slide 40

Slide 40 text

hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). remove(function(data) { console.log(data.success) // => 1 }) collection().remove

Slide 41

Slide 41 text

hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). remove(function(data) { console.log(data.success) // => 1 }) collection().remove Object

Slide 42

Slide 42 text

collection().update hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). update({ isbn: "978-0-596-51774-8" }). then(function(data) { console.log(data.success) // => true console.log(data.affected) // => 1 })

Slide 43

Slide 43 text

hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). update({ isbn: "978-0-596-51774-8" }). then(function(data) { console.log(data.success) // => true console.log(data.affected) // => 1 }) collection().update

Slide 44

Slide 44 text

hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). update({ isbn: "978-0-596-51774-8" }). then(function(data) { console.log(data.success) // => true console.log(data.affected) // => 1 }) collection().update hook-ext/security.yaml

Slide 45

Slide 45 text

hook-ext/ security.yaml

Slide 46

Slide 46 text

hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). update({ isbn: "978-0-596-51774-8" }). then(function(data) { console.log(data.success) // => true console.log(data.affected) // => 1 }) collection().update Object

Slide 47

Slide 47 text

Seeding $ hook generate:seed books ... Seed created at 'hook-ext/seeds/books.yaml'.

Slide 48

Slide 48 text

Seeding

Slide 49

Slide 49 text

Seeding TRUNCATE TABLE `books`

Slide 50

Slide 50 text

Seeding New rows

Slide 51

Slide 51 text

Seeding $ hook db:seed ... Truncating 'books'... Success. Seeding 'books': 100% Done.

Slide 52

Slide 52 text

Console $ hook console

Slide 53

Slide 53 text

( thnks node <3 )

Slide 54

Slide 54 text

Schema • Database definitions / migrations • Collection data types • Collection relationships • Serves as documentation

Slide 55

Slide 55 text

schema.yaml

Slide 56

Slide 56 text

schema.yaml CREATE / UPDATE attribute

Slide 57

Slide 57 text

schema.yaml Disable automatic migrations

Slide 58

Slide 58 text

schema.yaml Relationships: - belongs_to - has_one - has_many - has_many (though) View the documentation!

Slide 59

Slide 59 text

schema.yaml hook.collection('books'). join('author'). first(function(book) { console.log(book.name) console.log(book.author.name) })

Slide 60

Slide 60 text

schema.yaml hook.collection('books'). join('author'). first(function(book) { console.log(book.name) console.log(book.author.name) })

Slide 61

Slide 61 text

schema.yaml

Slide 62

Slide 62 text

Authentication • Auth • OAuth (plugin)

Slide 63

Slide 63 text

Authentication API • #register • #login • #logout • #update • #currentUser

Slide 64

Slide 64 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 65

Slide 65 text

auth.register() Promise hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 66

Slide 66 text

auth.register() Required hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 67

Slide 67 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Registered!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 68

Slide 68 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Registered!", auth) }).otherwise(function(data) { console.log(data.error) }) Object

Slide 69

Slide 69 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Registered!", auth) }).otherwise(function(data) { console.log(data.error) }) Object

Slide 70

Slide 70 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Registered!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 71

Slide 71 text

auth.register() hook.auth.register({ email: "endel.dreyer@gmail.com", password: "" }).then(function(auth) { console.log("Registered!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 72

Slide 72 text

auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 73

Slide 73 text

auth.login() Promise hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 74

Slide 74 text

auth.login() Required hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" })

Slide 75

Slide 75 text

auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 76

Slide 76 text

auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) }) Object

Slide 77

Slide 77 text

auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" }).then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) }) Object

Slide 78

Slide 78 text

auth.login() hook.auth.login({ email: "404@gmail.com", password: "12345678" }).then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 79

Slide 79 text

auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "not my password" }).then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 80

Slide 80 text

auth.update() hook.auth.update({ birthdate: "26/05/1990" }).then(function(auth) { // success }).otherwise(function(data) { // failure })

Slide 81

Slide 81 text

auth.update() hook.auth.update({ birthdate: "1990-26-05" }).then(function(auth) { // success }).otherwise(function(data) { // failure })

Slide 82

Slide 82 text

OAuth • JavaScript Plugin • 3rd party service configuration (hook-ext/ config.yaml) • Dependency (hook-ext/packages.yaml) hook.oauth.popup('facebook').then(function(auth) { console.log("Logged in!", auth) }).otherwise(function(data) { console.log(data.error) })

Slide 83

Slide 83 text

user data

Slide 84

Slide 84 text

user data hook.collection('items').create({ auth_id: hook.auth.currentUser._id, name: "User item" })

Slide 85

Slide 85 text

user data hook.collection('items').create({ auth_id: hook.auth.currentUser._id, name: "User item" }) owner

Slide 86

Slide 86 text

user data hook-ext/security.yaml

Slide 87

Slide 87 text

user data hook-ext/security.yaml

Slide 88

Slide 88 text

Extending the back- end • Routes • Observers • Schedule • Composer packages

Slide 89

Slide 89 text

Routes $ hook generate:route last_posts ... Route created at ‘hook-ext/routes/ get_last_posts.php'.

Slide 90

Slide 90 text

Routes

Slide 91

Slide 91 text

Routes

Slide 92

Slide 92 text

Routes hook.get('last_posts').then(...)

Slide 93

Slide 93 text

Schedule hook-ext/schedule.yaml

Slide 94

Slide 94 text

Schedule

Slide 95

Slide 95 text

(php is ugly sry)

Slide 96

Slide 96 text

(php is ugly sry)

Slide 97

Slide 97 text

(php is ugly sry)

Slide 98

Slide 98 text

(php is ugly sry)

Slide 99

Slide 99 text

(php is ugly sry)

Slide 100

Slide 100 text

Collection observers • toArray • creating / created • updating / updated • saving / saved • deleting / deleted

Slide 101

Slide 101 text

Observers $ hook generate:observer auth name); $message->from(Config::get('email.from')) ->to($model->email) ->subject("Welcome") ->send(); } }

Slide 102

Slide 102 text

Observers $ hook generate:observer auth name);

Slide 103

Slide 103 text

Composer packages • PHP’s Package Manager

Slide 104

Slide 104 text

Composer packages • PHP’s Package Manager

Slide 105

Slide 105 text

Clients • JavaScript • Corona SDK • C# (Unity) • Android • C++ • …

Slide 106

Slide 106 text

DEMO • hook-admin 
 
 https://github.com/doubleleft/hook-admin

Slide 107

Slide 107 text

Thanks! twitter.com/endel github.com/endel endel.dreyer@gmail.com