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

Bookshelf & Knex - November PhillyJS Meetup

Fb5d018725ccbe7c4359e29edddb201d?s=47 Tim Griesser
November 20, 2013

Bookshelf & Knex - November PhillyJS Meetup


Tim Griesser

November 20, 2013


  1. Relational Data and Javascript

  2. Tim Griesser @tgriesser /tgriesser Backbone.js maintainer Javascript Engineer

  3. Background • Server-side, primarily PHP development • Enjoyed writing javascript

    (and coffee) • Work on the Backbone.js project • Liked the conventions around Models & Collections • Began to explore
  4. ...easily building fast, scalable network applications. Node.js uses an event-driven,

    non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
  5. ... it’s really good for webapps!

  6. ...but

  7. It’s not quite there. • Still a relatively young ecosystem

    • Lots of examples with NoSQL • Touted as great for: streaming, realtime applications, with buffers and websockets... • Not so much for model heavy applications as you’d see in Rails, Django, Laravel, $insert_language_framework_here
  8. ...oh well, guess I’ll stick to what I know

  9. • Models, Collections, Views, Events, Routing for webapps • Solid

    conventions for RESTful data syncing • Flexible, easily extended, literate codebase • Lightweight, doesn’t add features without a number of solid real world use cases • For the 90% use cases
  10. None
  11. Laravel Framework • Well written & architected PHP framework by

    Taylor Otwell • Uses Symfony2’s components • Contains a great Query Builder, Schema Builder & ORM (Eloquent)
  12. Hmm...

  13. • So if Backbone has these nice Model, Collection, and

    Events built in Javascript • ...and Laravel has a nice Schema Builder, Query Builder, and ORM in PHP
  14. could we combine them?

  15. Query builder Eloquent Promises Models, Collections, Events

  16. None
  17. None
  18. Query Builder • Use javascript statements to build SQL expressions

  19. Query Builder

  20. Knex Query Builder • Query support for the majority of:

    • joins, where, having, union, aggregates, insert, update, delete, group by, order by, etc. • Builds the foundation of the Bookshelf.js • knex.raw(/* for very custom queries */)
  21. Schema Builder • Code to help create and edit the

    database structure • Maintains consistency between datatypes in different query dialects • Eventually will be used with migrations (almost there) to keep things versioned as the database changes
  22. None
  23. Knex: Also Used By

  24. None
  25. ORM’s • Quick refresher: • Object-Relational-Mapper • Values in data-store

    (MySQL, PostgreSQL, SQLite3) mapped to javascript objects (models) or arrays of models (collections)
  26. ORM • Takes care of standard SQL queries for you,

    especially for common CRUD operations • model.fetch() • model.save() • model.destroy() • collection.fetch()
  27. • Uses the events from Backbone.js • .on(event, handler, context);

    • .trigger(event, [arguments*]); • .triggerThen(event, [arguments*]);
  28. Lifecycle events fetching creating updating saving destroying fetched created updated

    saved destroyed Useful for validations, logging, etc.
  29. Relation Types • hasOne • hasMany • belongsTo • belongsToMany

    • morphOne • morphMany • morphTo • .through()
  30. .through • Creates a relation where a model can be

    selected through another model • Example, a “doctor” hasMany “appointments”, and an appointment hasOne “patient” • doctor.hasMany(Patients).through(Appointment)
  31. None
  32. hasOne

  33. hasMany

  34. belongsTo

  35. belongsToMany

  36. Transactions • Several queries executed on a single database connection

    • If something goes wrong, all of these queries are rolled back to their original state • One of the key features of relational db’s • Also, surprisingly absent from all Node ORM’s and query builders
  37. None
  38. Transactions • Trickier when everything is async • Need to

    pass the same connection along to each query • In Bookshelf, each async call (fetch, save, create, load, destroy), takes an “options” object which may optionally take a {transacting: t} - where “t” is the object in the transaction closure
  39. Eager Loading

  40. None
  41. Eager Loading • Avoids the N+1 Query Problem • Find

    a user with all associated accounts and for each of those accounts find the associated documents, where the document status is published
  42. None
  43. None
  44. Eager Loading • Avoids the N+1 Query Problem • Find

    a user with all associated accounts and for each of those accounts find the associated documents, where the document status is published
  45. Dynamically constrain relations

  46. Eager Loading (.load())

  47. Library features • It’d be boring if I read you

    the whole documentation, even worse if I wrote out code for all of it... • lots of relation types • transactions • connection pooling • well documented, decently tested • syntax & conventions from Backbone.js
  48. Building the Library from PHP

  49. None
  50. None
  51. None
  52. None
  53. None
  54. None
  55. None
  56. None
  57. None
  58. None
  59. Building the library • Async is tricky... • $.ajax(...) •

    Happens sometimes in client side JS, but not too often • In Node, async is Everywhere • Which is great but...
  60. Callback Hell Source: http://callbackhell.com/

  61. None
  62. An open standard for sound, interoperable JavaScript promises—by implementers, for

    implementers. A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.
  63. Translation?

  64. Promise turns an async operation into a value • Promises

    aren’t about a better syntax than callbacks • Promises are about error handling and making async code look synchronous • https://github.com/petkaantonov/ bluebird#what-are-promises-and-why- should-i-use-them
  65. Code on the Client • Still a WIP, but I’ve

    been able to get this working successfully in some of my projects • AMD + Shimming bookshelf in the Require.js config allows makes sharing code possible • Useful in cases where you have business- logic methods on your model or collection that are needed on both the client and server (validation, etc.)
  66. None
  67. In the Wild

  68. Ghost

  69. Next Steps • Finishing up Migrations • Validations (checkit.js) •

    Building out a Rails-ish “ActiveRecord” facade for the Bookshelf library • Better type-casting support • Making it easier to work with other DB’s
  70. Outside of Node • webSQL (deprecated, unfortunately) • sqlite3 on

    mobile devices, where JS is a runtime
  71. Contributing • Open source is tough, help wanted! • Commenting

    on tickets • Pull Requests • Tests! • Benchmarks • Feature requests
  72. Thanks • Questions? • http://knexjs.org • http://bookshelfjs.org