 So just in case this goes down I want to try I want to put another piece of technology to the test I just tweeted a link to my slides and as I flip through them it will flip you through the slides So if you don't see the link on Twitter that I tweeted it at Mountain West JS the link to the slides is Slides comm slash J. Dobry. That's J. Do B. R. Y slash JS data so All right, I'm really happy to be here at Mountain West 2015 in particular because when I got the email about presenting it said we want you at Mountain West 2105 and I was like Wow I Got put way in the backlog So I just decided it was a typo and came so here. Hopefully that's okay. Um a little bit about me I'm a dad. I like soccer speak Russian play Dota 2 if you want to Play with me. I'd be fun. That's my daughter. She's really cute. I just thought I'd put that up there She's really cute. I work at Lendio. It's a marketplace for small business loans Full stack engineer do lots of node lots of Angular My SQL PHP last five months. I've been doing data science So like machine learning classifications statistical analysis stuff. It's pretty fun. I'm really big into open source I have a bunch of projects Rethink DB or an ORM for that. So shout out to them and then Today I'm talking about one of my open source projects JS data I've given some other talks. I have a side project code train. I always should check it out It's pretty cool. So you guys are programmers and it's for you So why Why JS data? Why am I going to talk about a library today? Well, I'm gonna talk about the principles behind Why it was built and why it's gonna help you so Merrick touched on this in his talk He talked about the document web, which is kind of like web 1.0 Where it's just static is just static so in in that in the old In the old web the document web like Merrick termed it You just have a browser in the view and the user clicks links and then the the request is sent to the server and The server Receives a request Maybe pull some data if you've done like any like Java struts type work You just get a you just get a request and then in your templates You you talk to your DAO layer and then you get some data and you just put in your view And then the HTML is sent back to the browser This is how this I was for a while and the reason is that? Browsers were slow. They couldn't do a whole lot of work the CPU Take CPU power to render to render the templates in the client and so browsers were slow So server did a lot of the work Also, you were limited on storage options the only place where data was stored really was in your database on your server and So like I mentioned the struts example in web 2.0 You saw the demand we saw the demand for dynamic content like the demand to be able to collaborate on the web So we needed faster apps that could change quickly in response to user input and in this paradigm When we shift a lot of work to the browser We shifted work for rendering templates and gathering data organizing in the JavaScript You got the JavaScript heavy apps Merrick touched on that So in this in this in this model We saw the also the emergence of rest so you make requests for your data and you get the data back and then it's rendered on the client and this Happened because browsers got faster CPUs on all the user's devices got faster So they can you could actually offload distribute the work to the clients Also, we got more options for storage local storage index DB The back end is a service that has emerged with like fire base and go instant They may rest in peace and other companies like that So I'm going to talk about this model layer right here that I've highlighted in orange. So You all use ORMs probably very likely at your company, you've written your own you've spent a lot of time in This room it represents Thousands and thousands of man hours and millions of dollars worth of cost The amount of time we spent writing these model layers not just in the back end but now in the front end as well and If you if you use like frameworks like Angular you realize that they don't really it doesn't ship with a model layer You build one yourself many blog posts and talks have been dedicated to How to write a model layer in Angular how to use services and the same kind of problems applying in many frameworks and There are very very many frameworks they all slight they all solve kind of a similar problem in slightly different ways But The model layer has never been super consistent among these many frameworks I'm sure someone in this room has used all these different frameworks though Some of the frameworks try and address the model layer. Some are just libraries that are for the view only There's no real consistency there So every time you switch from framework to framework to framework you're rewriting your model layer to some degree and I'm sure we've all done that and it takes a lot of work JS data enters the picture as a consistent data layer that you can take with you As you move from framework to framework its framework agnostic and it solves this problem that Tens of thousands of developers dedicate their time to solving every day Jx data Works as an in-memory client or an in-memory data store It runs on the browser and on node JS and then it uses adapters to do the asynchronous Communication to your various persistence layers each adapter abstracts away from the data store how to get the data So in the browser You have the data store And then it can you can communicate with your rest back end It can communicate to local storage to local forage Mozilla's project to fire base And it presents you with the same API regardless of which persistence layer you're using for your data And you can use multiple persistence layers in combination So if you wanted to build like an offline app where you can optionally be saving data to local storage And then when it's online again sink that back to your your back end store on the back end I currently I have adapters for a number of sequel databases MongoDB rethink DB and then the HTTP and fire base adapters they work on note as well So the result of this project has been a Nice nice documentation built on read me die. Oh, which I highly recommend to anybody and I built a github organization where I can organize these it's like a dozen projects so far And I'm really open to collaboration and building a sort of the Twitter broodstrap of data layers for For client-side code and back-end code it can work in is an ORM and your front-end and your back-end There's a term like isomorphic code you could if you're using no JS on the back end You could theoretically use write your model code once and then reuse it on the back end in the front end with this Using JS data on the front end in the back end. So The philosophy is driving JS data. I originally wrote a project called angular data because using angular work. We didn't have a model there We read blog post. We're like, okay. We got these controllers. We're not supposed to do HTTP calls in our controllers We're supposed to write these services. So we started writing services. We have like 30 different resources in our database and Writing services got tedious. So what we did is we used decomposition and we were dry And so we wrote code that could be reused like a base service and then we would reuse it for all of our different resources and Then that grew into the inspiration for angular data Which I wrote during ngconf last year and then on hacker news Someone made a comment when it was submitted and said why is this an angular library? So I ripped out angular and I created JS data and this organization to make the framework diagnostic Tool that can be used whether you're using angular or reacts and in fact I have two demos that demo the same thing one uses angular one uses react and they both these JS data for all their their persistence needs so You may have seen tools like breeze JS and there are some other like angular tools like rest angular ng resource They all solve the problem to do to various degrees my experience with breeze is that it was Extremely complex and after a day working on it. I had no real nothing to show for it as far as integrating it into our product I needed something that easy, but I needed something that did more than like ng resource Something that actually stores data in the browser and can abstract away multiple persistence layers so The goal of JS data is for it to be easy to use you can just install it and immediately Be making requests employing data for your various resources The API is record recognizable It's similar to what you would see in like Mongo Mongo's client or Mongo's or various rms the way they train whole data Your apps yet might not yet be Frankenstein apps like Merrick was saying but most of your apps are probably credit Meaning that they do create read update delete operations on a bunch of different resources It's the kind of thing that we don't need to keep reinventing the wheel for it's been reinvented so many times that let's just come up with Something that's reusable that saves you those that boilerplate code and the time rewriting it and resolving the problem every time you go to a new company and That's what this dead simple crud and reusable code is for Framework agnostic switch from Angular to react or react to Angular. You don't have to rewrite your model layer. You just keep it Stored agnostic that adapters can extract away from the memory store the Differences in retrieving data from different sources I tried to pick Conventions that would generalize the solution to the problem for them as many use cases as possible But then left it open for you to configure it for the the various video sequences of your rest back in because various people They'll have like a dot JSON at the end of their URL or they'll have nested nested resources in the URL So they want to change the base path and things like that. So if there's a convention that is I tried to make it the most default applies to as many people as possible convention and then a configuration so you can extend it tweak it to your needs and then The tool itself tries to help you not shoot yourself in the foot So if you do something wrong the API is helpful with its error messages and things like that So it expects you to provide the right arguments and this principle designed by contract. That's what it follows in the implementation Now the store in the adapters each are separate projects And here's an example how to do it So you can simply new up a new store once you've loaded jf data in your app and that creates in memory a Store just a data store and then what you do is you register adapters with the store For example, you register the HTTP adapter and you tell it to use it as default So by default when you do any async operation find find all or create It's going to default to using your HTTP adapter, which will communicate with your rest back in here's an example of registering a firebase adapter and In every method call you can also override the default and just say for this particular method call I actually want you to go to firebase and pull a date from there or something like that so Once you have your memory store you you got to tell your memory store about your resources So you just call store define resource give it a name and then That is the only required option for a resource. It will assume a whole bunch of default options From that and then there's lots of configuration This school resource is an example of a relation that shows a relation So like school belongs to district so you can do relations and it will automatically link up your objects together So they just have references to the to each other as you need them There's an example of the default settings The store comes with default settings and then the disc the resources inherit from the default settings But every setting is overwritable on the resource level and even on the method call level So I defined a district in a school resource to resources By default it's going to assume that ID is your primary key that you're using to identify unique items You can customize that with Mongo. It's going to be underscore ID probably so you're gonna have to continue that For if you're gonna use the HTTP adapter it assumes a certain format for your your endpoints Slash district on the get you can customize all that and configure to your needs Maybe use its districts instead of district You maybe you chose plural and you're in that camp or something and all that can be customized So the API for the data store it gives you a synchronous API and an async API the synchronous allows you to Interact with data that's already in the store So if you want to just synchronously pull some data And you don't want you don't have to deal with a promise for waiting or latency or have anything like that You can just you can query the data store itself for what it already has. This is what's in memory in the browser or a node so Here's an example of a synchronous get call District I get ID of one it's undefined right now because there's nothing in the store the store is empty So the store returns undefined Now with a fine call That is the asynchronous analog to get get and find are like the same thing one is synchronous Queries the data store when it's asynchronous and it will delegate to an adapter So I call fine in it's going to delegate to the HTTP adapter, which was the default performs a get request the fine call immediately returns you a promise a promise Which represents the eventual value that your server will return so when the server resolves it returns some JSON that The district ID one gets injected into the store, and then it resolves your promise with that data So right here You can see that it it resolves a promise with your data But then I can call that synchronous get call and it returns me that same object already in the data store and that strict equals Shows you that they are the they are the same object. It is a reference to the same object that's in the store JS data uses something called identity mapping meaning it doesn't throw away data If an item is already in the store and you re retrieve it from the from the back end The reference you had to the original original item will stay valid It will just update the one that's already in the store with what you retrieve from the back end So it keeps a single unique copy of every unique item that you ever put into the data store And then any reference you get to that item will stay valid. It's not going to get invalidated It's not going to throw data away. So it conserves data from that point of view So if I call find again, there isn't actually going to be another Get request because that item is already in the store All of this is configurable. You can force it to make a new request, but it gives you caching out of the box You don't you can call find as many times as you want the first time It'll make a get request and subsequent times. It'll just use the promise and resolve with the data if it's already there Here's another example that shows some things like saving data Now that my district is already in the store I can use I can I can just mutate the data district.name set to wasatch and then I can call save That's going to do a put I Get the promise back It resolves with the result of the call and I can see that my district has been updated. It has it's re it's synced When you do asynchronous operation operations It delegates to adapters and then syncs the results of those calls back to the data store So your data store will reflect the results of anything you do asynchronously Here's an example of destroying the district and at the very end oops I Call that I do that synchronous get call again after the destroy call has resolved And the data is gone. It's no longer in the data store. So here's a here's a quick table of kind of some synchronous methods and their analogs filter JS data comes with a query syntax. You can query the in-memory data store using Like a where type statement where criteria you can use you can sort you can you can limit you can offset and things like that So it makes doing pagination and like infinite scrolling really nice Because you can you just query the in-memory data store for a collection according to some filter criteria that you Y defines and Then on the side you're querying your server for that data And then when the server responds you can have your view just automatically repoll from the in-memory data store Whatever according to whatever criteria you need a couple demos So here's just a really simple Demo that shows using angular and JS data. This one's using the Firebase adapter And everybody see that good enough so if you're familiar with an Angular app At the very beginning in the config phase. I set up my Firebase adapter. I tell it where my firebase is give it a URL then down here I Register I register my firebase adapter is the default I Use a factory or service or whatever to create my user Resource and then I return it so I can inject my user resource wherever I need it in the app And then down below my controller. I finally make an initial request for the users It'll make it a little request. It'll get all the users from Firebase and then this bind all call right here What that says is whenever the user collection changes update the users field on the scope with those users So it'll just keep them synced to your scope And then a couple methods for adding and destroying users. So with an example I can just say Add an user and I'm at it and You can see that it just automatically updated the ng-repeat the list with the user that I added after the the store completed its operation Sorry, this was the Yeah, that's the any other example now. I can show you the react example which I wrote last night So it's the first time I've ever used a react. So take all this code with the grain of salt I don't know if it's the right way to do it But it seems to work. So if I refresh this react page People have been playing with it. So awesome If you if you're using like web sockets and things like that you could implement a sort of three-way data binding Which like was I guess coined by fire rates But you could have if you had multiple clients and use those web sockets to broadcast that certain data had been updated or created And then you can have your various clients Then just pull in the new data you could have The new users be appearing here automatically and things like that automatically re-rendered So with with the react app and once again, I don't know if I did this, right? I took the to do to do the to-do list example from the flux architecture page and I replaced all of the dispatcher and store code with just a simple j-state resource and just plug it in and it appears to work so There's this on change stuff Where I say whenever the on change I Register okay user store on change Whenever there's a change in the store whenever the user list changes call that react on change Which changes the state which I guess tells their reactor re-render. That's how it works any and Yeah, you can look at that So those are two really really tiny examples and normally you're gonna have a much bigger app many resources many routes It's very convenient to be able to just define your resources like this define your relationships among them You can do a find request where it retrieves like maybe nested relations And when they all get pulled into the browser the data store will automatically inject all of those pieces into the right place in the data Store and then link them up together. So you have the right links to them And things like that. I've created a repo JS data examples if I go back to the slides And that's a link these slides. These are links So that's going to be an example of applications using various back-ends combined with various front-ends They all use JS data and they will hopefully showcase different things like With different ways of using relations different features offline online type things right now the only examples I have in there is a Rethink DB back in so JS data runs on node as well So it just uses a rethink DB adapter and then it can just it's like a out-of-the-box or for rethink DB And the only front-end example I have is an angular one and it's kind of like this demo I showed you So I'm just going to do a quick run-through on some of the features I Tried to combine some of the best of the best that I found in various data layer frameworks out there A lot of this was inspired actually by ember data. I really kind of appreciated Some of the the problem they were trying to solve It's just it's tied to ember and your server really has to meet a strict format and how it does its URLs and requests And I really didn't like that. So that's why I wanted to make this as configurable as possible One is model lifecycle hooks. So whenever you do like an update There's going to be a before validate validate after validate before update And then it's going to actually update and persist it to your your persistence layer and then an after update and at Any point in that operation you can abort the life sample you can modify data It just gives you complete control and you can get your fingers and things Relations as many belongs to there are a couple methods that help with linking things together or dynamically Like I guess you call maybe side loading relations on the fly After you define your resources, you can add your own static methods to your classes That are like these global class double methods There's also an actions option where you can it really only applies to the HTTP adapter But if you have like your user resource But then you want to get you have like this thing where you Append count to the URL and it gives you the count instead of the actual data Like you can just use the actions option to do things like that One thing I really liked about Angular is how you put your data on the scope But it can just be a plain pojo. It doesn't have to be wrapped in any sort of constructor It doesn't have to be any heavy model class or anything like that So you could potentially use JS data and have your data be pure pojo JS data will maintain metadata about your stuff But it's it doesn't have to decorate your data with these construction classes if you don't want it to and that can improve performance But if you're gonna use the wrapper constructor that it provides then you can add your own custom Instance methods, so they'll just be put on the prototype and then they'll be available on any instances you inject into the store for example Added one called say it just returns this dot name and once you create an instance You can call user user dot same and that's an instance method you can do that kind of stuff So some people like to just work with pojo's and then they have Services that will operate on things and do their methods for them other people like to wrap their data with Constructors and then attach logic to the instances themselves. It's a kind of a style that different people prefer Another one is these config convenient shorthands If you are using Angular You can use dependence injection to pass around the various resources in the places that they're needed Or you can just pass around a reference to the just the store and then when you're doing your operations You just tell what resource you want it to operate on Some of these methods are also proxied through to those instances So you only would need to have a reference to the instance itself and you could tell the instance to save itself And it really just has the store save the instance So whatever style you prefer computed properties JS data relies on object observe and the Observe JS polyfill in case the browser doesn't support it to detect changes to your data And it will automatically recompute computed properties whenever your data changes and things like that You can see that after I inject this user the full name property has been computed for you So that's pretty cool part of the metadata that JS data tracks about your items is the lack that a timestamp of the last time your data changed So in if you're using an Angular app, you could set up like a watch where you just watch that timestamp and whenever it changes That means your data like you need to like go re-render something or re-ren some code It's it's different than the dirty checking which can be a kind of a performance it because it uses object observe And it will only update that number that timestamp according to object observes watching so it can be more performing I already I already talked about Korean collections There's also library JS data schema which allows you to just define a schema for a resource Required attributes maximum length and different things like that And then you can have it on save and update validate those schemas so you can get kind of out of the box client side validation of your data The change detection I talked about Some of these features come with a performance hit if you're gonna Be some doing some of these things they can all be disabled to improve performance for certain resources If you don't care about this kind of thing for them one of the features is change track tracking You can actually get like a log of the changes that have happened to each of your items That's off by default because it can In effect the performance But you can query your items to say does my item have any changes? What are the changes? What were the previous values of this item before it was changed? You can query all those things of your data Also some built-in cash expiration capabilities So you could do something like say I'm gonna load a bunch of like comments into this into the data store But I only want them to last like 15 minutes because people are flipping around comments so often They're not they're not gonna go back to them really be mine So that's maybe I why I should cash it but after 15 minutes, you know, just kick them out of the store Just kicking back out so I can just kind of not bog down the the heat within objects and Yeah, so The goal here is to turn this into the Twitter bootstrap of data layers for JavaScript apps. So That's just data. Thanks