104

104 JSJ Hypermedia APIs with Steve Klabnik


Panel

Discussion

01:15 – JavaScript Jabber Episode #91: JSON APIs

01:38 – Steve Klabnik Introduction

03:20 – JSON API & Hypermedia APIs

08:02 – Tooling

11:07 – How Hypermedia Relates to Real-Time Things

12:39 – Stateless vs Stateful

13:36 – REST

15:30 – Architectural Principles of Hypermedia APIs

  • Client Server
  • Stateless
  • Caches
  • The Uniform Interface
  • Code on Demand

20:22 – Endpoints

29:48 – Links

34:30 – HTTP Verbs

39:27 – Versioning

44:58 – Rust

46:12 – Resources

Picks

Next Week

JSConf and Organizing Conferences with Chris Williams

This episode is sponsored by

comments powered by Disqus

TRANSCRIPT

JAMISON:  I was going to say, Steve, this is the episode where we find out how wrong we were, right? [Laughter] STEVE:  Probably, I don’t know. [Chuckles] [This episode is sponsored by Frontend Masters. They have a terrific lineup of live courses you can attend either online or in person. Their upcoming course is JavaScript to Node, which covers some advanced JavaScript topics and real-time web development with Node.js. You can also get recordings of their previous courses like JavaScript the Good Parts, AngularJS, CSS3 In-Depth, and Responsive Web Design. Get it all at FrontEndMasters.com.] [This episode is sponsored by Component One, makers of Wijmo. If you need stunning UI elements or awesome graphs and charts, then go to Wijmo.com and check them out.]  CHUCK:  Hey everybody and welcome to episode 104 of the JavaScript Jabber Show. This week on our panel, we have AJ O’Neal. AJ:  Yo, yo, yo, coming at you live from the sweltering jungles of Virginia. CHUCK:  Jamison Dance. JAMISON:  Hello. CHUCK:  Merrick Christensen. MERRICK:  Hey guys. CHUCK:  I’m Charles Max Wood from DevChat.TV. And we have a special guest this week, Steve Klabnik. STEVE:  Hey everybody. I’m Steve. CHUCK:  So, we brought you on this week because we botched our JSON APIs discussion. [Laughter] CHUCK:  Or so, some people told us. It was interesting, the reviews we got. Some people were like, “No, they got it. It was just there was a lot to talk about and they glossed over a lot.” And other people were, “No, no, no. They totally blew it.” So, we thought we’d bring you on and maybe focus the discussion a little bit on Hypermedia APIs. STEVE:  Totally. CHUCK:  Do you want to well first, give us an introduction to who you are? I know who you are because I see you at the Ruby conferences. But maybe for the guests and the new people who don’t know who you are. STEVE:  Yeah, totally. I’m Steve. I am a complicated individual. I guess the easiest intro is that I work at a company called Balanced Payments and my job title is Philosopher in Residence. So, complicated. Basically what we do is we take in credit cards and charge them and give people the money when they use credit card stuff online. And so, my job is to be a bunch of things, but one of my roles is to be the, I joke, API Dictator. So, every single change in behavior in the API has to be signed off by me before it goes out. And so, I get to be resident HTTP nerd and standards nerd and make all that stuff work out. So, yeah. But I go to quite a number of Ruby conferences or have in the past. I’m starting to slow down a little bit because flying all over the place is exhausting. I’m currently writing three books: one on Rails, one of hypermedia stuff, and one on Rust. I don’t know. I could go on forever, lots of stuff. MERRICK: Sounds like you’re underachieving, honestly. [Laughter] STEVE:  It happens. I feel lazy. I don’t know. I have a different set standard for productivity than most people, I guess. But anyway, so I co-authored the JSON API spec. So, that’s also why this would be relevant for this particular conversation. And also, we use JSON API in production or work as well. So, there’s also that kind of stuff. JAMISON:  So, that’s the spec at jsonapi.org, right? STEVE:  Yes. JAMISON:  I want to plug your book for you, because you only half plugged it. It’s ‘Designing Hypermedia APIs’ and you should go buy it. STEVE:  Yeah, thanks. JAMISON:  I guess it’s crass for Steve to say that, so I’ll say it for him. Can you talk a little bit about JSON API, the spec specifically, and how it came about? STEVE:  Sure. JAMISON:  So, my perception was it’s like the Ember Data spec. STEVE:  Yeah. JAMISON:  And that’s all I got from outside looking in. STEVE:  This is a fun story, actually. So, the story of JSON API actually is a story about Yehuda and I going from me being a Yehuda fan boy to me being friends with Yehuda. So, way back in the day I was like, “I have my hero programmers,” and one of those was Yehuda Katz. And then from going to these Ruby conferences, we met and talked about stuff. And I had been working on hypermedia concepts and building stuff with hypermedia for a while. And actually I was in Utah at MountainWest RubyConf a couple of years ago. Basically Yehuda said, “I don’t believe in this hypermedia stuff. You should explain it to me.” And we proceeded to have a three-hour long argument about whether or not hypermedia was a good idea. At the end of it he basically said, “I will believe you when I see some code. I believe you more than I did before, but I’m not really sure what’s done.” And I was like, “Yes!” And so, that was this really humanizing moment where I got into an argument with a programming hero and won. [Chuckles] STEVE:  And so, now we are friends. I no longer believe that anyone is superhuman and we’re all just programmers trying to do what we’re doing, et cetera. So, a programming celebrity is stupid. But that argument turned into JSON API two years down the line. What were you going to say? JAMISON:  I was just going to say, it’s like in ‘The Princess Bride’ when the man in black defeats each of his enemies and then they join his crew. MERRICK:  Totally. STEVE:  I have not actually seen that movie. JAMISON: Oh. Oops. MERRICK:  That’s a shame, dude. STEVE:  I’ve heard good things about it. JAMISON:  Well, that’s what it’s like, STEVE:  But I’ve never seen it. So, at some point in time. MERRICK:  Could you illuminate me on what exactly hypermedia APIs are? How are they different from just regular RESTful services, et cetera? STEVE:  Yes. So, the lineage is REST doesn’t mean what everybody thinks it means. So, rather than trying to tell everyone they’re wrong, we created a new term and said, “Cool. Let’s talk about this brand new thing that you have no preconceptions about.” And so, hypermedia APIs, the simplest explanation is it’s by the book REST. What that actually means is that, so you know, have you ever tried to open a door and it’s actually a door that you push but it’s got a pull-looking handle on it. So, you try to pull it and you may need to push it, or the other way around, right? MERRICK:  Yeah. And if you get it wrong, you have to [inaudible]. STEVE:  [inaudible]. And it sucks. So, William Gibson called these things affordances, and this is a term that’s used in industrial design and some other design fields. An affordance is a property of a thing that demonstrates to you that you can take an action with it. So, the reason why you push on a certain handles and pull on certain door handles is because they imply to you that an action should be taken. So, a hypermedia API is an API that doesn’t just dump out raw data. It actually also includes affordances to let you know what you can do with that data in line with the response itself. So, if a regular REST service is just showing you doors, this is showing you doors with an open/close link that shows you whichever thing you can actually do with the door at the current time. So, the door is already closed. It would return an open link. And then if you follow that link, it would return the door, but now it would be open. The state would be changed to open and it would show you a close link as the [inaudible] one, or whatever. So, that’s the general concept of hypermedia. And hyper means above and media is media. So, above media, meaning there are links and relations between multiple bits of medias is sort of the general idea. It’s a generalization of hypertext from HTTP. MERRICK:  Got it. STEVE:  So, not just text has links. Other things do too, in essence. MERRICK:  That makes more sense. STEVE:  Yeah. So, JSON API is, there are a couple of things, but one of the things it is, is a hypermedia format. So, it includes links so you can tell people what stuff it is you can do with your data. So, after this discussion about whether or not hypermedia was a good idea or not, we were talking about, so one of the problems that Yehuda had back then was that Ember was just getting off the ground. And while Ember comes from Rails world in many ways, you don’t want to restrict Ember to just being for Rails. And so, he was trying to figure out, we should have an Ember API format. And I was like, “Dude, there’s a thing called media types. And that’s what they’re designed for, is that you say I’m going to produce something in this format. And that way you can write a consumer for the format and it just works.” And so, he said, “Yeah, whatever. That sounds dumb.” And then a while later was like, “Oh wait, actually you were totally right. Check it out. I wrote this draft of a spec,” and released the initial spec of JSON APIs. So, what it does is JSON API is essentially a standardization of the initial format that Ember expected and produced so that other servers could be written to interpolate with Ember transparently, basically. And so, that’s the lineage of it now. And it’s grown as people have used it for other purposes and done other things. But that’s the initial thing, was let’s actually write down a standard of what Ember is going to expect on a server. MERRICK:  So, can you talk a little bit about what kind of tooling, et cetera? Why is it a good idea to standardize on something like hypermedia? Why do you need a standard like this? STEVE:  Everybody’s JavaScript. This is a JavaScript show, not a Ruby show, so I can’t assume that you all believe in or even like Rails. [Laughter] STEVE:  So, Rails got so popular because conventions allowed people to be very productive. Because once you learn the convention, you can build things really quickly because you have the shared understanding of what’s going on. So JSON API means that instead of having to relearn, so basically it sucks that Twitter and Facebook and everybody else have totally different API formats. And so, what happens is you can’t carry any knowledge over from one API to another when you’re actually implementing things, because there’s too much stuff that’s custom. So, the idea is that if everyone produced JSON API, we would have a shared understanding for how to tackle specific problems that are almost universal. So, for example, one of the things is creating some sort of object. You probably want to build a resource of some kind. So every single API needs to deal with how you create a resource. And rather than making them bespoke, artisanal, hipster, hand-crafted, individual resources, we now have this shared standard for how to create a resource. And so, that way you already know how it works across different APIs, which means that you could write one set of code to work across the APIs. MERRICK:  Is there implementations of, I guess abstractions to create hypermedia APIs across languages that aren’t Ruby? STEVE:  Yeah. So, there are multiple standards including JSON API that do hypermedia stuff. So, one of them that’s very popular is called HAL. And one of the things that are nice about the media type approach is that it’s inherently language-agnostic. So, JSON API says nothing specific about Ruby or even JavaScript. It’s just HTTP. So, we have internally at Balanced, we actually have a full Python server side framework for generating JSON API that we’re hoping to open source in the near future, that basically gives you the ability. So, people have written client libraries in a bunch of different things. So for example, we have Python. And Active Model::Serializers is mostly kind of supporting JSON APIs. It’s a little out of sync at this point for Ruby. But we have this Python one. People have written JavaScript ones. And for other hypermedia formats, there are tons of people that have implemented things in tons of languages. A lot of people are actually in the .NET world, and so we see a lot of people coming from there actually, which is weird as someone who’s steeped in the tradition of open source. I don’t really have a lot of connection to Microsoft. But a lot of them are super into the concept. MERRICK:  Awesome. JAMISON:  Is there a client list on the JSON API website or something? STEVE:  Yeah. JAMISON:  You said there are all these different clients in different languages. STEVE:  We keep a list on. There’s an examples page on jsonapi.org and that shows, I think it’s in the examples one, yeah. So, it shows a list of client libraries and server side libraries. So yeah, we have listed up here already multiple JavaScript and iOS consumer clients, PHP, Node, Ruby, Python, server side stuff. JAMISON:  Cool. So, sorry, maybe this is deviation from where we want to go, but I wanted to ask about how hypermedia relates to real-time things. Does it apply seamlessly? Can you apply all the same concepts? Do you have to change anything when you’re working with real-time data? Is it just your resource is now a pipe that gives you more data? Or how does that work together? STEVE:  I’m slowly learning that I am an old man. JAMISON:  [Laughs] STEVE:  And so, real-time is one of those things that make me bust out my old man-ness. And so, who knows how you’re even defining real-time exactly? But most of it, so the hypermedia style is specific to client-server interactions. So, if you’re holding a long-open pipe to your server and you’re expecting bi-directional communication, that is a totally different architectural style. And it’s also totally valid. I’m not saying that it’s bad. But it’s definitely at odds with the principles of building things this way. Essentially that’s not nearly as scalable as the arguments. So, by keeping with client-server style architecture, you can scale for a lot less than long-running open connections basically, is the idea. MERRICK:  Do you want to talk… STEVE:  But to answer that is probably off topic. But generally speaking, yes, once you’re talking about bidirectional pipes, you’re no longer in hypermedia land, which doesn’t mean it’s not theoretically useful. But nobody has done any work in that area. [Inaudible] JAMISON:  Sure. And I guess some of the principles still apply. You could make the data you’re pushing down have hypermedia links inside of it. STEVE:  Yeah, totally. Right. JAMISON:  Okay. Cool. Merrick, were you going to say something? MERRICK:  Well, I was just going to ask a little bit about what is it that makes this model of writing APIs, namely statelessness, more scalable than something that’s long-persistent. But then Steve made the point that maybe that’s a little bit off topic. STEVE:  Yeah. Basically, the tl;dr is when you’re stateless you can horizontally scale trivially by adding in new nodes. And when you’re stateful, then you have to keep track of which connections are going to which servers. So, that inherently means you’re keeping track of more stuff which means you are slower basically. Not to mention just generally the resources. So, you open and close… and this might have changed as technology changes or whatever, but basically you could handle, if you only have let’s say 5,000 open ports or whatever, you open 5001 long connections, you’re screwed. But if you’re opening 10,000 short-lived ones but leave spaces in between, so there are all sorts of that kind of crap, too. But that is off topic and too low-level and too empirical, like you should test whatever works for you and yadda, yadda. CHUCK:  So, I want to come back around to REST and hypermedia APIs. It seems like everybody’s got a different definition for REST and it seems like people who talk about hypermedia APIs really have a focused answer. STEVE:  Right. CHUCK:  What are some of the differences though, between I guess the more traditional REST or Rails REST as opposed to correctly built hypermedia APIs? STEVE:  Sure. So, Rails REST basically just made all their stuff up, which is fine. [Laughter] STEVE:  That’s how everything gets happened, right? You just make stuff up and it works. But there is basically no real connection between the two in any sort of significant way. I would say that the closest thing that they share is that both agree that following the HTTP spec as closely as possible is a good idea. But most of the core things you think of for Rails REST are totally irrelevant from the hypermedia perspective. So for example, pretty URLs are totally non-existent and not a concept in REST. People use the word resource wrong, so they would say that /person/one, /people, and /people/new are three URLs to one resource. In the RESTful terminology, those are three separate resources. Let’s see. What else? That GET, PUT, POST and DELETE are CRUD is not true and not relevant at all to REST. They are that. They are also other things as well. And also, they got PUT wrong, and stuff like that. So, that doesn’t mean that Rails REST is not useful or good. It is way better than things we’d used previously and I am never totally sad to work with a Rails REST API. But one of the things about these kinds of discussions is that people really want there to be one answer. And we’re engineers, so there isn’t. So, while I advocate a particular style to be useful most of the time, it doesn’t mean that I think you’re a terrible person if you’re not building APIs this way, in the moments right now, or anything. But yeah. CHUCK:  So, what are the core tenets then of hypermedia APIs? STEVE:  There are seven architectural principles. [Inaudible] of course, because that’s where everybody derives their understanding of this from. So, I should also say this, too. The REST theory, what happened, the history of this is that the web is incredibly successful and that was sort of an accident. Tim Berners-Lee had no idea that this would be particularly a great thing. And so, what Roy Fielding sought to do with his dissertation was to take what had already existed and document why it was successful. That’s actually the lineage of REST, is the story of how the web works. So, when people say, there’s actually nothing that gets me more annoyed than people that comment on various websites and say, “REST is totally impossible and could never actually work,” or, “Hypermedia is totally impossible and never actually work,” when they are using the very thing that proves them wrong to make that point. [Chuckles] So, the web is RESTful, generally speaking. There are one or two small exceptions. But anyway, so the big points are client/server, as I mentioned earlier. You always have servers and you always have clients. Clients start the interaction between clients and servers. It is stateless. So, the server can take a thing from any clients. And statelessness is about the communication. Not that your application can’t have state, but that when you’re sending the message, everything that’s necessary to understand the request should be included along with the request itself. The ability to cache things is the next one. So, you have to build, transparently put in caches in these places. The uniform interface, which basically is a fancy word for saying that we all use the same HTTP verbs even though we have different services. We all use GET, POST, PUT and DELETE, even though that says nothing about our domain. They’re domain-agnostic verbs. The last one is that it’s layered. So, for example, you can then put a load balancer in front of a bunch of web servers. And your browser doesn’t care about that at all. It just cares that it works. You could put a cache in front of a server that needs caching. That’s totally fine. So, I’ve got these layers build up. The last one is funny, because it’s an optional requirement, which is a really silly thing when you first think about it, but kind of makes sense. And that’s called code on demand. And this basically means JavaScript. So, you’re allowed to write Turing-complete code in your clients that do alternate things. So, those are the big picture points of what actual REST actually means. And it’s very much like an information architecture kind of concept. It’s not like a lowly programmer building a thing kind of concept. It’s something that you extrapolate from to build your system. It’s not a checkbox, checklist of things necessarily that you have to implement per spec. So, that’s the summary. MERRICK:  So, one of the big questions I have with these, you know there’s this huge move towards thick clients where to render a page, you’re making these massive API calls. STEVE:  Sure. MERRICK:  Or a huge number of API calls. And I’ve seen different people are solving this in different ways. A lot of people are using that request batching concept where you can describe HTTP requests essentially within a single request. STEVE:  Right. MERRICK:  But then you forego caching. And so, I’m wondering if hypermedia resolves this problem at all, or if hypermedia API spec resolves this problem at all, or what your personal recommendation for this problem is. STEVE:  So, this is one of the bigger failures of Rails REST’s thinking, basically. So, one of the problems with a Rails-y REST solution is that you think that you need to have a discreet call for every individual action. You think about calls as function calls on a Ruby object. So, oh of course I need to call new first. And then I need to call append. And I need to add these two things together. So, this had happened when I first came in at Balanced for example, where we have a credit card number. And then, so that makes a credit card object. And then you have a customer object, then you associate them. And so, our intern was building out a prototype of how the new version of this will work. He showed me what he was doing and I was like, “Dude, why do you need three HTTP calls to make this happen?” And he was like, “Well, you need one to create the card, one to create a customer, and one to associate the two.” And I was like, “You have all the information upfront. Why is it not one call to make a card and a customer?” And he’s like, “Oh, well because that’s not really RESTful, right?” And I’m like, “No, it absolutely is good, according to the lines of HTTP, that you can make a resource that takes in the information for a card name and a customer and creates the card and customer entities on your system.” That’s totally fine. So, I would say that it’s not so much that hypermedia solves this problem. It’s just that you don’t tend to think about things as I need to batch up these 35 creates and some resource that does bulk resource creation and you give them the information they need and it solves it. It’s not something you need to work around. That’s a totally first-class concept when you don’t think about the way that Rails tries to make you think about it. MERRICK:  You mean, by creating a new endpoint? STEVE:  Yeah, so endpoint does not mean anything in REST. I should back up slightly. So, this is one of the things that are language confusing. So, in the Rails world you have resources, which are your domain objects. And you have endpoints which are the URLs that point to these objects. In the actual REST or hypermedia parlance, a resource is anything that can be named. And the way you name a thing is URLs. So, every URL is a distinct resource. So yes, you’d be creating a new resource/endpoint to make a new thing. But the difference is that resources don’t have to map one-to-one to your business objects, which are called entities. So, in Rails we tend to have a one-to-one, not even resource, they tend to take the idea of an entity, call it a resource, and then say you can have multiple endpoints to the same entity, which is conceptually very confused. So, I would say that you would make a new resource that allows you to create multiple entities. Does that make sense? MERRICK:  So, that makes sense. But then I run to the issue of composability. So now, consumers of my API don’t have the ability to compos things under individual requests. STEVE:  The do if you build in that endpoint. If you build in another resource that allows you to compose two things, then sure, they can do that. There’s nothing bad about exposing multiple ways. MERRICK:  Got it. So, exposing maybe a batching endpoint is not necessarily a bad idea if you need to enable client composability. STEVE:  Yeah. There’s nothing inherently wrong with doing that. It’s not awkward or weird. It fits right in with the regular old concepts. JOE:  Do you feel like most people think you’re a heretic? STEVE:  I don’t know if I’d say heretic. They definitely think that I’m nuts. [Laughter] JOE:  Do you feel like John the Baptist out in the wilderness crying? STEVE:  Yeah. Between all the random things that I tweet about, between all the weird obscure French philosophy stuff and all the REST stuff and all the social justice stuff, I’m pretty sure that 85% of my Twitter feed does not actually listen to anything that I say. [Laughter] STEVE:  But yeah, it’s no different. People definitely do think about that in terms of, they’re like, “Cool, Steve. I’m glad that’s working for you. Enjoy your weird corner in the woods where you mutter to yourself. Totally.” [Laughter] JOE:  Just as a guess, what percentage of developers out there do you think have the same paradigm of REST that you do? STEVE:  Percentage? JOE:  Yeah. STEVE:  Probably zero. [Laughter] STEVE:  I probably met a hundred people, total. This is incidentally why Fielding refused to stop answering questions about this topic, because after you get the one billionth email, you’re just like, “Please just go read the thesis and it just tells you.” This is actually how I learned this. So, the way that I learned this was some random person said, “Rails doesn’t actually do REST.” And I was like, “That person’s smart. But they said something that sounds stupid. I should maybe think about why I feel that’s true and maybe go look into what their argument is.” And then I was reading and I was like, “Okay, where is REST actually defined?” And people were like, “Oh, it’s in this dissertation.” And so, I read it and I was like, “What the hell did I just read?” first of all. And then secondly like, “Yeah, this has nothing to do with what Rails was talking about. What is going on?” and just actually studied it. So, I would say that not a whole lot of people, although it is kind of changing due to my multiyear campaign, at least in the Ruby world, people are starting to get an idea of what’s going on. And now they’re at the point where they, instead of not understanding anything that I’m saying and calling me crazy, they understand half of it and call me crazy. So, that’s progress. JOE:  So, it seems to me that in the early days before REST even became a thing that people talked about, there was this concept of endpoints when we started doing actual real endpoints. The endpoints were just whatever, right? STEVE:  Right. JOE:  Just created endpoints. Then REST came out and then everybody, except for the guy who invented REST did it wrong apparently. STEVE:  Yes. [Laughter] JOE:  And according to everybody else, that same thing is true from their perspective. Everybody else is doing it wrong but me, right? STEVE:  Right. JOE:  And so, then it became this very small, we’re only doing these endpoints to do one little tiny thing. And if you want to do anything complex, you have to call 35 endpoints in a row, right? So, what you’re talking about is a paradigm for REST. How is that different from the original, when we just didn’t even think of REST and we just built endpoints willy-nilly? STEVE:  So, the difference there is that in actual REST, the uniform interface constraint has four sub-constraints. And one of those sub-constraints is hypermedia as the HATEOAS, hypermedia as the engine of application state. And so, if you’re not doing links between your resources, you’re failing on that sub-constraint and therefore failing on the constraint, and therefore you’re different than REST. JOE:  Can you explain us for those of us who are not following you? STEVE:  Sure. So, applications work like state machines. We have a certain… there is certain data. We do operations to them. It transforms the data. We get new data, right? And this can be modeled as state machines. All of the… a state machine is one of the most useful concepts in computer science. And we don’t tend to think about our applications as state machines, but they basically are. So, you can also represent state machines in hypermedia very easily because each response is a state. And each link to something else is an edge that points out to another state. So, I guess I should say nodes and edges. So, each response is a node and every link is an edge. So, when you think about your application like this, if you had a state machine with no edges, it wouldn’t really be a state machine. You would just, you have no idea what to do. You’d have all these discombobulated states and you wouldn’t be able to figure out how they worked. So, the HATEOAS or the hypermedia constraint, because HATEOAS is a terrible term, basically says that you need to directly expose those transitions in your API itself. And that way, you can know what you can actually do with the application just by looking at it. So, if you’re in a state machine, you can see I have this exit and this exit and this exit from this node. And then you follow one and now you’re in a new node and you follow along. And so, your position in that state machine is where you’re at in whatever business process you’re on. So for example, let’s say that I want to order some pizza online from some sort of online pizza seller place. So, I go to their homepage because that’s the entry point for their service. And on their homepage, it has a link and it says what kind of food do you want? Pizza, sushi, whatever, and so I click on pizza. That now takes me to their pizza ordering page. So, I’ve progressed my business process in the application by changing some state about what it is I’m doing. And then there’s an order form that shows me I can get a peperoni pizza or a salami pizza or a veggie pizza. And so, I say I want three of each, and I click order. And that is also, order is also a link that takes me to the confirmation page. I’ve caused some sort of state change to happen. I’m moving through the process. At any point in time, I could have taken a different option, right? I could have quit. I could have gone to help. I could have chosen another store or whatever. And that’s a state machine of me doing stuff. MERRICK:  Can I just get maybe a little bit less abstract. Are you saying that the transitions to states that make hypermedia different are those links? STEVE:  Yes. MERRICK:  The fact that it tells you, this is a different state you can travel to from here. STEVE:  Right. So, remember our discussion about affordances, right? So, without any affordances, you wouldn’t know what you could do in your environment. And so, the way that we do it now is we include no affordances in the responses. We put them all in human-written documentation that you have to write up and figure out yourself, whereas when they’re actually in the response you can know what you’re doing just by looking at the service. It’s self-explanatory as opposed to needing a whole ton of extra crap that is not parsable by computers. MERRICK:  Man, something about that just blew my mind. [Inaudible] STEVE:  Right? It just clicked. I was like, “What?” MERRICK:  Yeah, it makes sense. JOE:  I totally dig what you’re saying. One of the things that I’m not mapping that out to is how that is implemented or reflected in the API. STEVE:  Sure. So for example, in JSON API, we have a section that allows you to return the data. So, one of the things I should also mention with JSON API is that it is pragmatic in the sense that I actually don’t think it’s a perfect hypermedia format. But I think that it’s closer to my ideal format than what we currently have. JSON API has some flaws in it that only I care about. And so, I’m willing to live with them in order to get more people using hypermedia stuff. So, with that little small caveat JSON API includes a section for links. And those links have essentially a relation and then the actual URL result. And so for example, I might have a new order relation. And so, I know when I fetch the home… I guess [let’s move into] actual credit cards. This is what my actual real world deployment of this stuff is. So, at Balanced we have this JSON API. If you hit root of our API with its credentials, it will essentially say, would you like to charge a credit card? Would you like to charge a bank account? Would you like to pay out a seller? All these different actions. And now I have names that go with the links. So, I would say, cool, the charge a card link is the one that I want. So, I click on charge a card and it would have the ability for me to fill in the card ID number, or in this case, the URL actually because we use URLs for IDs. And then, that would give me the card representation. Now, I’m on the card page. There’s a link that basically says, charge this card. And you fill it in with the amount and you submit it. And then the card is charged, whereas previously if I would have needed to know what all those URLs are separately I would need to code them in my client. Instead it walks these steps to make that happen. AJ:  So, question, somewhat tangential maybe, but when you refer to a URL or a link, there are two ways that I think of that. One is, well I guess three ways. But it doesn’t really seem to make sense to me to use relative URLs in the API. And there are absolute URLs where it begins with ‘/’. STEVE:  Sure. AJ:  Or, there’s a full URL that begins with ‘http://’. And to me, I see on the jsonapi.org page, your link has the full ‘http’ everything. STEVE:  Right. AJ:  But it seems like in an API, it would make more sense to just do it with a ‘/’ because then if you change the domain name or you’re working on the test server or whatever, it’s still going to be valid. Tell me a little bit about your thoughts on that. STEVE:  So, there are a couple of things. First of all, when I say link, I mean RFC 5988, my favorite RFC I think, maybe. I like to say that after every one because it makes you think like people have actually named them or whatever. [Laughter] STEVE:  But it’s called Web Linking. It actually defines what a link means. So, there are bunch of different kinds of links. And you’re right. So, links can be relative or absolute, right? So, it’s really up to you. There is no requirement in JSON API or in most hypermedia formats to use an absolute or relative URL. When half of your value proposition is you don’t need to calculate URLs anymore, adding a relative URL means you still need to tack it onto a base URL of some kind. So, one of the funny things about it is if you use relative instead of absolute URLs, you’re like, “Don’t construct any URLs, except put them onto the base. Take the relative one we give you and put them on the base to make the request again,” right? So, people tend [inaudible]… AJ:  [Well I would] consider that to still be absolute if it begins with a ‘/’. STEVE:  Oh, that’s not how the terminology works. So, an absolute URL is one that is the full qualified ‘http://’ or whatever protocol, that’s the word I’m looking for, protocol host name, end stuff. That’s absolute. AJ:  So, you’re qualifying absolute URL as absolute URL with the base. Because if I do a link in HTML and I begin it with a ‘/’ that’s considered an absolute URL. STEVE:  No. AJ:  No? STEVE:  That’s still a relative URL. It’s relative to the root of the server you’re looking at. AJ:  Okay. STEVE:  So, I guess maybe technically, actually HTML might define it the other way. You actually might be right. I’m not sure. Anyway, the point is that the distinction between including the hostname or not. AJ:  We’ll find out in the comments. STEVE:  Yeah. We’ll find it on the comments. Somebody will be like, “Oh, the guy who knows all the things doesn’t actually know all the things.” I haven’t looked at the BNF for the URL RFC recently. That’s a lot of TLAs. [Laughter] STEVE:  Anyway, so, woo! Anyway, the point is that you can include the hostname or you can not. Most people include it because that way you can just shove that value into your HTTP client and not worry about it at all. So, as far as you’re, so that I don’t end up going to the wrong place, that’s actually the strength of including the whole URL, not the weakness, because you as the server get to determine what your client sees. So, if you want to temporarily redirect everyone to the correct server because you’re going to work on a new one, then you can actually use the whole full URL to point them at a totally different server or service. So, you could actually say it like, “I need to take these servers down. Please migrate to these other ones.” Now we tend to actually use load balancers and pull machines out and get them in. So, you don’t have to do it this way. But in a more primitive time, you can imagine a situation which, my service is running on api.BalancedPayments.com and I temporarily spin up an api1.BalancedPayments.com and I redirect people to use that. And then they use that, and then I work on the server, and then I redirect them back, and everything is just fine. AJ:  I’ve seen that [works]. MERRICK:  What’s so mind-blowingly awesome about that is if clients aren’t hardcoding these actions, then it makes upgrading a particular endpoint significantly easier. STEVE:  Right. MERRICK:  If you need a new charge endpoint, you just put it in the response. STEVE:  Yup. And since one of the golden rules is basically clients don’t throw up on things they don’t understand, they look for things they understand rather than looking for things they don’t understand. So, then it works. So, I make the analogy of a bookshelf. If all of your books are in English but one of your books is Japanese and you don’t speak Japanese, you don’t go, “Well, I can’t read this whole bookshelf. There’s something I don’t understand here.” You pick out the pieces you know and you respond to those. And while another person with different capabilities might be able to read the Japanese book, it doesn’t wreck your day. Unless that’s the book you wanted to read of course. So, it’s the same with these client libraries. If I introduce a new capability in my server side, then the client can just totally ignore it and it doesn’t matter and people won’t even ever notice. MERRICK: Right. It’s just rad, because it also gets rid of the documentation growing stale problem. STEVE:  Yup. MERRICK:  Hey Jamison, did you have something to ask? JAMISON:  I did, yeah. So, I want to ask about the role of HTTP verbs, especially how it relates to embedding URLs. STEVE:  Sure. JAMISON:  So, if some of the actions you can perform on resources involve POST or PUT or whatever, you need to include things in the body. How do you embed that information in the URL? STEVE:  There are two ways to tackle this problem. The first one is put it in the link relation definition version, which is the one that JSON API supports at the moment. So, the idea is that you would say, for example, when you see the charge a card relation, you must send a POST request and only a POST request to that endpoint. And that becomes part of the definition of understanding what charge a card means. And so therefore, it’s encoded in the sense that you have that identifier, that part of the definition says it needs a specific one. That is an option that lots of people take, including the aforementioned how. Other formats actually give you the ability to specify the verb in the body. So for example, in HTML the format element gives you the option to put in GET or POST to determine what HTTP verb the form should send. So, you can pick one or the other and formats choose which one they prefer based on what their author prefers, basically. But they’re essentially equivalent. So, it doesn’t really matter as long as you pick one or the other and do it. CHUCK:  I’m not sure I completely followed that. How do you actually know which verb to tell people to use? STEVE:  Have you ever used Atom before? The RSS competitor Atom, not the GitHub editor. So, in the Atom specification, there’s actually also a sister AtomPub specification that talks about publishing Atom documents. And so, it includes for example, an edit link relation that says if you see edit and then a URL in an Atom document, then you need to send a PUT request to that URL and you could update the contents of what’s in there. And that is part of the Atom spec that talks about how the edit relation works. So, it says when you see edit, got to use PUT. And so, that’s one option. The other one is the HTML option of including it in the actual body. So, you can specify it upfront or you can make it as part of the body. It doesn’t matter. JAMISON:  So, it seems like the first option, you’re losing a lot of the benefits of having URLs in the first place, because you take away, you need outside information that isn’t contained in there, because you need to have parsed or understood the spec at some point to know what [inaudible] certain things, right? STEVE:  Sure. So, a human, this is not… So, in some senses yes, and some senses no. So, this is not necessarily an artificial intelligence, can totally understand everything that you’re doing style of API. A human still has to read. If you’re putting stuff in JSON, you need to read the JSON RFC or someone, a human, had to read the JSON RFC and then build the code to make it work. So, it’s not like we’re going to have total 100% clients always figuring out what they do, unless they’re intelligent as humans are, which is why the web works. So, the web allows you to do whatever you want and things don’t break because it’s written by humans. In talking about machine to machine interaction, a human had to have coded that machine at some point. And so, somewhere a human will have had to make the machine understand what that relation means, which is only through things. By creating the name, you allow the machine to pattern match. My understanding of this concept will be expressed through this name. When I see this name, I can apply this code. MERRICK:  So, to try to and make that more concrete, if your links come back and the key is edit, then I’m going to use PUT. STEVE:  Right. MERRICK:  If the key is create, I’m going to use a POST. If it’s something I don’t recognize, then it either needs to be documented or I’m going to call GET on it. STEVE:  Right. MERRICK:  Okay. JAMISON:  I was going to ask about, I mean this might be getting too heavy into the details, but how does that apply to specifying what the bodies look like in those requests? You can just punt on this if you don’t want to get that low-level with it. STEVE:  Yeah. Really, the things is designing a type is as much of an art as it is a science. So, I would say that that has a bunch of different solutions of which are all roughly equally valid. And yeah, I think it’s too much detail for this right now. JAMISON:  Okay. STEVE:  But there are [many] ways that people do that. And you just make up whatever you want. As long as other people think it’s a good idea, they’ll use it. One of the funny things about standards and standardization is that anyone can actually make a standards body or a standard. It’s only if everyone else actually pays attention to you. So, many people have made formats and they have not worked out. Many people have made formats and they worked. It just depends. So, there’s a certain degree of art. MERRICK:  Within this links definition, if there’s a create in the URL, that doesn’t include the taxonomy of what you need to send the object. STEVE:  That’s true. MERRICK:  So, that’s something that you have to be aware of, right? STEVE:  Right. MERRICK:  Whatever the taxonomy that [inaudible]. STEVE:  And some actually do include that taxonomy in the response as well. So, Collection+JSON is a type format that lets you sort through lists and things. And it actually has a query object which gives you the full parameters you would need to pass in as query parameters and how that works. It’s very much like HTML forms. HTML forms include what you need to send in the body itself. So, you can do that if you choose to. MERRICK:  Got it. So, I’m going to change the topic a little bit. One of the big problems that I’ve experienced writing APIs, especially with mobile devices that consume the same APIs in terms of downloadable apps, is versioning the APIs becomes very difficult. And deprecating APIs also becomes to be intractable. So, I’m wondering what JSON API or hypermedia, I’m not sure which umbrella to ask about, but I guess really what I’m asking is your personal opinion on how best to version APIs when you have to keep the old version to live for downloadable. STEVE:  Sure. This is my really out there in the woods stuff, actually. I think that versioning is an anti-pattern actually. And what’s funny about this is people instantly freak out when I say that, because they assume all kinds of things… [Gasps] STEVE:  …about what I mean when I say that. JOE:  I’m freaking out. STEVE:  Yeah. So the thing is this: everyone says use the right tool for the job. And we need to manage change when it comes to our services, right? Nothing stays the same. Everything is being changed all the time. So, one tool to tackle the problem of change is versioning. And I don’t think versioning is the worst thing in the world. I just think it’s suboptimal. So for example, at work we do version our API. I don’t think it’s strictly necessary, but it is a pattern. So, I personally prefer to put versions in the URL, because essentially the thing we have to remember is when you create a… so to tease apart what change even means, to talk about this and why versioning is important, you need to talk about change. So, there are two kinds of change. Well, more than two, but two that matter at the moment for this discussion. There are backwards-compatible and backwards-incompatible changes. There are also forwards-compatible and forwards-incompatible changes, too. But there are these four separate types of change and we automatically assume that we are talking about backwards-incompatible changes all the time. So, that’s the first problem with the versioning discussion, is that versions really only matter when you want to make a backwards-incompatible change. Especially if you’re in the style of clients that are only listening to the things that they know and understand, you can introduce new capabilities. You can make forwards-compatible and backwards-compatible changes. I guess technically, forwards-incompatible ones, too. Whatever. So, you can make backwards-compatible changes by adding things. And that would be totally fine. You don’t need to rev your clients. Everyone just listens and it works out. The question is what to do when you require a backwards-incompatible change. So, there are two approaches to this. And I think that the problem with using versioning by default is that by using versioning, you tell yourself that it will be painless to make backwards-incompatible changes and therefore you make them too often and too much. So, sometimes they’re necessary, but not always. So for example, if you want to migrate, we had a situation where we needed to migrate people from a concept we used to call accounts to a concept we called customers. And so, we left the accounts endpoints still running and going while we created the [accounts] one and told them to move over for a very long time before we killed the old version. So, we could have done that by saying, “Upgrade to the version 1.1 where the old one doesn’t exist,” or we could build the new one and the new version of whatever it is, tell people just to use the new one and the old one is deprecated, and then run analytics to see how many people and what people are actually using the old one. Especially when you’re doing an API, you can check based on the key that’s being sent over. So, you can actually see, “Oh, here are the five people that are still using that old thing,” and then you could talk to them about a migration strategy and then eventually move them off. And then once you’re done, you can eliminate it. Once you know that no one is relying on this functionality anymore. So, that’s what I would say is the responsible way to version your service, is to not introduce new versioning, strive to be backwards in compatibility for the end of time, essentially as much as you possibly can while getting away with it. And if you absolutely must make a backwards-incompatible change, instrument it. Find out how important it is to your customers. And then work with them on some sort of timeline sunset thing. You don’t need versions to do that. So, that was a really long rant. I hope that’s somewhat [inaudible]. MERRICK:  No, no. I think there’s one area where it’s a little bit convoluted for me and that’s say I’m making cards not backwards-incompatible, to go get their cards. Or it is backwards-compatible I mean. However, the charge has two versions. So now, what happens is the mobile client asks for the same cards URL. And unfortunately, that link points to the new charge, which it needs the backwards, because charge is backwards-incompatible. STEVE:  Right. MERRICK: It doesn’t have the right action. STEVE:  Right. This is the problem with backwards-incompatible change. And that’s why you should do it as infrequently as possible. MERRICK:  Okay. [Chuckles] STEVE:  So, basically in my universe, you would not actually remove. So, you would do them at the same time. You’d include the new data and the old data. You let old clients use the old stuff. You tell new people to use the new stuff. And then you would wait until you could upgrade all of those old people or enough of them that you’re willing to cut them off. This is what we do with Internet Explorer 6. We can’t actually kill IE 6. But at some point, it becomes a small enough amount of our traffic that we say f**k them. And we use banners that say, “If you’re on IE 6, please upgrade because you’re killing us, man,” and all that kind of stuff. MERRICK:  Yeah. It’s very web. STEVE:  Yes. MERRICK:  This idea is pretty much, think about how the web standards process works and emulate that in your APIs. STEVE:  Yes, because the web has been the most successful largest scale distributed system that mankind has ever built. And so, learning from its successes and failures is probably a good idea. MERRICK:  Seems like a good idea at the time. STEVE:  Seems like a good idea. [Laughter] STEVE:  Then, you know, freaking Heartbleed happens and you just cry for days. MERRICK:  Yeah. I’ve been following a lot of your stuff on Rust. And I’m wondering if you plan on, Rust obviously right now is not oriented around this problem set. But do you see yourself implementing hypermedia APIs et cetera with the Rust language? STEVE:  Maybe someday. Basically, yeah we’ll see. SSL support landed on master of the Rust HTTP project last week. So, it’s still early days. And now we know of course it probably should be fixed to actually verify these kinds of connections or whatever, given Heartbleed. JAMISON:  Oh, don’t even. Don’t even [inaudible] it. STEVE:  Yeah, yeah. Anyway, hopefully someday I believe that we can write server-side things in Rust. We’ll see how it goes. I have this feeling that Rust is more expressive than low-level systems languages have been in the past and therefore it will allow us to do this. I would never want to write a web service in C++. That’d be terrible and terrifying. MERRICK:  Yeah, yeah. STEVE:  But I think that rust has enough high-level goodies that it might be tolerable to write web services in. We’ll see how that happens as things go on. I don’t know. But I think that it will be. We’ll see. MERRICK: Sure, sure. CHUCK:  Alright, well definitely an engaging discussion. Is there anything else that we should know about hypermedia APIs or any other questions you guys want to ask? JAMISON:  I have lots of unknown unknowns still. STEVE:  Yeah. It happens. One of the funny things, you don’t learn about, unless you take time to study things, you don’t learn them the whole way through. So, the only reason that I’m Mr. Crazy-off-in-the-woods is because I spent a year of my life studying this stuff. So, it’s totally natural. It’s hard to bridge the gap. Fielding literally wrote a blog post about jargon and its ability to include or not include people based on what their training is, which is really interesting, I can give a link a link to or whatever. But yeah, it’s complicated, and it’s new, and it’s different, and it’s weird. MERRICK:  I have one final question. And that’s that you have a more intimate understanding of just this concept of REST and writing APIs and this kind of stuff. It’s obvious and apparent that you’ve thought a lot about it. And I’m wondering, what kind of resources and things can people leverage to develop that kind of understanding themselves? STEVE:  Totally. So, I always like primary sources. So, go read Fielding’s thesis. And then be confused and then read it a couple more times. There’s a rest-discuss mailing list that’s pretty decent. And there’s also my  HYPERLINK “mailto:hypermedia@librelist.com” hypermedia@librelist.com where, that’s the list for the book. But I let anybody join it or whatever and ask questions about this stuff. So, you can talk to people that way. There’s also a pretty decent #REST on freenode as well that people are in and actively helping stuff. There are a couple of really good books by O’Reilly. One of them is ‘Building Hypermedia APIs with HTML5 and Node’, which is buzzword-driven so they can sell books. [Laughter] STEVE:  But it’s actually nothing to do with Node whatsoever. He says right in the beginning, “I’m using Node because every web developer knows JavaScript. But this is not really a Node book.” And then the last one is the next book by the author, which is ‘RESTful Web APIs’ which just came out a couple of months ago, which is also good in terms of explaining how a lot of this stuff works. And of course my book previously mentioned is okay for now. I will be improving it more, shortly hopefully. CHUCK:  I get emails from you periodically saying, “I’m working on it!” STEVE:  Yeah. The problem is that I took on too much. So, this has been, I’m working ‘Rails 4 in Action’ now. And I told them last January that it would take me ‘til April. And here we are a year and three months later and I’m not done yet. So, I’ve been trying to put all my effort into finishing that off. I thought it would be a short project, so I took it on, even though I was already writing a book. And that was stupid. So, what are you going to do? The last thing I guess I should say before we go is we’re hoping to have JSON API finalized. So, the specs still says draft on it but since we have it production now on multiple places, we don’t plan on anything being backwards incompatible. But we’re cleaning up the last couple bits of details for an initial release of the spec. And that will be happening very soon, hopefully. CHUCK:  Cool. Well, thanks for coming on and straightening us out. STEVE:  Yeah, thanks for having me. CHUCK:  We’ll go ahead and do the picks now. AJ, do you want to start us off with picks? AJ:  I’ll start you off with a pick, Chuck. So, I might have picked this one before. Not sure. But there is a chit tune called Micro Boogie that is absolutely beautiful to listen to. So, I just love chit tunes. I’ve said that a bunch of times. And I’ve actually started playing this at weddings and other types of dances when I am DJ’ing. And of course, nobody knows it. But it’s just got this fun beat. And people will do stuff. They’ll do the train, or they’ll just throw their hands around and be goofy, or whatever. And so, it’s awesome and it makes me happy. And let’s see, other picks. I’m going to pick Virginia because I’m here and it’s warm and it’s humid. And that’s nice. And I’m going to also pick East Coast Time, because that’s what everybody should really be using anyway. And it’s two hours later. CHUCK:  Okay. Jamison, what are your picks? JAMISON:  So, I have two picks. The first one is a video that actually one of my coworkers did. She did an awesome degree in fine arts but it was a lot of abstract music visualization stuff. And she created a little synthesizer that is controlled by moving browser windows around. So, when the browser windows hit the bottom of the screen, they’ll play a sound and then bounce back up. Or they can bounce left and right and stuff. So, it’s pretty sweet. I just linked the video of it. And then the next one is actually totally unrelated. I didn’t even know Steve worked at Bounce. But I just listened to a podcast talking about them, some of the cool engineering stuff they do there. It’s a thoughtbot podcast. I think it was an interview with the CTO. STEVE:  Yeah, Mahmoud [inaudible] CTO, yeah. JAMISON:  Yes, yeah. It was super cool. And it sounds like they do lots of really cool things between open sourcing all the technology and even [lots of] the revenue numbers and things like that. So, there’s some cool stuff. Those are my picks. CHUCK:  Alright, Joe, what are your picks? JOE:  So, my first pick is going to be the Sphero ball. After last week’s episode on robots I got impressed and went and plunked down the money and bought a Sphero ball. And I’m playing with it with my son. And I’ve just had an absolute blast with it. It’s completely awesome. So, that’ll be my first pick, is Sphero. My second pick is a little thing that I heard about called HabitRPG, which is a website that lets you gamify your life. So, you can put in things that you feel like are positive for you, whether that’s things you do on habit s, or by habit, or things that you do on a daily basis, or to-dos you need to get done. And then also things that are negative for you in your life. And you put them in there. And then whenever you go in and say that I did this or I didn’t do this, or I did this negative thing, it will basically give your character experience in life and let you level up. And it gives you that instant feedback that you get from gamification, what keeps people playing World of Warcraft for way too long. CHUCK:  [Laughs] I like the way you said that. JOE:  Yeah. JAMISON:  It’s like World of Rake-the-leaves-my-yard now. JOE:  Exactly, exactly. [Laughter] JOE:  But it’s actually a really cool interface. And I like the implementation quite a bit so far, from what I’ve seen. And then my third and final pick is going to be a board game called Rampage. I played this a couple of days ago with my family. And it’s a board game where you set up all these little buildings. And then each person controls basically a Godzilla character. But it’s like a reflex-based game where in order to move, you have a little disc and you have to flick it around on the board. And wherever it goes is where you moved. Your whole goal is to eat the people. So, when you want to attack a building, you pick up your monster if he’s close enough to the building, and you drop it physically on the building. And then if it scatters the little people close enough, then you eat them. And if it scatters them next to somebody else’s monster, then they eat them. And it’s just a super, super fun board game. I really had a blast playing it with my family. My nine-year-old boy loved it. And my 16-year-old daughter loved it. So, that’s my third and final pick, is Rampage. CHUCK:  Awesome. Merrick, what are your picks? MERRICK:  So, I also have three picks. My first pick is the Extensible Web Summit that happened last week. It was just… it’s the best tech event I’ve been to so far in my life. And I just felt insanely privileged to be there. And the meeting minutes and all that stuff was very forward thinking. And people were thinking about the problems themselves and not the buzzwords. And there was something just so refreshing about that conference. STEVE:  I’m still bummed there was no publicity whatsoever. I put it on my calendar and then never heard anything again. MERRICK:  I know. STEVE:  I’m subscribed on [inaudible] list and there was no-… MERRICK:  Well, yeah. I live here in Utah and I emailed the organizer and I’m like, “Hey, is this like a meetup? Is it worth me flying out there and getting a hotel, et cetera?” because of what you said. It was just an Eventbrite page. But man, it was awesome. It was so good. The next pick I have is the Pebble Steel. I waited three months to get it, but it’s actually been a pretty cool product. It’s just a little watch that corresponds with your normal devices. And my last pick is the Philips Hue Lights. I’m so scared to use the word RESTful around Steve now. [Laughter] MERRICK:  Well, the Philips hue lights work over this HTTP thing where you send it verbs to URLs and you can change the lighting environments. [Chuckles] MERRICK:  I don’t know if it’s REST per se. But the Philips Hue Lights are awesome. And the Node Hue API project is just an excellent wrapper for the project. So, I’ve been having a ton of fun programming those lights to respond to different events and stuff like that. So, those are my three picks. CHUCK:  Alright. I’ll jump in next with my picks. The first one, there’s a utility that I found that you can run against your site to see if it’s vulnerable to the Heartbleed thing. So, I’ll put a link to that in the show notes. And I’m going to pick something else. I may have picked it on the show before. But the client that I’ve been working for, they’re using a system called Flowdock for their group chat. And it’s really slick. So anyway, I’ll put a link to that in the show notes as well. Steve, what are your picks? STEVE:  I got three quick picks. The first one is called Monument Valley. And I saw this game and bought this game because thought leader Tom Dale told me to. So, I will say the same thing he said, which is it is a beautiful work of art that happens to be a game for your iPhone. The idea is that you have these really gorgeous screens that are like Escher paintings where you can twist little bits of them. And then if they align visually they also align. So, you have two totally separate things and then you twist them so they touch. And now your character can walk across them even though spatially that makes no sense. So, it is super gorgeous and wonderful and amazing. My second pick is the book that I’m reading right now which probably no one will care about. But I think it’s fun to talk about anyway, which is a book called ‘Parables for the Virtual’. And it is Brian Massumi’s exploration of what affect theory means for the contemporary blah, blah, blah moments. [Chuckles] STEVE:  If you like random French dudes that people get annoyed about reading. He describes this language in his book as a black hole. And I think it’s pretty appropriate. It’s super hard to read, but it’s super great. And I’ve already found it to be amazing and fulfilling. The last one, which is one that people probably will care about, is the freaking Netrunner card game. Android Netrunner is a living card game by Fantasy Flight, which is my favorite American board game manufacturer. And it’s super fantastic. So, it is a card game that was originally created by the same guy who made Magic: The Gathering shortly after it came out. But then, all the other card games than Magic went bust. And Fantasy Flight has purchased the rights to it and now releases it under… it’s much more like a World of Warcraft subscription than it is a Magic card game. So, every month a new expansion comes out. And you just spend $15 and you get all of the cards. None of this opening random packs and trading with people for rare, expensive cards, just $15 a month and you’re current and own the full set of everything. So, that’s super neat and awesome. And it’s a great game, too, separate of the economics and all the other things around it. You play hackers versus evil corporations. And as the corporation, you need to advance your shadowy agendas. And the hacker needs to break into your servers and steal your agendas. So, it’s super, super awesome. Any programmer should be totally obsessed with it. So that’s it. Those are my three. CHUCK:  Sounds like fun. If people want to keep up with you, find out what you’re up to, what’s the best way to do that? STEVE:  Unfortunately, following me on Twitter is the best way to pay attention to what I’m doing. [Chuckles] STEVE:  I tweet a lot, probably too much. So, I apologize in advance if any of you do decide to follow me on Twitter. But that is definitely, it’s like a direct brain-to-tweet link. There’s no filter whatsoever. JOE:  I would like to say, I don’t think I’ve ever seen anybody who’s tweeted as much as you have: 87,000 tweets. STEVE:  I think I’ve tweeted more than everyword actually, which is not as recent. [Chuckles] STEVE:  Yeah, so it happens. But yeah, Twitter is definitely the place. Or you can email me at steve@steveklab.com but I’m terrible at email. So, it’ll probably take a while to get back to you. CHUCK:  Alright, well we’ll wrap up the show. We’ll talk to you all later. [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.]

x