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

#TDC2015: Know hook and how to use it

#TDC2015: Know hook and how to use it

My speech about hook at The Developers Conference 2015, Brazil (Front-end track)

https://github.com/doubleleft/hook

C35f590e9178794d7f4c4f07192d3772?s=128

Endel Dreyer

July 21, 2015
Tweet

Transcript

  1. None
  2. @endel twitter.com/endel github.com/endel endel.dreyer@gmail.com

  3. The problem • Projets with short delivery time (<1 month)

    • Repetitive back-end code • Lack of front-end integration standards
  4. Backend as a Service • baasbox/baasbox - Java • deployd/deployd

    - NodeJS / MongoDB • hoodiehq/hoodie.js - NodeJS / CouchDB • parse.com - Closed source / $$$$$ • doubleleft/hook - PHP / MySQL
  5. hook • REST API • Data persistance (CRUD) • MySQL

    / PostgreSQL / MSSQL / MongoDB • User authentication • Extensible
  6. 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
  7. WTF backend?

  8. 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/
  9. Static Web Apps

  10. Getting started • Back-end (doubleleft/hook) • Command-line Interface (doubleleft/hook- cli)

    • Front-end (doubleleft/hook-javascript)
  11. Getting started $ hook app:new tdc2015

  12. 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.
  13. 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
  14. 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)
  15. 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
  16. 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
  17. 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)
  18. 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”)
  19. 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”)
  20. 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”)
  21. App Credentials • cli - deploy, seed, full-access • browser

    - for web applications • device - for mobile applications • server - for server-to-server communication
  22. 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
  23. Front-end • Friendly API • HTTP Requests • Status Codes

  24. JavaScript Client var hook = new Hook.Client({ endpoint: "http://localhost:4665/", app_id:

    1, key: "c2cee0f2575e3547315e123ddfbe8029" });
  25. 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 });
  26. Collections • Database table • Typed attributes • Automatic migrations

    • File upload • Security rules (security.yaml)
  27. Collections API • #create • #where • #update • #remove

    • #then / #first
  28. collection().create hook.collection('books').create({ name: "JavaScript: The Good Parts", author: "Douglas Crockford"

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

    }) Promise
  30. 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) })
  31. 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
  32. 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
  33. collection().where hook.collection('books'). where("author", "Douglas Crockford")

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

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

  36. 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" })
  37. 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
  38. 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 })
  39. 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
  40. hook.collection('books'). where("author", "Douglas Crockford"). where("name", "like", "%javascript%"). remove(function(data) { console.log(data.success)

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

    // => 1 }) collection().remove Object
  42. 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 })
  43. 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
  44. 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
  45. hook-ext/ security.yaml

  46. 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
  47. Seeding $ hook generate:seed books ... Seed created at 'hook-ext/seeds/books.yaml'.

  48. Seeding

  49. Seeding TRUNCATE TABLE `books`

  50. Seeding New rows

  51. Seeding $ hook db:seed ... Truncating 'books'... Success. Seeding 'books':

    100% Done.
  52. Console $ hook console

  53. ( thnks node <3 )

  54. Schema • Database definitions / migrations • Collection data types

    • Collection relationships • Serves as documentation
  55. schema.yaml

  56. schema.yaml CREATE / UPDATE attribute

  57. schema.yaml Disable automatic migrations

  58. schema.yaml Relationships: - belongs_to - has_one - has_many - has_many

    (though) View the documentation!
  59. schema.yaml hook.collection('books'). join('author'). first(function(book) { console.log(book.name) console.log(book.author.name) })

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

  61. schema.yaml

  62. Authentication • Auth • OAuth (plugin)

  63. Authentication API • #register • #login • #logout • #update

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

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

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

  67. 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) })
  68. 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
  69. 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
  70. 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) })
  71. 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) })
  72. auth.login() hook.auth.login({ email: "endel.dreyer@gmail.com", password: "1234" })

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

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

  75. 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) })
  76. 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
  77. 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
  78. 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) })
  79. 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) })
  80. auth.update() hook.auth.update({ birthdate: "26/05/1990" }).then(function(auth) { // success }).otherwise(function(data) {

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

    // failure })
  82. 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) })
  83. user data

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

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

  86. user data hook-ext/security.yaml

  87. user data hook-ext/security.yaml

  88. Extending the back- end • Routes • Observers • Schedule

    • Composer packages
  89. Routes $ hook generate:route last_posts ... Route created at ‘hook-ext/routes/

    get_last_posts.php'.
  90. Routes

  91. Routes

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

  93. Schedule hook-ext/schedule.yaml

  94. Schedule

  95. (php is ugly sry)

  96. (php is ugly sry)

  97. (php is ugly sry)

  98. (php is ugly sry)

  99. (php is ugly sry)

  100. Collection observers • toArray • creating / created • updating

    / updated • saving / saved • deleting / deleted
  101. Observers $ hook generate:observer auth <?php class Auths { public

    function created($model) { $message = Mail::message('Welcome ' . $model->name); $message->from(Config::get('email.from')) ->to($model->email) ->subject("Welcome") ->send(); } }
  102. Observers $ hook generate:observer auth <?php class Auths { public

    function toArray($model, $array) { unset($array['endereco']); unset($array['cpf']); return $array; } public function creating($model) { $message = Mail::message('Welcome ' . $model->name);
  103. Composer packages • PHP’s Package Manager

  104. Composer packages • PHP’s Package Manager

  105. Clients • JavaScript • Corona SDK • C# (Unity) •

    Android • C++ • …
  106. DEMO • hook-admin 
 
 https://github.com/doubleleft/hook-admin

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