152 JSJ GraphQL and Relay with Nick Schrock and Joe Savona

00:00
Download MP3

02:25 - Nick Shrock Introduction

02:40 - Joe Savona Introduction

02:49 - Facebook and Open Source

04:10 - GraphQL and Relay Overview

  • React for Your Data” / Component-based Data Fetching

06:11 - Unique to React? Passing Down Through the Hierarchy

10:09 - Queries

  • Tooling
    • Graphical
  • Pulling Definitions

14:13 - Why Do I Care? (As Someone Not Working at Facebook)

15:21 - Building Applications with GraphQL and Relay

19:01 - GraphQL and Building Backends

21:42 - Drivers and Client Software

  • Synthesize => Code Generation
  • Flux
  • Container Classes

30:58 - Reusing Components

31:50 - Data Management

34:25 - Open Source

36:40 - Reflecting Backend Constraints? (Optimizing the Backend)

43:02 - Relationships => Logs

46:24 - Security

47:16 - Replacing REST (Adopting New Technology)

  • “The Progressive Disclosure of Complexity”

52:14 - What You Wouldn’t Use GraphQL or Relay For

  • Games Picks

Another Eternity by Purity Ring (Jamison)JT Olds: What riding a unicycle can teach us about microaggressions (Jamison)OCReMix (AJ)Duet Display (Chuck)Summoners War (Chuck)Thinking, Fast and Slow by Daniel Kahneman (Joe) Learning a new language (Joe)Other People: What Kind of Man (Nicolas Jaar remix) - Florence & the Machine (Nick)Boosted Boards (Nick)The Onion: Succession Of Terrible Events Fails To Befall 33-Year-Old Riding Longboard To Digital Media Job (Nick)

Transcript

