 Hi everyone, thanks for coming. I hope you had a good break I really just want to take a moment to Gather a round of applause for all the organizers for these awesome conference. They've put it So please give it for the organizers. Thank you I'm here today to talk about on next it might not be a very familiar concept for you But I'm glad that others before me did a very great job at introducing the concept that I'm going to talk about So this talk in particular is about the way that clients and different platforms for that we program for today And the way they are changing the way that we develop these applications I'm currently a student in Germany more originally from Portugal And I've been a contributing for a closure script and the home for the past year or so So I want to start by a time where we where we when we were building a rest applications and What we would expect normally from rest is that we define our logical and logically separated resources Each one identified by their own you are I Have our clients Are little happy nice clients request these you arise and get the data that the endpoint decides that they're going to get And this is actually dear the reality is that for each endpoint you can really only request or create the trivial data once you You go and you need more than the set of data that that endpoint Gives you you need to make a decision and you either bloat your endpoint by giving putting more data there that doesn't really belong to that resource and what this means is that other clients that might not need that data will be over fetching or you you choose to make multiple requests and Multiple requests are really not acceptable for today's low-end devices or for 3g connections So this is a problem and we we want to get out of it The thing is that this was not unknown at all and at a time of rest formulation Dr. Roy Fielding actually Acknowledged that the problem with the the uniform interface is that Data is really transferred in a standardized form and it doesn't fit what every application every specific application needs so once again, the problem is really about the the wide variety of clients that we have today and that we developed for and Changing the end point is just a huge problem because of the the way that it will affect the other clients that are also hitting that end point And so we really need a way out of this this current situation and over the years a number of technologies that came out have come out to Try and solve this very problem with So they they said that I don't want to interact with the rest APIs They're they just lead to to huge sources of complexity. So This led to the popularity of document-oriented source and things like a meteor or Parse couch base fire base and so but for me these these technologies they really don't Solve the problem. They're very nice technologies and I'm not saying the otherwise, but they really just solve the symptom because by Making it easy to to to sync and send trees of data to to to a certain server We we lose the the benefit of relational queries and we can we cannot run any sophisticated queries against our back-end anymore And so we really need to To define a goal that lets us overcome the problems that that rest Means for for these new types of applications And there is one more thing is that in the rest system everything is out of band The actual code implementation is separate from the the specification of these endpoints and If you need to hit an endpoint, you don't you have no idea what it's going to return you so you really need to to go check some documentation that may or may not be outdated to to to To inform yourselves about what is going to return So what we really want is to to shift the control to to our clients and I'm going to introduce a bit of jargon here from what I and others before me called the Demand-driven architecture and this is demand driven as opposed to supply driven in that in that in the rest sense that You get what the server dictates that you get in this case the clients decide what you're going to get And so the first thing about demand-driven is that you need to have a demand you need to Exactly specify the total of your data requirements and the shape that you want to get that data in right? You don't need you don't want to be aggregating or transformating data You just want to to get the data and pass it immediately to to your render function to display the data on your UI and so You want to describe this because the service the backend implementation cannot predict what a client needs when you're hitting a certain end point So we'll have our back and be more dynamic and have our clients describe exactly what they're looking for So the second property that we need is composition in in that We're all building UIs by component by using components and this has been touched upon today a lot and so We want through composition For example by a recursive data structure. We want to have each component say what? data it needs and we want this Piece of demand to be valid by itself, but also want to compose it through a recursive data structure So that we can send the whole thing that an application needs in one batch to request to our servers And so the next thing that we want is a way to interpret the query language or this recursive data specification that we define and so This is what makes it really storage agnostic in that you don't need to be tied to the details of a backend implementation or a backend data storage With a language that you Well tight as I said and So in this sense and this is a quote about graph QL is a query language Really, but just like the URLs are the query language of rest. So it's just a contract to define How to tell the API server while you're looking for but not how to get it So I just I'll have a first demo here I'll need to mirror displays because I don't I don't have the skill of programming over my shoulder And can you will see this? Yeah, right and so Here on the left. I have a little bit a little data structure that describes well, what kind of Properties and or attributes I Want from the the piece of data that is displayed on the right side and and so let's say for a moment then I'm developing for for a mobile phone and Having all these properties right here is too much and I cannot present them in my client And so I can always fetch them in the rest sense and throw them out But this means that there is data going over the wire that I don't need So let's make this efficient or at least a bit more efficient. And so I can specify for a Certain speaker a certain talk that I really can only present its title And I run the query against my my backend and boom I just I just get the attributes that I exactly asked for What's more is that I didn't need to ask person a or person be in the in the backend team to put or? Or remove those attributes for me In the implementation and there's one more thing is that as you can see a speaker stalk is a logically different entity in my database and and so through this query language I can query several across several entities through in one query and get everything that I asked for okay so all next has been influenced by a lot of things that came out in recent years and React was for me one of the best things to happen to you guys and that it just brings functional programming to the To the browser in a way that okay, so let's always render from root and I don't care about the the huge source of complexity that is Dealing with the DOM the DOM implementation. So let's just say declaratively specify what I want to render and just render it So another thing that influenced the design of omnis is really in graph QL Which you might or might not be familiar about with and so relay is a thing a library by Facebook that lets you annotate your UI components with queries With the attributes that you want to receive and graph QL is the the backend part for that And so they play very nicely together however Doing a graph QL implementation is not trivial. I think Facebook didn't open source that part. They only really released the spec and so but the thing about this is that moving towards these new kinds of systems allowed Facebook and others to delete a ton of code from there as from their restful implementations This is a quote from lead that was talking here this morning. Hi And so by Netflix Falkor is the same thing, but the right from from Netflix's microservices architecture in The previous speaker was speaking about Falkor in a way that it lets you bind to the cloud and seems like all your data Is local to you and this is an awesome concept another thing is that Falkor has this concept of a router which Knows how to route each key that the UI needs to their specific microservice that knows how to serve that key And so also Netflix they they ended up eliminating 90% of their Networking code when moving from from rests to Falkor But my my favorite stack is The closure one I really fell in love with closure Some years ago, and if you don't know what it is closure is a dynamic programming language a list for the JVM and It has spawned the the implementation of closure script Which is a a set of closure that compiles to JavaScript So you can use the the same language that you use on your server You can use it on the clients just like you might be using with JavaScript in node and so transit is a Format on top of Jason that that piggybacks on Jason on webpack that lets you Transfer these closure and closure scripts data structures, which are immutable by default over the wire And they atomic which is right there at the bottom right Is an implementation that is derived from the same concepts and features a Sense of immediate ability and really a sense of time built directly into the database So these two to introduce that Ohm next is the Closure script and closure library that Intends to deal with these problems that we have today and so Ohm next was originally built by by David Nolan who is the core the lead contributor to to closure script and Ohm next is like the second iteration of his design process So he first developed Ohm dot core which was the first one and And after seeing the ideas behind Falcor in relay He really rethought his Processing and came up with Ohm next And so Ohm nox Ohm next let's just have two really beneficial properties that we That are as I said before that clients can really They can really request the exact total response that they need to hydrate their UIs and They can communicate novelty atomically to to to the back end Without sacrificing the power of relational queries and so Ohm next is really opinionated in that And you might be familiar with the single source of truth of opinion. It's what read ax also Enforces I believe and so another opinion is that we minimize flushing to the dumb and we minimize flushing to the dumb by using react as the underlying UI implementation And so we also want to to abstract from the the library user Both a synchrony and the event model. So a synchrony is just a problem because of The the callback Helen cascades that fortune should fortunately are going to be solved in the next version of Agnes script as we heard today and event models event models are just really another source of complexity because of Event cascading and so in Ohm next we have a way to abstract all of these from the developer And so this is a checkpoint and I'm going to go through all of these questions in The next slides. So brace yourselves How do we make precise requests with Ohm next? We have just like in relay we have query expressions and query expressions are co-located with components and they let let us annotate Exactly within the definition of a component what did this exact component needs to hire to hide the their data needs For rendering and so this is how we a Ohm next component looks like if you don't like the parentheses just ignore them This is almost like a react component. You can add the other life cycle methods as well And everything works this query expressions There they are what lets us specify what our client implementation needs and we have for example a single keyword that Expresses an attribute a Parametrized keyword This is how to perform a join and this is what I showed you earlier when showing you the the little demo there and so in this case we're Asking for a person's address, but we are really only concerned with the the street and the zip code The entity might have other properties in in the back end we but the particular client that writes this query expression is just not concerned with it So we also have a way to express mutations mutations are something that change the state of our application and so mutations are They're expressed as regular function calls and our parser Which is another thing in Ohm next knows how to interpret them And so the parser is really what takes a pure function from query to to data It's what hydrates the the the query expression that we pass on to it And so this is the same concept as Falcor in just in the way that Falcor calls this routing and in Ohm next we call this parser Or parsing and so the parser runs reads and mutations and it runs both on the front end and the back end and this is the the actual the interpretation layer that I described earlier and It sits at the edge of our system you never call the parser directly And it's actually what allows us to abstract a synchrony from the developer because everything in Ohm next looks very synchronous Although it might not run synchronously And so this is what I'd raise our queries that we pass to it Without reshaping we just get the data out of the parser in the way that we expect the shape That we expect it to to be passed to our render function so that it can render immediately without performing any additional transformations So how do we communicate novelty with our back ends? And the answer is the same we run query expressions through the parser and because query expressions are data structures we can manipulate these data structures and say which Attributes can be satisfied locally and which ones need to be sent to the server and so Whenever we cannot satisfy we don't have a thing in our local app state that satisfies What we we are currently asking for we can just send the query to the server Which also runs the parser implementation to hydrate that data and pass it back on to to our UI And so There is a key after a mutation that I'm running and what that says is after you run that mutation reread this key and this is what allows us not to have an event model because we have query expressions specifying keys to be read after the mutation just Oh max is just smart enough to know which Components depend on the specific key and so it knows which components it has to update So creating information and this is the part about communicating novelty atomically to the server is This has just an awesome synchronization story. No next in a way that you can create temporary information on the client Non-trivial information you can create Relationships between this data and you can send it to to the back end and the back end can reply with the mappings from your temporary IDs that you have on the the client To the real IDs that are now persisted on the on the back end and you never need to delete This temporary information that you created on the client. You just need to replace these IDs and all nexus is it automatically for you So what about a local state All next has first-class support for client only state And so we just support a merged view of remote state with local state And so because the parser is able to to pick Which things are local which and which are remote we we can this just works So there's only one problem which is that We commonly we model our domains as graphs with interconnected relationships between our entities, but We need to render trees so We need some kind of normalization and Because we have query expressions in all next Omnics can automatically normalize and denormalize your data into a format That there are no Repeated data in your in your state and I'll show you an example just afterwards So normalization is a concept is there that is also in relay and Falcor, but Omnics has this Added advantage that you can normalize and denormalize it for you. And so let's look at a very simple data set of a Few people and let's say I from those people I have favorites And so you can see in this data set that Bob there is repeated twice And so a normalization pass into this day in this data We'll have to replace this duplicated data with something that relates to to the To what their identity is and this is something that we Additional that we need to specify in our own components. It's their identity in this case after normalization pass we substitute Alice by a Way we call a link that Knows how to to find that data in our state So in this case Alice is person by name Alice And if we look into our state and go into the person by name dictionary and the key Alice We find exactly that data that we're looking for after the second normalization pass. We have Bob There and you notice that it only really appears once and but there are two links to it and so because different Areas in your screens might show different things My different attributes at a certain point when performing this normalization we merge all the attributes that are found at the identity at that node and so and One thing that is different from react. However in all next is that Normally when you perform a transaction say a set state or something else in react And so see the the arrow where I say so there's This is a tree of components and I'm saying that the component that At that point is component that performs a transaction react. We'll always render from root In the sense that it doesn't really re-render from root, but it performs the the diffing from from the root of your Component tree, but in all next because we have query expressions and we know how to relate query expressions to the components that depend on them We can just really re-render from the place that perform the transaction and If other sub trees have the the same identity we also Rerender those sub trees so we can perform this kind of incremental rendering where we don't even need to re-render from root And so what implications does this have for testing? and so For testing Having a single source of truth and A parser that lets us abstract the synchrony and that really doesn't need to interact with our components at all And since at the edges of system is just awesome. This Combined with closure scripts immutability Is awesome for for testing because because we know that our components They're just pure functions from the data that we pass them on to do you do you with the rendered UI be dumb or native? So we can just test the UI data tree And so I'm a really big fan of property-based testing for those of you who don't know what property-based testing is it's Opposed to what example-based testing is that we commonly do in our systems in which we specify inputs and output pairs in property-based testing we write invariance and We have our Generative testing library generate test cases that attempt to falsify these invariance But what we get what we get for free is shrinking in that a failing case The our library can shrink it to the smallest possible case that Fails so that we can test that case again in an example-based test for example and fix the bug And so ohm next plays really well with a closure library called test doc check Which is the implementation of quick check originally for Haskell in but in closure and so and so in om next because our queries and our mutations their data and we know how to generate data with Generative testing generators We can generate transactions that run against our parser and check the invariance in the resulting state And I'm going to show you a little demo of that So okay, so here we have a poor man's conference list application and In this case, I have a list of speakers You might have seen this data set before and I'm I'm selecting the speakers that I that I really want to see in the conference And so I went when I when I favorite a talk I'm supposed to get the stock in the favorites list But we can see that when I favorite this talk it didn't appear in the favorites list. So I wrote a bug and so To not not to do that again I'm going to property-based test my application In a way that I can be confident that it works and so I Can see here for example Wait, is it too small? Yeah, all good. Okay, so Let's say I want to generate 10 transactions that I will test and these are Based on my my generators. I'm going to generate 10 transactions Randomly that will run and attempt to falsify my invariant And so my invariant is that whenever I click on adds on favorite a talk it must appear on both lists and and so When I run this command It will check 10 times that when clicking it really adds to the favorites and so the result of This is that and you saw that it's not working. So I really got a false But the really interesting part here and you cannot see that is that It shows me the smallest possible case that I can use to To Fix my but the smallest possible failing case that I can use to try and fix the bug and so because I'm very smart and I Prepared the presentation beforehand. I really already have here a fix to the bug And so I'm just going to fix the bug on the fly Wait for the hot load to kick in and hopefully when I run this again I will get that It passed So if I come back to my my little Poor application and I click favorite I can see that the the person Appears in the favorites list, but notice that I I could be confident about this fact without even ever trying the application and this is just awesome and so by by generating random transactions that run against the Parcer and Shrinking those failures and getting the minimal failure to reproduce the bugs you can just be very confident about our testing story So but by by this is actually modeling the user and by modeling every possible user interaction against our UI You can just profit So there's a lot of more things that omnik supports that I really don't have time to talk about here But also I mentioned them here briefly so we have in the query syntax We have native support for recursive UIs for heterogeneous UIs and these are think the Facebook newsfeed when Which is a really a heterogeneous thing that you don't know what's going to come after if it's a post or a photo or a video right and Because we know how to pick queries from locally from the remote queries, and we know which attributes belong to the local cache and the the the ones that need to to be fetched remotely We can just Take this query That is going to be remote Hash it and get the stable URL that we can send to to our backend Which is? Cacheable by default by HTTP standards So there's no need for any custom caching story Also omniks allows you to Is really is storage agnostic in the client? We'll see about the server in a second, but you can really provide a custom storage if you want to use a a Browser local storage or the index the DB everything is supported It also has built-in support for streaming in those are cases where you might want to sideload data without passing through the the re-render cycle and server-side rendering either through running it through React on node or by some other library that I developed that the server-side rendering on the JVM and So closure on the server. How does it look like? Of course if you're using closure, it is preferred and you need to write less boilerplate But anyhow if you want to use with other languages You kind of need to implement the parser logic to parse these queries into something that Hydrates the queries with data. It's definitely easier for languages with the transit format implementation for you to exchange is data between the client and the server and because the queries are exchanging transit over the wire and Regarding storage datomic is supported by default because the omnicx query syntax is a superset of datomics What they call pull syntax, but other databases work as well the the work necessary to do there is to Translate between these recursive data structure that represents the the demands of our UI to to The underlying storage Implementation that you have on your back end so all next has been in alpha for a long time almost since November I think But it's really reaching beta very fast And if it's not next week, it will be the week after that the only real thing left to do is write tons of documentation because These concepts are not simple to grasp and people really need a lot of help and if you want to help us write documentation get in touch It's always appreciated But if you don't know where to start Start by these places First the first thing there is the home official wiki Tony K is an American guy that Provided a very nice home tutorial that you can find on his web page there and Shameless plug. I've written a Few blog posts on very specific pain points that you might run into when you're starting out with home next So We've seen that we can radically simplify the way that we do UI programming today and data fetching and data creation in our applications and My my advice to you all is that even if you don't end up using home next And really regardless of the library or framework that you end up choosing Just strive for these simpler systems with the two properties that I mentioned here You'll find The sites and the the code demo for this presentation in that repository there In a short moment, and I'll take any questions now if you have them a lot of talks have been about Query API is but all mostly about reading What about writing and how does all next differ from anything else, right? So you might have Seen that I had I described that home next also does mutations and mutations are something that Changes the state of our application either locally or remotely So because mutations also run against the parser You can also send them remotely if they cannot be satisfied locally and you can even satisfy them locally and remote Remotely and this is an optimistic update So By by running a mutation remotely you send as arguments It's just like a regular function call, but you send as arguments the the the novelty that you want to persist on the On the back end implementation, so that's how you do it. Excellent. Thank you Excuse me. You've mentioned how old it is the question was how old is on next and How many people use it and is it production ready? I know you said it's nearly beta. Yeah, so I Actually forgot to mention that There are a few companies already using all next in production it There's even a framework on top of all next called entangled which really Builds upon it and adds a lot of the nice features that you you might Because all next is really just building blocks for you to make this The an implement a demand driven implementation you can run it alone or through another How old what is the is on next was the other question and so Falkor and really they were announced. I think in January or February last year and David Nolan saw the the announcement and I think he started working on it on Middle mid-July or well mid-summer last year and so it's coming up on an year or more than a year now and It's yeah, that's it. Excellent. The question are also added to say impressive testability by the way, right? Thanks What about browsers that don't have JavaScript for any reason? browsers that don't have JavaScript, so if you're Developing for a browser that doesn't have JavaScript. I assume you're you want to to develop a static Page of some sort and as I mentioned there is server-side rendering for omniscient applications So as part of your build process You can you could always hook up a server-side rendering and deploy that to some CDN and have your applications Run through that Excellent. Thank you very much. Please give it up ladies and gentlemen. Thank you