ANDREW WARNER: Welcome. I an Andrew Warner.
I am the director of engineering at
RapGenius dot com. You can follow me
on Twitter at wwarner. And you can also
follow RapGenius on Twitter at RapGenius.
So Tweet at me during the presentation,
after the presentation, tomorrow.
Whatever. I'm down. I will respond to your stuff.
So, this is really exciting for me. This is
my first RailsConf speaking. And so, you know, I'm
super excited to be here. Come on. Little round
of applause. Yeah. Yeah.
This is very exciting for me, not just because
I'm speaking, but also because you all, you know,
this is a pretty full room. You all chose
my talk over the other two talks! This is,
you know, it makes me feel good. It also
is crazy, because, how do you even know what
I'm gonna be talking about? I had some summary
that's kind of vague. Like, maybe I'm gonna say
some stuff, but, you know, maybe I'm gonna change
it a little bit. Now I've got this slide
on the screen that says Rails Holy Grail. Who
knows what that even means? So, you know, I'm
excited that you chose me even besides all this
stuff.
So, you know, I'm gonna be talking today about
the Rails Holy Grail. I'm a little bit disappointed
that DHH kind of stole my thunder with his
Holy Grail slide. But, you know, I, I still,
I'm gonna use it. I couldn't find another replacement
Holy Grail slide in the meantime.
So, I guess, what am I gonna be telling
you about? Well, first, I'm gonna be talking to
you about what the Holy Grail is. So what
I mean when I say the Holy Grail. I'm
gonna be showing you some existing Rails solutions that
kind of get us close to this. I'm going
to be offering up a new solution for your
consideration today. And I'm gonna show you what else
this new solution gets us.
So, first off, what is the Holy Grail of
the web? This background is like the song Holy
Grail by Jay-Z. I don't know. So, the Holy
Grail of the web, what I actually mean when
I say Holy Grail, is the best possible user
experience combined with the best possible developer experience. So
it should be very easy for me to rapidly
develop an application, as a developer, that is also
easy to use for a user.
And so what is the best possible user experience?
Well, I'm talking about sort of a, a single-page
app thick client feel. So you shouldn't have to
reload the entire page every time you, every time
the user actually clicks on a link. So in
2004, when Rails came out, it was really great
because it allowed you to create, very quickly, websites
which were kind of a thin client, where every
single click reloaded the whole page.
And this was revolutionary. Before that, you know, it
was really difficult to make a site rapidly. And
around the same time, actually, Google released this Gmail
thing. Kind of hard to see the screenshot, but
I think you're all familiar with what Gmail actually
is. Gmail was this single-page app where every single
click actually loaded right on the same page that
you were on whatever you content you wanted to
see as the user. You didn't have to wait
for your whole browser to refresh. This is pretty
good. So it's just no full page reloads at
all. This is the best experience for the user,
and it should sort of feel like a desktop
app or a mobile app in terms of the
native feel.
The best developer experience is a little bit different.
So, you should be able to use a developer-friendly
framework. You should be able to rapidly develop something.
You shouldn't have to reinvent the wheel. Easy things
should be easy. So, Ruby on Rails is one
of these frameworks. You might have heard of this.
Kind of why we're here today. So you should
be able to use a developer-friendly framework.
You should be DRY. You shouldn't have to repeat
yourself. D-R-Y. Don't Repeat Yourself. But actually, what I
mean here is more like DRV. So what is
DRV? Well, I mean, you shouldn't have to repeat
views. You shouldn't have to write one set of
views that lives on the client's browser and one
set of the views that lives on your web
server.
You should be writing mostly one language. At least,
in so far as views are concerned. So you
shouldn't have to context switch. Context switching is very
expensive. Sort of switching from Ruby and Rails to
JavaScript. This is difficult for us, as developers.
And your website should be SEO friendly. So I
guess this part really applies to content sites. So
I work at RapGenius dot com. Content and SEO
friendliness is extremely important for us. We lost a
bunch of traffic when we actually got banned from
Google for a little while. They showed us exactly
how important SEO was. So your site should be
able to show a crawler, a search engine crawler.
HTML that it can index and than make available
for users' searching.
So so what is the closest thing to this
Holy Grail today?
Well, it's kind of the node.js. There's a node.js
solution that I think is the best thing. Come
on, boo node.js! Give me some boos.
So there's this Airbnb Rendr framework, right. So this
says render your backbone JS apps on the client
and on the server using node.js. So this framework
is, you know, pretty easy to use. You write
your backbone JS client-side app and the client can
sort of incrementally update the page and this sort
of Gmail-like experience. And then the server can also
render full HTML pages for arbitrarily deep links. So
the user can still see a full HTML page
if they get deep-linked, and a web browser, or
sorry, a web crawler for a search engine can
also see HTML. So this, I think, is the
best solution right there. Right, out there today.
And here, I've actually built like a little demo
app using render to show you how cool it
is. So this is a little bit washed out.
But, this is sort of a mini version of
our site RapGenius. It's, so RapGenius allows you to
view documents and read documents and also read inline
annotations on those documents. And the annotations are meant
to provide context and also explanation, if something's complicated,
and just add to the text.
So here I've built RailsGenius, which allows you to
add context to, like, Rails talk abstracts. So this
is my talk. And I've added some inline annotations
here, and the, the point I'm trying to make
is that we should be able to, when I
click this link, to add views, which is actually
an annotation, this shouldn't refresh the whole page. It
should just load-in the part of the page that
changed. Which is a much better experience for the
user.
So if I actually click on this, it just
loads that part of the page. You know, this
is something that, you know, might be familiar to
you from using apps, but it's, it's kind of
hard to like do this out of the box
in Rails. And, you know, also you should be
able to like edit it right there and that
should just snap in the edit view, et cetera.
And this should not be too, too difficult to
build. Looks like I lost my internet connection. There
we go.
So this kind of stacks up pretty well. It's
DRY. We have one set of views. It's SEO-friendly.
You know, we can serve HTML the crawlers. It's
a thick-client feel, so single-page app. Mostly write one
language. It's backbone JavaScript, et cetera. But it is
not Rails. So I think it takes, it still
took me awhile, even with this render thing, to
like, create an app that was good. And Rails
is just much easier to create like, the vanilla
example apps using, like, scaffolding or even not using
scaffolding. It's just way faster for development. So I
still think this is bad even though it's the
closest thing to the Holy Grail today.
But, my point is that Rails, I'm, I'm worried,
because I think Rails is kind of getting left
in the dust in this respect. Like, it's kind
of, there's not really like an established solution for
building like a thick client good experience Rails app.
And so now I'm gonna show you some sort
of solutions that get part way there. So let's
look at those.
So one option, and, you know, this is kind
of a joke but it's a serious thing that
people actually do, is creating one version of your
app that lives on the client, and one version
of your app that lives on the server. And
so, you know, in this example you would write
erb or HAML on the server, and then you
would have an API that returns JSON from the
server to the client, and then the client would
figure out how to render new parts of the
page that it wants to snap in using like
some kind of frontend like handlebar or underscore.js templates.
Right, so this seems kind of reasonable. But the
problem is if you forget to update both templates
at the same time, you're gonna end up with
some inconsistency between the client and the server in
terms of the logic. And this can be very,
very dangerous. It can lead to some hard to
suss out bugs and, you know, we all know
DRY is a good thing to strive towards.
So this doesn't stack up very well. It's not
DRY. It's SEO-friendly. It's a thick client. You didn't
write mostly one language, though. You had to write
a bunch of stuff on the client and the
server. And we only get a half point for
Rails. So you've gotta spend a lot of time
still on the frontend noodling around there.
All right. So Turbolinks are something you also might
have heard of. You might be thinking, well I
can just do this with Turbolinks. This is like
a one-liner, right? So Turbolinks, the way it works,
is you write just one set of views, and
then when the user clicks on a link, you
can just pop in the whole new page but
save the browser instance. So you save on this
overhead of, like, parsing and compiling CSS and interpreting
JavaScript and, you know, running all this stuff. It,
it's actually kind of expensive to spin up a
browser instance for the client. So you, you eliminate
all that overhead and your client is extremely simple.
You basically have to write no JavaScript.
So the problem is that Turbolinks kind of ends
there. There's nowhere else to go. If you want
to snap in, like, just a new part of
the page, you've gotta write some kind of custom
controller action that just returns that part of the
page and then you've gotta use like some jQuery
soup type thing to like snap that in and
then you're relying upon your, your page structure. So
that is not a great solution.
But this works pretty well if you're trying to
do, depending on what you're trying to do. So,
you know, this is DRY. It is SEO-friendly. It's
not really like a proper thick client, though. It's
kind of like a fake thick client. Feels almost
like a thick client. Not quite there. Mostly write
one language. We've got that covered. We've also got
Rails covered. So this is kind of why Turbolinks
is so popular I think. Because it basically does
what you want without much hassle.
So there's also this Ember/Angular/Backbone type movement now. You
might have sort of seen, there are a bunch
of talks about this. People allude to it all
the time. This is sort of the new way,
this is the new wave of building Rails apps.
So you just have a JSON API in your
server, that's it. Your entire app experience lives on
the client, so it lives in JavaScript or CoffeeScript,
what have you. And the initial page load, the
first time your user visits the site, they download
like this whole JS app thing, and then that
sort of boots up and figures out how to
like render the site.
And so this might remind you of new Twitter.
So Twitter in like, 2010 I think released this
new experience where they were claiming this, exactly. They
were saying this is going to be much better
for our users because we can just sort of
like snap in a new Tweet when you click.
And they actually found that this was kind of
costly. Like, sometimes it would take ten seconds to
render a 140 character Tweet. Because you had to
download like all these assets and then like that
would sort of like boot up, spin up and
build the page. This isn't like an actually good
experience for users, at least the first time they
visit the page. It's actually pretty bad.
So it doesn't quite stack up great here. It
is DRY. It is not SEO friendly, though. Now,
there's some tricks to sort of, making it, sort
of making it SEO friendly, but, you know, for
the most part it's kind of hard to make
it, you know, allow your app to like serve
HTML to a crawler. Now if you're not building
a content site, maybe it doesn't matter. But, you
know, my claim is this is pretty important on
most websites. It's a thick client. You don't get
to write mostly one language. Half of it's JavaScript.
So, again, half point for Rails.
So the point that I am trying to make
here is that each of these things makes like
a key, key trade off that we can't live
without. So what are we actually going to do
about this?
Well, now I'm gonna show you like a new
solution that, you know, maybe it's good, maybe it's
not. And actually, this starts with a, sort of
like, admission. So I kind of lied to you
before. I told you I built this app that
I was showing you before using render which is
this like, node.js thing. But the truth is, I
don't even know JavaScript. I don't even know anything
about node.js. Render. I just read about it, right.
I actually built this app using this new sort
of like technique slash library called Perspective.
So again, here's the same app. And just to
remind you, you can kind of click around here
and, you know, things just sort of load. And
this is a very simple example, but things are
snapping in, you know, just the parts of the
page that are changing. Need to get changed. And
you can sort like edit and save stuff. And
we're just sort of updating parts of the page
that need to change.
And so this is this perspectives thing, which I'm
claiming is better, right. So let's see how it
stacks up on the chart that I just made.
It's DRY. It's SEO-friendly. It's a thick client. You
write mostly one lang- I think you see where
this is going. And it's Rails. So I checked
all the boxes in my own talk. This is
a key, key thing. You have to be able
to do this if you're gonna speak at RailsConf.
You gotta have a chart, checks all the boxes.
This is good.
So, you know, the key sort of thing here,
the key part of Perspectives, is that we want
to be able to share our templates between the
client and the server. So like the server should
be able to render full HTML. And the client
should be able to like receive JSON and like
render a template, right. This is sort of the
appeal of something like render.
So, here, you know, let's, let's say we thought,
well maybe we can sort of share templates. Maybe
we can share our existing erb templates. Those are
pretty easy to write. So here's like a simple
erb template, right. We're just generating like a link
to a user. We're using the name as like
the anchor text. We're using user_url helper from Rails
to like generate a link to it. This is
pretty simple. You might imagine that using something like
Opal, which transforms Ruby in JavaScript, you could like
pour it your whole server, kind of like, instance,
including all these helpers link link_to and user_url, to
JavaScript, and then you could just jump down your
erb template and then that could get sort of
rendered on the client.
This might, you know, you might think that this
works. But, actually, you can kind of do more
stuff in erb than you might sort of be
aware of from simple examples. Like, you can, here's
an example, where I'm actually just running like a
SQL query in an erb template. And this, I
think, demonstrates like, the fundamental difference - yeah, boo!
This, I think, demonstrates like a fundamental difference between,
you know, the client and the server, is that,
they're kind of in different environments. Like, the server
has access to resources that the client, not only
doesn't have access to but shouldn't have access to.
The client should not ever be able to like
hook up to the database and ask some questions.
Right, so. And the client is the same. Like,
the client knows stuff about the user's browser. Like,
they can inspect local storage and all this stuff.
Like, they're fundamentally different environments. And so I don't
think that any of the existing templates out there
really get you this sort of shared environment for
free.
So, the way, you know, so the way to
get to a shared template between a client and
a server is to find the lowest common denominator.
So, like, if you've taken, you know, calculus at
the graduate level, you might have heard of the
lowest common denominator. It's the way that you are
able to like, if you're trying to add fractions,
you can like, multiply the denominator-
The point is, it allows you to like find
some common ground between, you know, the client and
the server, right. So we need lowest common denominator.
Which is the dumbest possible template. So we need
something that's really dumb, that has, that basically can't
do anything. And so what is that? Well, that's
mustache. Mustache are the dumbest templates out there. Don't
tell them I said that. They're probably in the
other room or something. But they're, they're pretty dumb.
You know, you might have heard mustache templates referred
to as being logic-less. I actually think logic-less is
kind of like a bad way of describing it.
Because when I hear logic-less, I'm kind of thinking,
like, OK, I can't write like an if statement.
There's probably no like for loop situation. Like, what
else can't I do? Well I probably can't do
like an if-else, like, you know, the reality is
you can actually kind of do that stuff. It's
called a different thing. So I don't like using
the word logic-less.
It's more like you can't run arbitrary code. It's
more like no code, code-less or something. So you
can't run arbitrary code. This is the sort of
take away from mustache, right. And so, you know,
this is kind of cool because, because you can't
run arbitrary code, we can write mustache template renders
in all these different languages. So you can easily
render mustache templates in Ruby or JavaScript. If you
want to use one of these other languages, these
are terrible, but I guess you could use like
dot net or something if you wanted to render
a mustache template in dot net. I don't know
what you're doing but you might be able to
do that.
So, to show you like how to create a
mustache template, I want to look at like a
specific example. So here's, like, the RailsGenius app, and,
you know, in the left, lower left-hand corner here
there's like an annotation, right. So this is sort
of annotating the line node.js. And if we sort
of zoom in on this thing, we can see
there are a few different components.
There's the section of text that's annotated. So we'll
call that the referent. This is like a fancy
word for like reference or something. So we'll call
that the referent. That's the line that I highlighted
and explained. And then we'll call this the sort
of body. And you'll notice the body can contain
like arbitrary HTML. There's a link to node.js dot
org. A link to Ruby on Rails, et cetera.
I'm sort of adding, like, you know, I'm adding
hyper media here because it's the web.
And then there's this edit link, right. And so
this edit link, you might imagine, should appear for
some users and not others depending on, like, what
your permissions are or what your sort of situation
is.
And so mustache, the, the template for this, the
whole template, looks like this. So I'm gonna go
into like the specifics of how I would actually,
you know, what this is doing. But here's the
template. And to render this, I just need this
hash of JSON data. So I can render this
anywhere as long as I have this hash. Key
thing to remember.
So, if I can't run code in mustache, like
I can run code in erb, how do I
actually like put data in the markup, which is
like the whole point of templates, right?
So you can use these tags. Right, so given
this section of JSON, you have a referent mapping
to node dot js, right. We can render that
data into this template with a, you know, inside
of a block quote, by using this double curly
brace thing. This just says, like, basically, gsub, or
actually not gsub, sub this referant into, inside this
block quote. Pretty simple.
So this is just gonna print like block quote
node.js, you know. That should hopefully be fairly self-evident.
So if you want to sort of do something
where you're printing raw HTML, the double brace will
actually escape it. So that's most the time what
you want. But in this case we're actually like,
you know, we want hyper media in that annotation.
So this, you know, actually has an href. An
a tag, rather.
So we're gonna use the triple brace, which is
another type of tag that says print this HTML
raw. So this will actually print out, like, you
know, real anchor tag. Which is, in this case,
what we want. So here is the sort of
meat of mustache. This is probably the trickiest part
of mustache. There's another type of tag which is
this sort of double brace hash block, right.
So here is the block that I'm talking about.
So you can see this double brace, and then
there's hash edit. This hash is kind of where
the logic by another name comes into play in
mustache. So this is going to, if edit is
like, a boolean type thing, it's going to run,
or, or go into the block. If edit is
true, if edit is like a list of something,
it basically is your for loop is the way
to think about it.
There's one more thing that is like if edit
is like a hash, it kind of just will
run the intersection if the hash is there. Otherwise
it won't. So in this case, we're just saying,
you know, we should show the edit link. That's
what edit true means. This is our logic by
another name. And then we're actually, you know, grabbing
the edit href from the JSON hash as well.
And so this will result in just putting the,
printing the edit link.
Now if edit were false, it wouldn't print that.
And so you might be asking, like, well what
if I wanted to do something else. Like I'm
used to writing these if-else statements. So mustache also
has this other sort of tag, which is a
carrot. SO there's like double, double squiggly, double curly
brace, carot edit, which just means sort of go
into this block if edit is unset or false.
So this is the kind of last tag. So
in this case, if edit were false, we would
just print can't edit. So this is mustache. That's
basically all you can do.
So how does this actually help us? Well, I
don't know if you guys remember, but at the
beginning of this mustache section, I showed you this
template and I said all you need to render
this template is this hash. And I also told
you that there's a Ruby library for this and
a JavaScript library for this.
So I think you might see where this is
going. If we have some way of generating like
a hash, anywhere, then we can render it, we
can ship the template and the hash to any
environment and like render it there.
That's the point I'm trying to make. So how
do we actually generate this hash? That's the sort
of tricky part. Well I'm gonna do some handwaving
here and say, well, this, Perspective's library might help
us a little bit.
So you know here's a traditional Rails view. This
is like an erb template, right. And so what
I'm saying is that if we split this into
a template, which is mustache, and a perspective, which
is something, it's a new type of object, then
we can just have this data transport thing, which
is just the hash, which is generated by the
perspective. And then we can render the template anywhere.
So this is how we render on the client
or the server.
So what is this perspective thing look like? Well,
as you might imagine, it's a bunch of stuff
that specifies what is in the hash. So, here's
the whole perspective. I'm gonna dive into different parts
of it. But you can see it's just basically
a Ruby object with like some macros thrown in.
That's, that's sort of the goal of the library.
It should just be a Ruby object. Plain Ruby
object.
So you can specify inputs, which you specify with
params. So you can say param annotation, this perspective
expects an annotation as input. You can specify outputs.
This perspective outputs reference, which is the annotation's referent
property. It also specifies body as a key. And
that's the annotation's body as HTML. So this is
gonna be raw HTML.
And so properties our output. And so these are
actually just keys in this hash. So we can
just turn this perspective object into a JSON object
and then that can be rendered anywhere. So now
that we know what this perspective object is, it
should be pretty self-explanatory how we get from the
right over to the left and render this template.
Now you might be thinking, isn't this just like
a fancy version of like helpers or something? Like,
helpers with like a namespace? And it's actually different
because, you know, helpers are sort of operating at,
they seem like they kind of live in their
own separate object, like annotations' helper or something. But
actually they're in a global namespace which can be
called from any template at any time. And so
they can kind of like override each other.
They also are direct function indication. So this is
just data. This hash in the middle is just
data. SO like if you reference a property twice,
you're always gonna get the same value, unlike a
helper, which could theoretically return different things if you
call it different times. SO it's kind of like
a safer thing for us as developers.
And so to build like an app with this,
you can imagine the initial request that the client
makes will receive HTML so the, the server will
say, OK let me take this perspective thing, turn
it into JSON, render in mustache template and then
send that back to the user. And, in the
case of like new Twitter, the user would just
see the 140 character Tweet rendered. And in the
case of like a web-crawler for a search engine,
it would see like the full HTML that it
can then index.
And then subsequent requests, just like we would do
with like Ember or Backbone or whatever, we just
request JSON from the server and then we render
the part of the page that needs to change.
So, you the know, the key thing here I
think is that HTML is unstructured data. And so
a lot of like sort of Rails patterns will
tell you just return like the snippet of HTML
from the server that you need and then snap
that in somewhere. And the eventually leads to like
soupy code and coupling to like classes on HTML
elements, which leads to a lot of like weirdo
bugs that are hard to track down.
JSON, on the other hand, is structured data. It's
a lot easier to deal with this, so, you
can either render it or you could do something,
you know, on the client that's a little fancier.
If you want to do, update different parts of
the page, whatever. The point is that it's structured
and it's easy to deal with. And if you're
building out like a thick client, you want to
couple your client experience to structured data, not unstructured
data.
All right, so I'm gonna do the quick getting
started. You know this is, this is sort of
about this library, but I don't want it to
be all about this library. So, you know, it's
just a gem. You can just generate the install
for it. That'll like make your app perspectivified. You
can scaffold stuff. You know, you break your erb
templates into mustache templates and a perspective. And you
just add this one line to your controller, so
this just uses a responder to figure out if
the client wants HTML or wants JSON, and turns
the perspective into whatever you want to. In this
case, it's just, you know, find this annotation by
ID. Use this little macro to create your perspective
and pass it the data it needs, which in
this case is like an annotation. And then we
can render a JSON version or an HTML version.
So what else does this buy us? So clearly
this rendering on the client and server thing is
pretty good. But actually, I didn't like set out,
when I was thinking about this, to like build
some sort of like new thick client like framework
thing that competes with Ember. That wasn't my goal
and I'm still not sure that's my goal. The
benefits I'm about to tell you about were actually
like the initial inspiration for like wanting to build
this library.
So, number one is separation of concerns. So, I
really hate seeing erb templates like this. Here's like
an erb version of the template I just showed
you. So instead of having like a nice edit
property, there's often like some logic in here, if
you look at the bottom there, that's checking, like,
whether or not to show the edit link. And
this is kind of ugly. It's kind of ugly
no matter where it lives. But it's especially ugly
if it lives in a template.
And it is so easy to do this with
erb, cause, you know, erb literally just means embedded
Ruby. So you can just write anything. Like I,
like I've seen saying. SO like here we're saying,
the person can edit the annotation if they created
or they're like a super admin type, type, type
user.
So, mustache and perspectives force you into this separation
of concerns, where you literally can't write any code
in your template. So you have to put it
in the perspective, which is just a Ruby object,
which is where it kind of belongs. And there's
no, there's no love for this in erb land
in Rails. You're kind of, you're kind of off
in this waste land of like, I guess I'll
throw some view logic in here. I don't really
know where it's supposed to go.
And so this, this leads me to like, so
here's the, sorry, here's the perspective version of it,
where actually just generate this edit property and say
whether or not we want to display the link,
based on that logic I showed you before.
So this also gives you like, testing. So I
now DHH was like, you know, shitting on this
in his talk. I still think testing is important.
Maybe not TDD. But like the point is, if
you wanted to test like an erb template and
had some logic in this, in it, you would
have to like, render, the only thing you can
do is render the template. You can't talk to
it. It's not an object. You can't ask it
questions. All you can do is render it and
then do like a string-match on it.
And in fact, I've seen a ton of tests
like this. Web driver tests are basically just doing
like, advanced regexes to like figure out if the
logic is right. And this is really bad. A
perspective is just a freakin' object. Like you just
new it up and pass it the data it
needs and then you can test your logic. SO
here I'm just creating a test double. You know,
test doubles are important in testing. Test double for
a user, test double for an annotation. I'm creating
this new perspective and then I'm asking it if
the edit link is true and verifying that it
should be showing that.
So another thing is caching. So this is like
maybe a little bit difficult to motivate, but like,
this sort of like cache digest thing, Russian doll
caching thing is kind of hard for me to
like wrap my brain around, right. Like, you have
to, you have to write, sometimes, like a special
comment to get the templates to know about each
other. Not as good as just having objects that
know about each other.
So if you want to cache an annotation show
perspective, you just use this cache macro and that
says, use the annotation as the cache key, right.
And so if you're familiar with, like, cache keys
in Rails, if you're using generational caching, this will
just say, the cache key - hopefully you can
see this - is just the type of object,
the id of the object, and when it was
last updated.
So this will like fall out of cache if
anyone updates the annotation or if it's like a
different annotation it'll have a different cache key. So
this sort of, hopefully this is, is somewhat familiar.
If you have another template that you're rendering, like
here, this annotation show perspective, is rendering a nested
user slash avatar perspective, so you can see that
at the bottom. You might want to say, well,
if the user updates their avatar, we also want
this to fall out of cache.
This is sort of the, the Russian doll caching
of it all, right. So if the inside Russian
doll is uncached then it should bust the outside
Russian dolls cache key. So this thing, you can
also assign a cache key to. You can say,
cache based on the user. So if the user
gets updated from the user's avatar perspective, we want
this to fall out of cache. And so, like
I said, we want the whole thing to fall
out of cache if the user gets updated or
the annotation gets updated.
And so what perspective will do for you is
say, OK, we know that there's a nested user's
avatar perspective here, and so to generate the cache
key for this whole thing, we're just going to
concatenate the cache key from the annotation and the
cache key from the user and produce this ugly,
terrible, long cache key, which you don't have to
worry about at any point as the writer of
the code.
So this is all sort of handled transparently for
you. So are we ready to sail off, to
drive off into the sunset in Rails land now
with this new stuff? Well, not quite. The, the
point I'm trying to make here is that, or
one thing I want to get across here is
that this is sort of a nascent library slash
weekend project motivated by, you know, having, making it
annoying to like, do caching, and it's hard to
kind of separate your, your templates out, and also
I'd like to be able to like render the
same thing on the client and server. But there's
still a bunch of stuff to be done, right.
Like there's still some work to be done to
like integrate this with existing like frontend frameworks if
you want to add like a bunch more rich
experiences on the client.
And I want to get to the point, though,
where we can have a good answer to these
node.js libraries. Like this is a big motivation. Like
I'm tired of node.js being, like, well let's just
embrace JavaScript. Like, no let's not embrace JavaScript. Ruby.
Ruby is better. So let's, let's get at them.
But, the key take away is you shouldn't be
sort of creating one version of your app that
lives on the server and one that lives on
the client. The ideal situation is move most of
the stuff to the server but be able to
like still create this thick client situation.
So that's it. That's my talk. You can check
out this library by going to RapGenius slash perspectives
on GitHub, or if you're lazy, there's this bit.ly
link. bit.ly slash RG perspectives. And also, as I
said at the beginning of the talk, we are
hiring. So if you're sort of interested in this
kind of stuff or other stuff Rap Genius related,
get at me. Hit me up on Twitter. Hit
me up via email. Andy at RapGenius dot com.
And I think we have time for some questions.