[This episode is sponsored by Frontend Masters. They have a terrific lineup of live courses you can attend either online or in person. They also have a terrific backlog of courses you can watch including JavaScript the Good Parts, Build Web Applications with Node.js, AngularJS In-Depth, and Advanced JavaScript. You can go check them out at FrontEndMasters.com.]**[This episode is sponsored by Hired.com. Every week on Hired, they run an auction where over a thousand tech companies in San Francisco, New York, and L.A. bid on JavaScript developers, providing them with salary and equity upfront. The average JavaScript developer gets an average of 5 to 15 introductory offers and an average salary offer of $130,000 a year. Users can either accept an offer and go right into interviewing with the company or deny them without any continuing obligations. It’s totally free for users. And when you’re hired, they also give you a $2,000 bonus as a thank you for using them. But if you use the JavaScript Jabber link, you’ll get a $4,000 bonus instead. Finally, if you’re not looking for a job and know someone who is, you can refer them to Hired and get a $1,337 bonus if they accept a job. Go sign up at Hired.com/JavaScriptJabber.]**[This episode is sponsored by Rackspace. Are you looking for a place to host your latest creation? Want terrific support, high performance all backed by the largest open source cloud? What if you could try it for free? Try out Rackspace at JavaScriptJabber.com/Rackspace and get a $300 credit over six months. That’s $50 per month at JavaScriptJabber.com/Rackspace.]**[This episode is sponsored by Wijmo 5, a brand new generation of JavaScript controls. A pretty amazing line of HTML5 and JavaScript products for enterprise application development in that Wijmo 5 leverages ECMAScript 5 and each control ships with AngularJS directives. Check out the faster, lighter, and more mobile Wijmo 5.] **CHUCK:  Hey everybody and welcome to episode 152 of the JavaScript Jabber Show. This week on our panel, we have AJ O’Neal. AJ:  Yo, yo, yo, coming at you live from Provo. CHUCK:  Jamison Dance. JAMISON:  Hi friends. CHUCK:  I’m Charles Max Wood from DevChat.tv. I’m calling in from a café. We also have two special guests this week. We have Nick Schrock. NICK:  Hello. CHUCK:  And Joe Savona. JOE:  Hi. CHUCK:  Did I say your names right? I hope I did. NICK:  Yup. JOE:  Yeah, Savona, yeah. You got it. CHUCK:  Savona? JOE:  Yeah. CHUCK:  You guys want to introduce yourselves really quickly? NICK:  Sure. My name’s as he said, Nick Schrock. I worked at Facebook for a little over six years. And I’m from Minnesota originally. Now I live in the Bay Area. And I went to the University of Michigan. JOE:  And I’m Joe Savona. I grew up in Jersey, went to NYU, lived in Japan for a while, and I’ve been at Facebook for about six or seven months now. JAMISON:  So Nick, you worked at Facebook before they were beloved for their open source software releases [chuckles]. NICK:  That’s true. JAMISON:  Is that… I’ve always wondered. Is this a conscious strategic decision Facebook has made? Or did this just kind of happen that they started releasing a bunch of stuff that other people used? NICK:  It definitely is a conscious, strategic decision. The business value of it is not the most obvious thing in the world. It’s more of an instinct that it’s the right thing to do. And we’ve even open sourced some of our hardware specs as well. I guess it comes from a number of things. One, it just kind of fits with our mission of making the world openly connected. It also makes Facebook a more technically fun place to work. And it also captures the fact that most of the relationships in the technology industry are not zero-sum. So, in effect if another company does better because of this open source software, it’s better for everyone. It also hopefully if we do our job well establishes an industry leader and also helps a lot with recruiting. So, there’s a lot of goodness there. Funny story, I was actually pretty strongly against the open sourcing of React at the time because I thought it was a distraction. And essentially, it was the most wrong I’ve ever been in my career. JAMISON:  [Chuckles] NICK:  So, I’ve definitely had to eat crow on that subject. JAMISON:  So, I jumped in, and I ruined it. Do you want to tell us what we’re supposed to be talking about today? NICK:  Yeah. We’re talking about two subjects. One is GraphQL, which is effectively our data access layer that drives our mobile applications and increasingly a lot of our software. And then I’ll pass it on to Joe to discuss what Relay is. JOE:  Yeah, so the other subject is Relay, which uses GraphQL. And it’s basically a declarative data fetching layer for React. So, it’s really, you can think of it as React for your data. So, what React does for views, Relay does to the entire data access layer. JAMISON:  There’s a little bit of information about Relay during React Conf. But it still seemed pretty sparse. Can you describe a little bit more what it is? JOE:  Yeah, sure. So, like I said it’s really all about declarative data access. And that means both getting the data that your application needs, fetching that from the server, as well as handling writes. So, a little bit more detail, we found that traditional approaches to data fetching were really error-prone. So, a number of things can go wrong. Typically, for example, you have to specify all of your data-fetching logic in one place. So, to fetch data for a page, you did in one place fetch all the data for the page and then pass that down throughout your React view to each component. And what that meant is that adding a property to a view, so let’s say you had some profile picture view, and it’s used all over your application, right, because you always show users. And you want to add one property. That one change would cascade throughout your entire application. And it made it really hard to reason about that profile picture component. Does it have the data that it needs wherever it’s used? We don’t know. And so, Relay moves data fetching logic declaration into the component itself. So, it’s really component-based data fetching. You can look at a component, understand what data it needs to render, and know that it will have that data when it renders. So, it’s very easy to reason about your application. And it’s very difficult to end up in an inconsistent state. In fact, Relay largely prevents a lot of the errors that typically occur with data fetching. JAMISON:  So, in some ways this is kind of a unique problem to React because of the emphasis on a top-down data flow where you construct your app as a hierarchy of components and you pass things down through the hierarchy? JOE:  Yeah. I think it’s probably a similar problem for any type of system that has any sort of a reusable component. So for example, you can imagine Angular with directives, the same problem could occur. Anytime that you’re splitting up your rendering, have reusable pieces, reusable views, this problem can occur where you make a change to some reusable component and it assumes that it has some data. And you may have a page that doesn’t actually supply that data to the component correctly. NICK:  Yeah. I’ll actually expand on that, too. I would say it’s not particular to React. A lot of the ideas for Relay actually come from our PHP codebase. We have a system called XHP which is analogous to JSX. Effectively you can express markup and then it essentially at runtime becomes an AST that you can manipulate. And then we have a system called [prepare blocks] HP which effectively colocates our data fetching with our XHP which determines our UI. So, I think it works with any system where you’re expressing your UI in hierarchical views, which is a lot of systems. JAMISON:  So, you’ve described the concept a little bit, which sounds awesome because I’ve been using React. I’ve definitely encountered this problem of I need to add one piece of data to this thing way at the bottom of my hierarchy. Now, I have to pass it through 10 different layers to get it there. Can you talk a little bit about how it solves that problem? JOE:  Yeah. So, basically queries in Relay are colocated with the components So, just the same way that React Native showed that we can have styles, particular styles that a component needs to render, we’re really expanding upon the idea of what is a component? And we realized that the data definition has to be colocated. It’s the one thing that was missing in order to really fully reason about, colocating queries with the component we’re able to… so, we get this local reasoning as far as actually getting the data there, because the queries are defined using GraphQL statically. So, each component defines its normal render methods and life cycle methods. But it also has the queries that it needs. And those queries are relative. So, for example I talked about the profile picture example. Then you might have a friend list example where each friend list item composes the profile picture. And its query composes its child component’s queries. And so, that means as you walk up the tree, you’re actually able to have a single object that represents the entire query for the full subtree without having to render at all. So, we can statically say for this route, we know exactly what queries we need to execute, execute them in a single pass, a single roundtrip to the server, and then render the components. NICK:  I think the other piece which makes this all fit together is a more in-depth understanding of GraphQL, which is really important. So, it’s pretty distinct from most traditional ways of accessing middle tiers. So, it is not REST. And it is not custom endpoints, which most websites as far as I know are built on. It actually, you can express your queries at field-level granularity, meaning the server effectively publishes the type system. So, it publishes the fact that, “Oh, there’s a User type. It has such and such fields.” And then within Relay you can refer to those fields individually. And effectively what happens in Relay is that a centralized, fairly complicated component just sends over the static hierarchy of views and sucks out the declarative data, and then that is particular to each component, and then assembles it all for one query to the server. And it is this type system which makes this all work in terms of, “In this component fields X and Y are queried.” And the client specifies that. And it’s not encoded in the server, which is what distinguishes it from REST and from most REST systems and certainly from custom endpoints. CHUCK:  So, what do these queries look like, then? And how does it know what types are available? NICK:  So, the server determines what types are available. So, the general development model with GraphQL is that a server-side dev or a client dev who knows how the server works adds a field to these type definitions on the server which defines the type system. Then we can actually query that type system, meaning that the traditional example of GraphQL is that you have a root call, like node of 4, and then you can open a curly brace and query X, Y, and Z. In the same way you can actually query the types. So, you can say type of user and then fields and name and whatnot. And using that tooling, the client software knows what types are expressed on the server. So, that was one aspect of your question. What was the other question? CHUCK:  How are the queries structured and how does it know what types are available? So, you… NICK:  Ah. Go ahead. CHUCK: You talked a little bit about how you know what types are there, I guess. NICK:  Yeah, it’s effectively through tooling, right? So, we have, because we can access the type system programmatically, we can actually build fairly sophisticated tooling. So, one of the more powerful tools that we have available is called Graphical, which is effectively an IDE for this query language. So, at every step in the query, it’s a hierarchical query. Go ahead. JOE:  Just to be clear, basically when you’re writing it, it looks like JSON. So, basically the query looks like JSON. You basically just take the JSON that you’d want to receive and take the values out of it and just leaving the keys. And what you’re left with is GraphQL. NICK:  Yeah. JOE:  So, at a high level. NICK:  Yeah no, that’s very useful context. And then at every level as developers are typing them as tooling, a typeahead pops up and you can select what query. In that type system we also expose documentation and whatnot. So, we surface that. And so, that’s generally how you know what you can query. JOE:  Yeah. So, what this means is that for example when you’re working with Relay, if you were to add a field that doesn’t actually exist, so you’re… back to that profile picture component, if you attempted to add a field that doesn’t exist on profile picture, we know that from the type system. And so, we can give you immediate feedback. You don’t even have to run the application. The compiler where we’re transpiling the JavaScript can say, “Oh, look. You’re accessing an invalid type here. Did you mean this field?” Just today, I typed URL instead of URI and got immediate feedback that I was using the wrong field. JAMISON:  That sounds magical. JOE:  It feels kind of magical when you use it, yeah. [Chuckles] JAMISON:  So, I want to make sure I understand. Do you pull those definitions down to the client first? Or, they’re just implicit? NICK:  No, we pull them down for the client. And you pull them down during the development process. So, this is like a development-time tool. JAMISON:  Okay. So, you just bundle it with your JavaScript while you’re developing it or something? JOE:  So yeah, so what happens is when you’re writing a Relay component in JavaScript, we have a whole bunch of transpilation steps, right, for ES6 classes and other features. And one of those steps is looking for embedded queries. And the syntax that we’re using is an extension of the ES6 template [inaudible] rules. So, we have a specific tag, a notation, GraphQL which we’re able to say, “Oh, okay. We know that given this position in a React component this is going to be a query.” And we basically analyze that, take the query that you wrote and the schema, annotate that and say, “Oh, okay. This field has this extra metadata.” And we basically replace in the transpilation step that string literal with objects representing the query with these extra schema annotations. So, we have just the minimal set of the schema information that we need to make that query work at runtime. We don’t have to bundle or do any kind of runtime loading of the schema or have any extra metadata that we don’t need. NICK:  Yeah. We defer all this work about verifying the type [position] whenever possible to the development stage and not at runtime. So effectively, every developer who’s working on the system has a local copy of the current state of the schema which has all the types, all the fields, and all the behaviors encoded within that schema. JAMISON:  Okay. That kind of makes sense. Another thought I had when I first heard about Relay and GraphQL is it sounds really awesome if you’re Facebook and it already all exists. [Chuckles] But I mean, we don’t have GraphQL. We don’t even really have… it’s still kind of closed source. It seems like it’s being open sourced. But why do I care about this as someone who doesn’t work at Facebook? NICK:  So, I would say there are two reasons for that. One is I think it’s an at least relatively novel idea. So, we hope to influence the way people think about this stuff. But two, open sourcing this is in our roadmap. So, we can’t really promise any scheduling on this. But we really want, me and another one of my collaborators is effectively working on an open source reference implementation of the type system on JS. And we hope to be able to stack that on top of various storage engines. So, it doesn’t really make sense to open source Relay without GraphQL because they systems are tightly coupled, at least in terms of the client-side type system. So, right now from your perspective it is a bit vaporware-y. But we hope to make it, actually open source some real software that implements at least a subset of the system. JAMISON:  So, you’re trying to get people excited about it before you do that, kind of? CHUCK:  I’m curious. What kind of applications do you envision people really building with this, then? Is it the single-page apps that we see some of the other frameworks being used on? Or is this going to sit on top of it or underneath it or to the side of it somehow? JOE:  Yeah, I think we really… we haven’t… applications. So, we recently released a mobile ads manager application for iOS. And as we talked about that, that’s actually completely built using React Native. And all of the data fetching for the entire application is powered by Relay. So, it’s a really rich interactive application with really great gestures, very responsive. And the fact that all the data is fetched by Relay is I think a really great testament to how powerful the framework is. We also have an example, an experimental version of the Facebook newsfeed, which is rolled out to a small number of users. And we’re expanding that. And that’s all built on Relay for the web. So, it really is pretty powerful. And those are two different styles of applications. One is more of an information management, dashboard type of thing where you’re managing your ads. The other is a newsfeed, obviously standard newsfeed type application. So, it shows there are lots of different things you can do with Relay. I think, and I’ve worked with other frameworks outside of React in the past. And this definitely solves a lot of the pain points that UI developers on any platform face when trying to access data. So, I think that once we have an open source GraphQL implementation which we’re, as Nick said, we’re working towards, I think that once you see the power of this and once we’re able to open source it and give, show examples more, I think that, I hope that people really the power of these two, of GraphQL and Relay together. NICK:  From my perspective, I’m not on the Relay team so I get to brag about it a little more. For most of the consumer apps that I interact with, I think Relay would be a pretty good fit, especially if you think about it in terms of stacking on top React Native, in terms of the apps that you interact with a lot. You know, [inaudible] for example that ads manager app that Joe was referring to, originally this was, people thought it was going to be an 18-month project. You were going to have to staff it up with a large number of iOS experts and whatnot. And instead we were able to, we had one iOS expert on the project and essentially some JS, some people with JS domain expertise. And that worked really well with ads because a lot of their tools are built in React. And we were able to build what we think is a pretty high-quality native experience in single-digit months. So, we’re really trying to dogfood this and prove that this stuff is real. And it’s really been effective for us internally so far. JOE:  Just for myself, if I was to go and write another app outside of Facebook, I would want to use Relay. It really does solve the typical problems. You always are faced with, “Okay, I know what I want my views to look like. How am I going to get data into this?” right? As someone who knows JavaScript and can do server-side or full stack development, you still have to think about, how am I going to get data into this? And so, Relay basically just completely solves that problem. It removes the question of how am I going to get data in and out? How am I going to get my writes to the server? How am I going to deal with optimistically updating the UI and rolling it back? We’ve taken an incredibly large class of problems and baked them into the framework, so that things like scroll loading are a simple change query params from five to 10 and we do the minimal amount of work to get you the five more that you asked for. That could take a ton of work in other frameworks, just making sure that you have the data. You might over-fetch or miss some data. A lot of those problems are really complicated. And we’ve just solved them. And so, it’s an abstraction that you don’t even have to think about. JAMISON:  So, I know you’ve talked a little bit about GraphQL compared to REST. Do you think that GraphQL is just a better way to build your backends no matter how they’re being consumed? It sounds like GraphQL was used before Relay existed. Is that true? In just some native iOS apps? NICK:  Yes, absolutely. So, essentially the entire surface area of our iOS and Android apps access our data model via GraphQL. And that predates Relay. And they’re not even JS, right? So, they don’t have Relay. So, it’s definitely used outside the context of Relay. JAMISON:  But, so in some ways it makes a lot of sense for Facebook because I imagine if you had the documentation for the Facebook REST API for internal applications to be a million billion pages long. So, I could see how it’d be a lot easier for native developers that aren’t working on the backend at all to just say, “Here’s the data schema. I need the data that looks like this,” partially because of scaling problems with the engineering size, or engineering team size. Does this apply to smaller companies maybe that don’t have the same problems with large API surface areas? NICK:  Yeah, I never claim that any system is universal. So, for applications and systems where there’s a small surface area and a custom endpoint gets what you want, and also that that data model doesn’t change that much over time, GraphQL is pretty much, I would consider it overkill for that. It is a heavier weight system than REST or custom endpoints. But I also think changing applications that have an install flow from the user’s perspective opens up a new set of problems. What I mean by that is take for example our release cycle. Facebook releases new apps, the main app is launched every two weeks. And we commit internally to supporting the clients for at least two years. That means if you think about it, there are 52 extant versions of the app in the wild. And that’s very difficult. And that’s not even counting in the hotfixes and dot releases. So, if you think about it, if you change a custom endpoint or what a REST endpoint returns, you have to keep in mind the 52 clients that existed before. And what changes about GraphQL is that the data you fetch is actually embedded in the client. So, it flips that on its head. And I think that is a new way of thinking about it to the JavaScript community who was used to being able to re-push new JS whenever they want. JAMISON:  Sure. Yeah, you use [their] service and it’s… NICK:  So, that’s one of the problems that it addresses. Oh, go ahead. JAMISON:  Yeah, yeah. I was just agreeing with you. Yeah, you just deploy your app and deploy your service and it’s fine. CHUCK:  So, I’m wondering. Do you have a GraphQL driver for JavaScript and another one for iOS? NICK:  Absolutely. So, we have client software for both iOS and Android. And with this system, you effectively have the type system locally. So, we’re able to synthesize a ton of artifacts within iOS. So for example, when you run our client tooling in iOS, so we do the simple thing of emitting a bunch of effectively structs, because these are strongly typed languages, that represent all the data in our system. So, it serves as an IDL similar to Thrift or Protocol Buffers or any similar system. But we’re also actually able to synthesize persistence. So, one of the major projects of iOS a couple of years ago was replacing a system called Core Data, which is Apple’s provided system for doing persistence. And it just wasn’t scaling on a number of dimensions to fit the needs of our applications. So, we were effectively able to completely replace that system via this toolchain. Because you have the entire type system. So, you can synthesize and emit persistence backends for this. Or backends that interface well with that type system. JAMISON:  Are you talking about code generation? What do you mean when you say synthesize? NICK:  Yeah, code generation combined with systems that are used to interact with that code that is generated, if that makes sense. JAMISON:  It kind of does. NICK:  [Chuckles] Okay. JAMISON:  [Laughs] I mean, how does this apply to JavaScript which doesn’t have a strong type system? JOE:  I mean obviously, there’s no type system. You can imagine doing some things with flow, flow typing. But really where it comes in is when you’re declaring your data dependencies in a Relay component, having the GraphQL type system means that you get much faster checking of, are you attempting to access some data that doesn’t even exist? Are you accessing a field that doesn’t exist on that type? And that’s really where this comes in handy. So, I think for me it feels like that’s where the type system really comes into play in terms of actually as a client developer, is just quickly finding mistakes. What really is powerful is what Nick talked about with the single endpoint and not having to have multiple endpoints with multiple versions. You don’t need to think about those. You think about what data your application needs. And then we can do a very, very efficient query for that data. So, one problem that this solves for example is if you’re using something like Flux. Flux is a really great model and it just showed I think the power of one-way data flow. And we basically just extend that. And so, we’re able to do a very, very efficient query. So, a lot of people experiment with isomorphic Flux and making Flux work on the server. Relay works seamlessly on the server. So, we have in our experimental version of the Facebook newsfeed we can render 100% server-side and send down HTML. We have a mixed mode that we call preload where the server can do the data fetching and then send back the results of the client and then have the client render. And we can also do 100% client mode where all the data’s fetched from the client. And so, it allows you to find the right balance for your application. If you care about SEO, then you can use server mode. If it’s not important for your application then you might use preload or client mode. You might choose to do different things based on the user’s network speed. You might discover that, “Oh, we have a slow network connection so we’ll change modes.” We haven’t experimented with all of the stuff yet, but we have those three modes working. And we’re trying to find the right balance for our application. So, using this toolchain, because you’re just going through a single access point, you can do more things with it. You can [inaudible] and see which queries are slow. How can we optimize them? See which pages are taking a long time to load. Maybe we should load less information upfront in order to get a faster response time. It’s just much easier to do extra things on top of that than if you had a multitude of JSON endpoints. That would be much harder to think about in aggregate, right? NICK:  Yeah. And also for server-side efficiency concerns, it also provides an extremely powerful leverage point for all of our infrastructure devs to optimize our backends. So for example, we can attribute cost to every individual field in the system and then understand what things are expensive and what things are not, things of that nature. JAMISON:  So, I think I understand. The basic idea is by laying out the data in each component that it needs, when you examine the whole tree of your application you end up with this giant nested object that describes all the data that all the components need. JOE:  Right. NICK:  That’s exactly correct. JAMISON:  And then you send that off to the server, you get back that nested object, and then the client, there’s a chunk of code that lives on the client that knows how to pass all that data back down to the objects that need it, right? NICK:  Yeah, exactly. JOE:  Right. So, that’s like the first part of the flow, is we say, “Okay, you’re attempting to go to this page.” Let’s say it’s a newsfeed story. We can collect, statically collect without having to render anything, we can build up a complete object that represents the query for that entire view that we want to render. We can also look at what we have, what data we have cached locally. We might say, “Oh, because you saw this story on the newsfeed, we actually already have the information about the story. We just haven’t fetched the comments yet.” So, we can say, “Oh, well we don’t need to run this entire query.” We can actually diff that query, find the minimal set that we actually need, basically subtracting like with the virtual DOM where we do a diff about what updates we need to form on the UI. We can do a diff of the queries. So, taking the query minus the things that we already have, send the minimal set of fields that we actually need to the server, fetch those, we merge them into the store. So now, the store’s aware of those new comments. And then we can render efficiently. And when we render each component we actually read basically a set of the data, only the data that the component actually asked for is available as props. So for example, if you have two components that are both rendering, receiving a story object, maybe one of them is querying for the story’s text, one of them is going to show the story’s author. Those components will only get the fields that they asked for. So, you can’t accidentally reference a field that you didn’t explicitly ask for. Even though the system knows that for example we have a story author, your component didn’t ask for it so you can’t reference it. And so, this helps prevent bugs where you’re accidentally just getting some data and then somebody else deletes it. And then now your component stops working. So, it really isolates the components and ensures complete modularity. JAMISON:  So, I guess I still have some questions on how the client piece works. JOE:  Sure. JAMISON:  In normal React, you would pull some data from a store and then you’d manually pass it down as props. And it sounds like Relay takes care of a lot of that for you. JOE:  Yeah, exactly. So… JAMISON:  Does this mean that you’re handing off the responsibility for constructing the hierarchy of your application to someone else? I guess I don’t understand how you in practice, how it looks to build an app out of this. JOE:  Sure. JAMISON:  If you’re not manually passing stuff down. JOE:  Okay. So, just imagine the case of a top-level story component. And that component renders the text and then it also uses let’s say a comments list, which renders a sequence of comments, right? So, just three levels: a story that renders comment list and that renders comments. So, you still write your… you start, they’re just regular React components. And you do your standard React.createClass or use the ES6 class syntax to extend React.Component. You’d write your standard React class. And then you’d export, module.exports which go into these, Relay.createContainer. And so, we are using what we call Container classes. So, rather than mixins where the data comes in from the side, what we’re doing is creating a higher-order class. So, you define your basic class and we wrap that. So, if you actually look at the React tree, for every one of your application components there’s a wrapper, a Relay component. But of course that doesn’t actually get reflected in the UI. Your UI is still going to be just story, comment list, comment. But conceptually there’s a container that actually does the job of fetching the data and passing it in as props to your component. So for example, the story. The story component, the story Relay component is going to get the id of story. And then Relay will say, “Oh, I have an id. I have the query.” It will go read the data for that story id and with that query, and actually go and get the story that you asked for, and give that story object as prop to your component. So, what you get is just a regular JSON object with the fields that you’d expect based on the query. And then you would say, “Okay.” So you’d say, story.comment and pass that to your comment list. And then the comment list Relay component will go and say, “Okay. Now I know what story I’m supposed to get.” I go get comment list, it’ll go and fetch that, and then give the comment list just a standard JavaScript array of comments. So, your regular React components just receive plain JavaScript objects. And Relay does the work of actually reading the data out for you. JAMISON:  Okay. That makes a lot more sense. So, you still can write pure components that just take in props and return stuff. JOE:  Yup, exactly. NICK:  Absolutely. JAMISON:  And then you wrap them in something else that does the data management stuff? JOE:  Yup, exactly. NICK:  Yeah. And we use existing React components for it. JAMISON:  Yeah, that’s where I was getting nervous. Like wait a minute, do I have to change all of my existing components? JOE:  No. NICK:  Yeah, that was a fantastic question. JOE:  Yeah, it’s a great question. Actually… JAMISON:  Why, thank you. Oh, flattered. [Chuckles] JOE:  Yeah, so just on that note. In our Relay version of the Facebook newsfeed, so we have a story component right? And it can render all the different types of stories. But we also have a share page where I can share a story with people or with a group. And we actually reuse the same story component on the share page, even though it’s client-generated data. Or it’s something we’re about to write into the store. It’s not in Relay yet. We can reuse that and basically pass in existing standard JavaScript objects into that component. And then we can reuse all these Relay components. So yeah, you can still use, you could gradually take your components and migrate them over. We don’t a full story worked out for the migration path. But definitely you don’t have to go and rewrite everything. You’ll be able to largely just annotate your existing components and just add the queries that they need to work. JAMISON:  Sure. One more question. It’s kind of a broader one. So, one of the themes of React has been, put more stuff in your JavaScript. Put your templates in your JavaScript. Put your styles in your JavaScript even. And this is taking it one step further and saying put your data needs and your data fetching in your JavaScript. Is this too much stuff for one thing to manage? Are you worried about, I don’t know, too many responsibilities instead of separating concerns out among different things that are responsible for individual pieces of them? NICK:  My response to that, and it’s a very common question and a good one. JAMISON:  I imagine there are a lot of hands raised in the air and flailing around when people ask this question a lot, too. NICK:  Right. JAMISON:  It just seems crazy at first glance. Like, okay, you put your templates into there. You put your CSS in there. And now you’re putting your API access in there, too? NICK:  Right. So, in my opinion a lot of the reaction of that is reaction to previous horrors. When people think of not separating concerns or having things in the same file, they imagine a templating system where inline you’re doing SQL queries and then building HTML strings. And it’s all interleaved and awful. And trust me, I know all about that because when I got to Facebook a lot of the code was structured like that. And the reality is that in every application that I’ve ever worked in, all those things that you described, styles, layout, data fetching, is coupled. That is the reality of these systems. And so, we’re not in a sense artificially coupling these things. We are acknowledging a reality a reality that already exists. But the key thing about these systems is that they do separate the concern of actually executing how these things are materialized. So for example, Relay colocates GraphQL which is simply a declarative JSON-esque hierarchy for determining your data fetching. And we have a centralized component that iterates over everything and then smooshes it all together and issues it to the server. And that’s the current implementation. There’s nothing preventing us from executing it in a completely different way. So for example, we’re experimenting with systems where instead of doing a request/response format we’re instead streaming updates to a local cache that is a source of truth, instead of the server. So, it does separate concerns. But in our opinion it separates the correct concerns, if that makes sense. And we’re able to do that by having these centralized engines that go around and suck out declarative parts of these systems, and then can execute them in ways that are completely independent of each other. CHUCK:  Yeah, I think it’s interesting. Along the lines of what Jamison’s saying, this is the issue that I have with Active Record in Rails, is that it blends the data fetching with the business logic. And in a lot of cases you really don’t need it to be and it complicates things, because it couples things together that aren’t always intelligently put together. And I guess the worry that I have with the issue that Jamison brought up here with it doing too much is that you may be making assumptions that work well for Facebook and Facebook’s apps but not well for mine. NICK:  That is always a risk. And to connect it back to your first question about why do we open source, I think this is one of the reasons. This group that produces a lot of these centralized abstractions is called product of the structure. And that was there from the beginning. And there’s the Facebook bubble. And then within Facebook we’re a bubble within a bubble, because for most of our history we were simply producing software that only our internal developers consumed. And open sourcing is a really good way to verify that the inmates aren’t running the asylum, so to speak. JAMISON:  [Chuckles] NICK:  And so, it’s a really good check step. JOE:  That’s true. NICK:  So, that’s one of the reasons why we’re super excited to open source GraphQL and Relay. Actually, just to get personal for a bit, I was planning on going for a three-month leave from the company and coming back and doing something else. And then the React Conference happened. And I was blown away by the positive feedback that GraphQL got. And you can’t open source Relay without GraphQL. So, it really re-energized me. And so, it’s really exciting. But to your point, that’s why we open source stuff. And we might make wrong assumptions and we might have made mistakes. And it’s software. We can do anything we want effectively. So, we’ll go and fix them. CHUCK:  I really like the approach. This is right along the lines of where you see some of the other successful open source projects going, where they realize that they’ve made some assumptions. And some of them have totally validated and some of them haven’t, so they iterate to the next version. And even though it introduces breaking changes, it makes a big difference as far as what you get in the end and how easy it is to put things together. NICK:  Yeah, absolutely. CHUCK:  I want to ask another question. Mostly I use REST APIs at this point. I think this idea is interesting. One thing I see with REST APIs, and I’m worried that you’re going to have the same issue with queries at one endpoint, and that is that the APIs generally reflect the internal structure of the application, or the backend instead of actually addressing the needs of the frontend. So, I use Rails. And just as an example, you can generate a scaffold that effectively gives you CRUD access to the database, which isn’t necessarily what you need. instead what you may need is, I need to charge a credit card, or I need to add a comment, or things like that, that may or may not fit CRUD. But it’s an endpoint. And a concern for the frontend is, I need to add a comment, not, I need to create a comment entity in my system. So, I’m wondering. Are you concerned at all that GraphQL is just going to be a way for people to reflect their backend constraints or their database constraints in the frontend? NICK:  The short answer is no, because I violently agree with your concern. And the system was designed with that in mind. So, let me expand on that. I think ORMs are one of the worst abstractions foisted on software ever. Meaning that you start with the database and then you effectively synthesize an object layer which is then, if you pass around the objects around your UI it is just a leaky abstraction. Famously it was called the Vietnam of computer programming. You don’t want to get in and you can’t get out. So, GraphQL was really designed to, you start with the view and you express the query as naturally as you can from the view’s perspective. And then you work backwards to the technology. It’s like how, Steve Jobs always said this, may he rest in peace, that you always start with the customer experience and then work backwards to the technology. In the same way our customer experience is effectively the frontend developer or the product developer more generally. In terms of it reflecting the backend constraints, one of the reasons why GraphQL worked is that for years we had been building up an abstraction stack that was internal to our PHP stack. But it also was built with that philosophy of starting from the API then working backwards toward the technology. And GraphQL was a very, effectively a fairly thin stack on top of that business object layer, if that makes sense. But really, we really try to focus on the customer experience, in this case the frontend or product developer. Every other query language that I know of effectively starts from the storage backend and then creates an access pattern that is very congruent with that storage backend. The prime example is SQL, right? That is not written with the consumer in mind if you’re building complicated products. It is built to optimize the backend. JAMISON:  I’m just like… CHUCK:  I completely agree. JAMISON:  Clapping to myself. CHUCK:  I know. NICK:  [Laughs] JAMISON:  It is [inaudible] work. CHUCK:  Well, it’s interesting because it’s easy to do, right? You have a structure that’s been handed to you. And so, it’s easy to mirror it. It’s harder to think about coming from the outside in sometimes because you don’t know what the intermediate steps are. And a lot of people don’t feel empowered to create them. NICK:  Yeah. And there are… CHUCK:  And I like the approach here… NICK:  There are real constraints. That’s right. I would be lying… CHUCK:  Yeah. NICK:  If the backend constraints didn’t leak somewhat into the views. But the way that gets exposed is that there’s effectively a relationship between the server side and client side developer in the system, meaning that the entire system has a style to its API. But it’s not super generalized, meaning that the client developer can only access what the server developer has explicitly stated is allowed. So, the most simple example is that we have an order by directive where you can say, “Oh, I want these things ordered by X.” It’s not like we explicitly don’t allow you to order by arbitrary columns or arbitrary fields, pardon me. The server developer has to specifically say, “Oh, you are allowed to order by this because I’ve thought about it. We have it indexed. We use a custom backend, which serves as index.” So, it’s not a hyper-generalized query language. It’s a way for the server to publish its capabilities to the client and do so in a way that the client feels like it’s uniform. And also has this more view-centric API, if that makes sense. AJ:  So, to be honest I’m a little lost. And most of that’s my fault, because I wasn’t… NICK:  It is a very difficult system to explain without visuals. JOE:  Yeah. NICK:  If we showed you the IDE you would effectively instinctively understand it, I think. So, it’s hard to explain over audio. AJ:  Yeah. Well, and so one question I have then is, because you were talking earlier. That part I really connected with well when you were talking about the ORMs and how they’re very specific to a backend. And I totally agree. I think that sometimes ORMs are more of a pain that they’re helpful. And sometimes they’re very helpful. But, so with this, what adaptations of backends can you have that this can be a good fit for? NICK:  That’s a very general question, which I think is difficult to answer. I guess I can only speak from our experience that all… we have lots of backends. We have our main store which we call [inaudible]. But we also have specific backends for newsfeed and for timeline and oh, many other products. And effectively we’ve just figured out a way to make it work for each one of those systems. And I don’t think there’s really a [inaudible], to double use the word, of that process. We have a business object layer. We have effectively within PHP a query-esque API. And if you can make it work on top of that, you can make it work in GraphQL. I’m not sure if that answers your question. But… AJ:  Well… NICK:  Essentially any API which produces lists and objects can be mapped to this relatively readily. AJ:  Okay. And then I remember you were talking earlier about the relations and how you explicitly define customer.orders or something, so that you can’t accidentally reference something that you didn’t explicitly allow. NICK:  Yes. AJ:  So, in terms of relationships that are updated frequently, is this still a good fit? Because most of Facebook is not really relationships as much as it is logs, right? Well, maybe I’m generalizing there. But I think of the feeds. They’re just append-only logs. NICK:  So, that’s a product you interact with mostly. But I actually would, most of the data that I think about day to day is more in terms of relations. One way you can frame what Facebook has done over the past several, many years, is effectively we’ve tried to schematize all the data in the world as graphs. So, the graph is our fundamental abstraction. And you have nodes and edges. And effectively this system, a way you can think about GraphQL is it’s a way to explore arbitrary subgraphs of that global graph. And relationships such as friend relationships, all the invitees to an event, all the fans of a page, we have gobs of them. And there are effectively places where you go from one object and fan out with N edges. And the system is just ideal for doing that, actually and was kind of designed to do that. Ironically, actually the log based systems, we have to more bend over backwards and do awkward things in order to make those fit within the system. AJ:  That makes sense. CHUCK:  So, is this a way of accessing data going to replace Open Graph as the Facebook API? Or is it still just going to be used internally and open sourced for people to use other places? NICK:  So, those are really two different systems. The use case of accessing your own data is in general just very, very different from accessing an external data. So, I can’t really envision a world where our external developers access the data in the way that we do it. Most of our external developers are interested in injecting data into the system, so to create feed stories and distributions, and also to pull data out of the system to essentially accelerate the distribution of their apps. No one really has any particular interest in rebuilding our newsfeed as we display it, because it is incredibly complicated. And I wouldn’t see the upside of doing that, if that makes sense. So, it’s a very different use case. So, GraphQL will be a system that you can use your own… no, initially that you can use to access your own data. Now, you can imagine it becoming a lingua franca where if everyone exposes GraphQL across their systems, you could think of it in a way as a generic way for people to access other people’s data. And frankly, it’s kind of a superset of the capabilities that Open Graph provides and the Graph API. But certainly in the short-term, GraphQL will be a system that companies and Facebook use to access their own data. And then we can work from there. CHUCK:  And the other question I have is, are you… so, as far as security goes, I don’t want just anybody formulating GraphQL queries to send to my system. Is the structure inherently more secure? Or do you just secure your endpoint the same way you it with anything else? So, OAuth, authentication headers, HTTPS. NICK:  Yeah, we just use existing authentication. CHUCK:  Yeah, collecting your… NICK:  Basically we effectively grab an access token from out external platform and we ensure that’s from a Facebook app. And then we piece out and then we just execute the string. So, GraphQL’s an explicitly higher level protocol than HTTP. It is an application layer protocol. That’s one of the things I find actually strange about REST, is the coupling of HTTP and the application level protocol. So, the authentication mechanism is completely orthogonal to GraphQL. CHUCK:  Yeah, that’s what I was thinking. JAMISON:  So, this is a broad question. It seems like part of what you’re trying to do is, well you said it, part of what you’re trying to do is propose a replacement for REST for some applications, which is… NICK:  Yeah. JAMISON:  Almost more of a social problem than a technical problem, because there’s so much investment in education and tooling and just developer mindshare around REST. NICK:  Yup. [Laughs] JAMISON:  Are you, what do you do to overcome that? If you say GraphQL is objectively a better solution technically, that doesn’t make anyone switch. That doesn’t make anyone create the Rails of GraphQL that magically generates all your, well… AJ:  Balls. JAMISON:  Your one endpoint. AJ:  If it’s empirically better, I’m on board. [Chuckles] JAMISON:  You will go it alone, AJ. CHUCK:  GraphQRail. NICK:  So, I think about this a lot personally, because a lot of my career has been convincing people within the company to use new stuff. And I think there are a few things. One, the value add. It has to be a step function that is worthy of changing the way you think. I think actually React is a pretty good example of that, where we turned a lot of best practices on their head. And we’re getting a lot of adoption, even though it’s a big shift, because a lot of people perceive that it’s better. I also think there’s a, with these systems, you have to think of it almost like a little startup where you have to provide value from day one. So, there is a transaction involved where they’re getting something. But it’s also incurring a cost in terms of learning. And the benefit at every step along the way has to be clear. And then the other thing with these systems is you have to provide an incremental approach if you want them to be used in existing applications. So, I think that’s one of the questions that we need to answer as we go along the journey of open sourcing this and figuring out its compatibility with a REST API. I have ideas along that front. But it’s early in the process. JAMISON:  That is a fantastic answer. NICK:  [Chuckles] JAMISON:  I like what you said about the benefit has to be there at every step along the way. I feel like I’ve used technologies of all kinds where there’s this promise of the great productivity paradise that will only come if I just break through this awful barrier of madness that I can’t get through. NICK:  Yeah. JAMISON:  It’s not madness. It’s just I don’t know it. And then… NICK:  Yeah, there’s a lot of… we also, another phrase we use internally… JAMISON:  Once something clicks, then you’ll find that you could have… NICK:  Oh sorry, I talked over you. JAMISON:  No, no, that was it. NICK:  Okay. Another phrase we use internally is what we call the progressive disclosure of complexity, meaning that you have to present the system in such a way where you get consumable bits as you go along the process. And also understand the value at each step. So, I think a lot of the ways systems are unapproachable is if they start out with a high perfor-… at least this is the way I think. Some people think differently. But the way I think and I think a lot of developers think is that if you approach a system and you start of for example with the complete formal specification of a programming language. I don’t have the mental capability to consume that and understand all the benefits. I need use case and starting with a simple thing and be like, “Oh. I get this. Oh, I align with the system’s values.” So, I think a lot of it is the way you present the information as well. And to ensure that the simple things are simple, and the complex things are possible. So, there is an artistry to doing this in my opinion. JOE:  Yeah. NICK:  And luckily we’ve had a lot of practice internally. Because the way Facebook works is that teams are empowered. We have small teams that are empowered to use whatever technology they want, which sounds awesome. But there are actually downsides in that effecting change across the system is just a hell of a lot of work, because you’re effectively dealing with respect to this relationship, people who are an external entity. We don’t work where we have some CTO who says, “You must use such and such technology.” We don’t want to work in a place like that. And I don’t think really anyone does. Well, I shouldn’t say. I never say never or always. But the majority of developers that I interact with do not want to work in a place like that. So, we’ve had a lot of practice doing this. We’ve been able to do it. React is a great example. It took a lot time to get internal adoption. It basically started with one developer building a framework to drive a single typeahead. And that was years ago. And there have been a lot of missteps along the way. And you just have to learn from that and move on. JAMISON:  Yeah. It makes me think of my struggles trying to learn Haskell where I see smart people that tell me it’s so amazing. And then I sit down to do something and I just cry and cry. NICK:  Yeah. JAMISON:  It’s definitely not… NICK:  You run into [inaudible] the monad. [Laughs] JAMISON:  Yeah, exactly, yeah. NICK:  Yeah. [Inaudible] JAMISON:  Like, “Okay, I can write a quicksort that sorts this list of integers in memory. But I can’t make an HTTP request.” But Haskell has very different design goals. CHUCK:  So, are there problems that aren’t well-suited to something like GraphQL or Relay? JOE:  Yeah. So for example, games. You probably don’t want to write your game using Relay and GraphQL, right? It’s well-suited to applications that have their data in a graph format, which we think is a pretty large percentage of the typical types of applications that we write as frontend developers, or just UI developers generally on native platforms. But certainly, if you have an incredibly highly interactive application like maybe a stock trading app with thousands of updates coming in every millisecond, maybe I don’t know, you might want to have something designed specifically for that. Although depending on the amount of data, Relay and GraphQL could probably handle it. But definitely games are not suited. But most applications are lists of lists that traverse a graph. And Relay and GraphQL really handle that case very, very well. But again, I’m sure there are cases that do not. We’re not claiming to cover every single application case. And we’re just trying to find the main common case and what those pain points are and solve those. CHUCK:  Sounds good. Well, I don’t think we have any more questions. So, let’s go ahead and jump in and do some picks. NICK:  I have [inaudible]… CHUCK:  Jamison, you want to give us some picks first? JAMISON:  I will. Yeah, I’ll do it. So, I have two. One is a new album by a band called Purity Ring that I really love. It’s called ‘Another Eternity’. I think it came out last week. It’s a female vocalist in front of just this really deep synth-y electronic music. It’s great. And my next pick is a blogpost by my friend JT Olds called ‘What riding a unicycle can teach us about micro-aggression’. It’s about sexism and the small ways that little actions that don’t seem a big deal to the people in the majority happen constantly to the people in the minority. The example that clicked the most with me was, I have a name that’s easy to make dumb jokes about, Jamison Dance. For years and years growing up, I got, “Do you like to dance?” And each person that made that joke to me, it was the first time that it had occurred to them. And they thought they were making a joke. But to me, I’d heard that millions and millions of times. And I got so sick of it. I got over it, but it really bugged me when I was a kid. And that can be the same experience that someone who is a minority or different gender has in technology when they just get little comments that don’t seem like big deals to the people that are making them. To the person on the receiving end, because they receive them so often, it has a much bigger effect. So, it was a really well-written post that helped me understand things in a way I didn’t before. Those are my picks. CHUCK:  Alright. AJ, do you have some picks for us? AJ:  I should. You know what? So here’s what I’m going to pick. I pick this every so often but I’m picking it again right now. Overclock Remix. I just love listening to chip tunes and video game remixes. And if you don’t know that about me, you must not have heard more than three episodes of this show. But I knew. And so, I pick OverClocked ReMix. And all of their videos are on YouTube. And I’m listening to a pretty dang good playlist right now. Well, not right, right now. But, yes. And that’s all I’m going to pick right now. I’ll pick more next week. That’s it. Done picking. Over. CHUCK:  Alright. So, the first one I have to pick is an app on my iPad. And basically what it does is it allows you to share your screen or basically have it act as a second monitor on your Mac. So, if you have an iPad and a MacBook Pro or a MacBook Air, check out Duet. It just connects to your Mac. You have to install the app on your Mac as well. But yeah, then you just tell it to connect to the Mac and it does all the magic stuff. And then you have two screens. I’m sitting in this café right now and I‘m using that. I’ve also been playing this game for a while. And I’m not sure if I mentioned it on the show before, so I’m going to pick it again. And that is called Summoners War. And it’s a lot of fun. Basically you get monsters and you fight them against other people’s monsters. So, it’s one of those kinds of games. But it’s pretty cool. I’m enjoying that a lot. And yeah, that’s all I really got. Joe, do you have some picks for us? JOE:  Yeah. So, I’ve going to pick a book that I really, it really changed the way I think about I don’t know, just people and interactions in general. It’s called ‘Thinking Fast and Slow’ by Daniel Kahneman. I’m not sure about the exact pronunciation of the name. But yeah, ‘Thinking Fast and Slow’. And it talks about things like if you ask a person to read an essay about old people and then time them as they walk down a hallway, they’ll walk more slowly. And things like confirmation bias, and it’s just really interesting generally. A lot of just really cool things about human psychology that you wouldn’t think about. Definitely recommend it. Second one is just learning a new language in general, whether it be a spoken one or a programming language. I’m semi-fluent in Japanese and it’s changed the way that I speak and write English and the way that I think about programming languages, too. So, if you haven’t tried becoming bilingual, maybe give it a shot. NICK:  I like the pick of a human attribute. [Laughter] NICK:  That’s pretty good. Alright. JAMISON:  That’s an ambitious one, too. It demands a lot of effort from the people that accept it. NICK:  Yeah, it’s good. I have two picks. One, I like the music stuff so I’m going to do a music pick and then a product. So, music. One of my best friends has always been raving about this artist called Nicolas Jaar. And he produces really unique music. And this week I finally heard the song where I got it. He did a 12-minute remix of Florence and the Machine, a new song by her called ‘What Kind of Man’ and it just blew my mind. So, that is my new favorite jam. And then the product is called a Boosted Board. Have you guys heard of this? JAMISON:  Nope. NICK:  So, it is an electrically powered longboard. And it is one, the most, so fun. And two, it’s actually completely transformed my relationship with the city. So, I live in San Francisco. So, one, I’ll explain how it works. It’s an electric longboard and you have a control in your hand. And when you engage you can go really fast. So, it has a maximum speed of 22 miles an hour. Which if you think about it on a longboard, that is ridiculous. You basically feel like a superhero. But the thing that really makes it work is that it has regenerative braking. So, much like a Tesla or a Prius or any electric car, you can slow it down without engaging brake pads since the electric motor does it. So, you can slow down and stop on a 10% downgrade. And so, it’s amazing. First of all, just hilarious to see people’s reaction to this thing. Because you’re just at a stoplight and then you engage. And then you’re going as fast as cars, and accelerating faster than them. So, that’s pretty awesome. And two, It is amazing because you show up to [inaudible], instead of having to lock your bike or park your car, you simply pick up your board and walk in. So, it’s really opened up the city for me. Like for example, there’s a commercial district about 0.7, 0.7 miles away from me and there’s hills. So, that’s a big investment to go down and get a cup of coffee or something, because that’s a 12-minute walk or something if you’re walking really fast. Now, I just hop on my Boosted Board and I’m down there in three minutes. And then I would just walk in, have my cup of coffee, and I can leave. So, it’s just an amazing product and I’m a huge advocate of it. JAMISON:  It sounds like it avoids the Segway problem of looking like you’re just a jerk for being on it, too. NICK:  Yeah. That’s all the eye of the beholder. [Laughter] NICK:  A lot of people don’t like longboarders in general. There’s this hilarious Onion article about a social media expert on a longboard. And it’s just this expletive-laden thing about how that person should just die. And that’s hilarious. You should google it. But I will say definitively you look cooler at least than you did on a Segway. JAMISON:  Yes. Cooler than a Segway. That’s the bar. NICK:  Yeah, yeah. CHUCK:  Not a high bar, but a bar. JAMISON:  Yeah, yeah. NICK:  Yeah, it is a bar. I’ll leave it to the general population to judge how cool you look on a Boosted Board. My mom certainly thinks links I look cool on it. So, that’s something. CHUCK:  Oh, there you go. That’s all that matters. NICK:  [Laughs] AJ:  That’s important. NICK:  Yeah. AJ:  Because sometimes moms, they love you enough to tell you what’s what. NICK:  Right. [Chuckles] CHUCK:  [Chuckles] Alright, well I don’t think we have any announcements or anything. So, we’ll just wrap up the show. Thank you guys for coming. JAMISON:  Yeah, thank you so much. NICK:  Yeah, no problem. JOE:  Thanks for having us. NICK:  Yeah.[Have you noticed that a lot of developers always land the job they interview for? Are you worried that someone else just landed your dream job? John Sonmez can show you how to do this with the course ‘How to Market Yourself as a Software Developer’. Go to DevCareerBoost.com and sign up using the code JJABBER to get $100 off.]**[This episode is sponsored by React Week. React Week is the first week-long workshop dedicated entirely to learning how to build applications in React.js. Because React is just the V in MVC, you’ll also learn how to build full applications around React with the Flux architecture, React Router, Webpack, and Firebase. Don’t miss this opportunity to learn React.js from Ryan Florence, one of the industry’s leading React developers. If you can’t make it out to Utah they’re also offering a React Week online ticket. Go check it out at ReactWeek.com]**[This episode is sponsored by MadGlory. You’ve been building software for a long time and sometimes it’s get a little overwhelming. Work piles up, hiring sucks, and it’s hard to get projects out the door. Check out MadGlory. They’re a small shop with experience shipping big products. They’re smart, dedicated, will augment your team and work as hard as you do. Find them online at MadGlory.com or on Twitter at MadGlory.]**[Hosting and bandwidth provided by the Blue Box Group. Check them out at Bluebox.net.] **[Bandwidth for this segment is provided by CacheFly, the world’s fastest CDN. Deliver your content fast with CacheFly. Visit CacheFly.com to learn more.]**[Do you wish you could be part of the discussion on JavaScript Jabber? Do you have a burning question for one of our guests? Now you can join the action at our membership forum. You can sign up at JavaScriptJabber.com/jabber and there you can join discussions with the regular panelists and our guests.]**

Sign up for the Newsletter

Join our newsletter and get updates in your inbox. We won’t spam you and we respect your privacy.