< Return to Video

RailsConf 2014 - Middleman: the Missing View in the Rails API Stack

  • 0:17 - 0:18
    BRAD GESSLER: All right. So, while these are,
  • 0:19 - 0:20
    these responses are coming in.
  • 0:20 - 0:23
    It looks like quite a few people have
  • 0:23 - 0:27
    either handcrafted html and css applications.
  • 0:27 - 0:31
    I'm not sure if they're single-page application,
  • 0:31 - 0:34
    or just deploy straight-up Rails applications
  • 0:34 - 0:36
    or all the logic on the server-side.
  • 0:36 - 0:40
    So that's good. I, I hope you'll learn
  • 0:40 - 0:42
    something new today about how my company,
  • 0:42 - 0:44
    Poll Everywhere, which the,
  • 0:44 - 0:45
    the product is what you're seeing.
  • 0:45 - 0:48
    We're a software as a service company.
  • 0:48 - 0:52
    We just sell this to presenters based on audience
    size.
  • 0:52 - 0:57
    So, I'm gonna fire up the slides here. All
  • 0:57 - 1:01
    right. My display settings are working, so
    this is
  • 1:01 - 1:05
    good. All right, so Middleman. The missing
    view in
  • 1:05 - 1:07
    the Rails API stack.
  • 1:08 - 1:10
    Let's just jump into it. So, as I said
  • 1:10 - 1:13
    before, I am Brad Gessler, CTO and co-founder
    of
  • 1:13 - 1:16
    Poll Everywhere. We started this company about
    six years
  • 1:16 - 1:19
    ago now. So, we were mobile first, whatever
    that
  • 1:19 - 1:23
    meant, SMS. So we went through all the pains
  • 1:23 - 1:26
    of having to upgrade, if you will, to the
  • 1:26 - 1:32
    second vintage of mobile first, which is mobile,
    basically
  • 1:32 - 1:34
    a mobile website. We had a lot of fun
  • 1:34 - 1:39
    doing that and, and learning things the hard
    way.
  • 1:39 - 1:41
    But first, what is middleman? How many of
    you
  • 1:41 - 1:43
    have heard of Jekyll in this room? That seems
  • 1:43 - 1:46
    to be the, the predominant static website
    generator. And
  • 1:46 - 1:48
    if you go to the Ruby toolbox and you
  • 1:48 - 1:51
    ask Ruby toolbox for, hey, what should I use
  • 1:51 - 1:53
    to generate a static website? You're going
    to get
  • 1:53 - 1:57
    Jekyll. But it's, it's not like Jekyll, in
    the
  • 1:57 - 2:00
    sense that it uses a lot of the more
  • 2:00 - 2:03
    modern, basically RubyGems inside of what
    you see in
  • 2:03 - 2:06
    Rails 4 and Rails 3, which is, the fact
  • 2:06 - 2:09
    that it uses tilt to manage all of the
  • 2:09 - 2:13
    template and, and sass and all that good stuff.
  • 2:13 - 2:15
    So, if you're looking for a tool to build
  • 2:15 - 2:17
    a static site, don't be scared off by the
  • 2:17 - 2:21
    fact that middleman is catching up with Jekyll.
    And
  • 2:21 - 2:24
    you should feel a lot better about that after
  • 2:24 - 2:25
    this talk.
  • 2:25 - 2:30
    So, middleman is extraordinarily well-documented.
    Thomas Reynolds built middleman.
  • 2:30 - 2:34
    He's the, the guy behind this. And he also
  • 2:34 - 2:36
    built an amazing website with a lot of great
  • 2:36 - 2:39
    documentation behind it. So if you go to,
    I
  • 2:39 - 2:42
    believe it's middlemanapp dot com, you can
    get a
  • 2:42 - 2:46
    sense of, of everything that, that this static
    site
  • 2:46 - 2:48
    generator involves.
  • 2:48 - 2:51
    Another really nice thing about this static
    site generator
  • 2:51 - 2:54
    is that it's, it's very modular. So it actually
  • 2:54 - 2:56
    uses rack in its gut, so if you understand
  • 2:56 - 2:58
    rack, you can write a lot of extensions using
  • 2:58 - 3:02
    rack, which is kind of crazy. A static site
  • 3:02 - 3:05
    generator using rack to, to do certain things.
  • 3:05 - 3:09
    And there's also a, an extension framework,
    where you
  • 3:09 - 3:12
    can roll things out, like, a middleman blog,
    if
  • 3:12 - 3:15
    you so please. So, middleman blog in middleman
    is
  • 3:15 - 3:19
    essentially a, a drop and replacement for
    Jekyll. With
  • 3:19 - 3:21
    a few other things. If you're used to writing
  • 3:21 - 3:23
    GitHub-flavored markdown, there's a few tweaks
    that you have
  • 3:23 - 3:25
    to make there to, to get that whole thing
  • 3:25 - 3:27
    working.
  • 3:27 - 3:31
    So, getting started with middleman is actually
    very similar
  • 3:31 - 3:34
    to what it's like getting started in a Rails
  • 3:34 - 3:38
    application. You install the gem, you initialize
    the application,
  • 3:38 - 3:40
    it creates all of this boilerplate code. You
    can
  • 3:40 - 3:43
    see from this directory structure you have
    your configuration
  • 3:43 - 3:47
    file, default index.html.erb. You get a layout
    file and
  • 3:47 - 3:50
    then you have all of your assets. Stylesheets
    and
  • 3:50 - 3:53
    JavaScripts. And then you spin up the server,
    and
  • 3:53 - 3:56
    it boots extremely fast. So, in under a second,
  • 3:56 - 4:00
    you can hit this server and things are just
  • 4:00 - 4:02
    working.
  • 4:02 - 4:05
    So, the thing that I like a lot about
  • 4:05 - 4:08
    middleman is that it's very easy to come into
  • 4:08 - 4:11
    middleman from Rails. I said earlier that
    this uses
  • 4:11 - 4:14
    tilt, so you can bring all the same gems
  • 4:14 - 4:17
    and really the same toolset that you hopefully
    have
  • 4:17 - 4:20
    come to love inside of Rails into middleman
    and
  • 4:20 - 4:25
    start using it without too much of a problem.
  • 4:25 - 4:27
    So the other interesting thing about middleman
    is that
  • 4:27 - 4:31
    it's multi-environment aware. This is, I pulled
    this from
  • 4:31 - 4:35
    a default middleman configuration from the
    boilerplate and simplified
  • 4:35 - 4:37
    it a bit. But here you, you get an
  • 4:37 - 4:39
    idea that in your development environment,
    you can put
  • 4:39 - 4:43
    extensions in there and activate them. Like
    live reload.
  • 4:43 - 4:45
    And you can pull these extensions off of that
  • 4:45 - 4:50
    directory that is on the middleman website.
    And then
  • 4:50 - 4:53
    your production environment in middleman is
    called your build
  • 4:53 - 4:54
    environment.
  • 4:54 - 4:57
    So, in there, you're going to activate certain
    extensions,
  • 4:57 - 5:02
    like minifying css, JavaScript, having an
    asset hash so
  • 5:02 - 5:04
    that you can basically hash your assets and
    do
  • 5:04 - 5:06
    what you do in Rails where you, you give
  • 5:06 - 5:10
    your asset path a, a hash and a path,
  • 5:10 - 5:12
    so that you can cache it.
  • 5:12 - 5:15
    So, once you have this configuration setup
    and your
  • 5:15 - 5:18
    webpages and stuff are, are ready to go, you
  • 5:18 - 5:21
    have to deploy it somehow. And this is another
  • 5:21 - 5:24
    area where middleman really shines is that,
    deployments are
  • 5:24 - 5:28
    incredibly easy. It's two steps easy. There
    is the
  • 5:28 - 5:30
    build command, which takes all of the templates
    and
  • 5:30 - 5:33
    files and whatnot, and it basically compiles
    a bunch
  • 5:34 - 5:38
    of html, css, and JavaScript files into a
    build
  • 5:38 - 5:41
    directory. And then the, the best part about
    it
  • 5:41 - 5:42
    is that getting that build directory up to
    your
  • 5:42 - 5:45
    web server is as simple as rsync. Or, if
  • 5:45 - 5:47
    you want to throwback to the days of using
  • 5:47 - 5:52
    DreamWeaver, you could use FTP to upload it.
    Or
  • 5:52 - 5:54
    SFTP if you're into the whole security thing.
  • 5:54 - 5:58
    I developed a, a gem called shart, appropriately,
    hoping
  • 5:58 - 6:01
    that it would make for an awkward IT conversation
  • 6:01 - 6:04
    in some corporate environment, where you can
    deploy your
  • 6:04 - 6:06
    middleman website up to an S3 bucket, and
    you
  • 6:06 - 6:08
    can actually set the headers that are going
    to
  • 6:08 - 6:14
    emitted from that S3 bucket. Mostly caching
    headers on,
  • 6:14 - 6:15
    on certain assets.
  • 6:15 - 6:17
    So there's a ton of tools you can use,
  • 6:17 - 6:19
    and there's a ton of deployment targets that
    you
  • 6:19 - 6:21
    can choose from for middleman. If you do go
  • 6:21 - 6:23
    the route of deploying to S3, it's an incredibly
  • 6:23 - 6:27
    cheap way to really run your website. You
    just
  • 6:27 - 6:29
    pay a couple cents a month for a, a
  • 6:29 - 6:33
    personal website. And it's also incredibly
    scalable, whenever you're
  • 6:33 - 6:36
    deploying to an S3 endpoint.
  • 6:36 - 6:40
    So. Yippie. You have a static website. You
    know,
  • 6:40 - 6:42
    why should you care about middleman? How is
    this
  • 6:42 - 6:48
    going to, to help you scale your application?
  • 6:48 - 6:50
    Before I dive into that, it's really important
    to
  • 6:50 - 6:54
    kind of understand the place that middleman
    will have
  • 6:54 - 6:58
    in this spectrum of dynacism, is what I call
  • 6:58 - 7:00
    it. And it turns out dynacism is not actually
  • 7:00 - 7:03
    a word, so. I had to ignore the, the
  • 7:03 - 7:04
    spellchecker on this thing.
  • 7:04 - 7:08
    And it looks something like this. So the graph
  • 7:08 - 7:11
    that you saw earlier was actually a static
    web
  • 7:11 - 7:14
    application. And if you access PollIt dot
    com slash
  • 7:14 - 7:17
    brad on your smart phone, that was another
    static
  • 7:17 - 7:18
    web application.
  • 7:18 - 7:23
    So, that's a very dynamic application, though,
    in that
  • 7:23 - 7:25
    the chart has to move and animate and pull
  • 7:25 - 7:28
    this data from the server in real time. In
  • 7:28 - 7:30
    under, you know, a second, it has to get
  • 7:30 - 7:32
    from all of your phones, whether it comes
    from
  • 7:32 - 7:35
    SMS or your smart phone, we have to get
  • 7:35 - 7:36
    it up on that graph in a really short
  • 7:36 - 7:38
    amount of time.
  • 7:38 - 7:42
    So that is arguably a highly dynamic application.
    And
  • 7:42 - 7:45
    we also have to make things really smooth
    and
  • 7:45 - 7:48
    seem very fluid, because that's just what
    you have
  • 7:48 - 7:51
    to do for presentations like this. So as we
  • 7:51 - 7:57
    go down the dynacism spectrum, you have your
    GUI-oriented
  • 7:57 - 7:58
    applications.
  • 7:58 - 8:01
    So, Google spreadsheets - you're probably
    very familiar with
  • 8:01 - 8:03
    that. Who hasn't used it? You're doing a lot
  • 8:03 - 8:05
    of actions, a lot of very short actions, and
  • 8:05 - 8:09
    you don't want to build applications where
    you click
  • 8:09 - 8:10
    a button and then you have to wait for
  • 8:10 - 8:13
    a response to come back to a server. The,
  • 8:13 - 8:16
    basically the functions of the GUI are very
    tightly-coupled
  • 8:16 - 8:18
    with what comes out of that.
  • 8:18 - 8:21
    So we kind of start moving down into document-oriented
  • 8:21 - 8:24
    web apps, like an invoicing application or
    Base Camp
  • 8:24 - 8:26
    where you can, you start to get into Rails
  • 8:26 - 8:29
    territory, where Rails is, it's kind of the
    sweet
  • 8:29 - 8:33
    spot between these highly dynamic applications
    or these highly
  • 8:33 - 8:35
    static applications.
  • 8:35 - 8:38
    So moving down into the blogging platform
    world, you
  • 8:38 - 8:42
    may have something like Subtle or PostHaven,
    that is
  • 8:42 - 8:44
    backed by mySQL, but for the most part it's
  • 8:44 - 8:49
    just storing these documents in a database
    server, just
  • 8:49 - 8:52
    for the convenience of administering many
    users in a
  • 8:52 - 8:54
    multi-tendency environment.
  • 8:54 - 8:56
    And then you go on down to your personal
  • 8:56 - 8:58
    blog, and maybe some of you have a GitHub
  • 8:58 - 9:01
    site. Maybe you're using Jekyll for that.
    Maybe you're
  • 9:01 - 9:05
    using middleman. All the way down to informational
    websites,
  • 9:05 - 9:08
    like a mom and pop shop or Steve's plumping
  • 9:08 - 9:08
    services.
  • 9:08 - 9:11
    If somebody wants to make a killing, go out
  • 9:11 - 9:14
    there and sell these restaurants that have
    flash websites,
  • 9:14 - 9:16
    sell them on a middleman website so that we
  • 9:16 - 9:18
    can get some html out there and have less
  • 9:18 - 9:22
    flash on the internet.
  • 9:22 - 9:25
    So, where does middleman kind of fit into
    all
  • 9:25 - 9:28
    of this? If you're working on a green-filled
    application,
  • 9:28 - 9:31
    it's pretty easy to get started right away.
    Kind
  • 9:31 - 9:33
    of what you hear about doing today is, you
  • 9:33 - 9:37
    build your single page html application over
    here and
  • 9:37 - 9:39
    you build your smaller kind of API off to
  • 9:39 - 9:41
    the side using Sinatra or some type of, of
  • 9:41 - 9:43
    microframework.
  • 9:43 - 9:46
    But, since we've been around as a company
    for,
  • 9:46 - 9:50
    well, since 2008, we actually started out
    using Rails
  • 9:50 - 9:54
    1 point 2, I believe. It was before REST
  • 9:54 - 9:57
    was even a thing in Rails. So we had
  • 9:57 - 10:00
    this green-filled application. We spin this
    thing up. It
  • 10:00 - 10:02
    was great. We were able to move pretty fast
  • 10:02 - 10:05
    inside of this framework. And we just set
    up
  • 10:05 - 10:08
    this application at polleverywhere dot com.
    The real time
  • 10:08 - 10:10
    components we had, I don't know if anybody
    remembers
  • 10:10 - 10:14
    RJS, but that was basically how we would make
  • 10:14 - 10:17
    things appear in, in real time on Rails, was
  • 10:17 - 10:21
    through these kind of, in retrospect, horrendous
    helpers that
  • 10:21 - 10:25
    would emit JavaScript from the server and
    run on
  • 10:25 - 10:26
    your web page.
  • 10:26 - 10:28
    So, we got a lot of mileage out of
  • 10:28 - 10:30
    that. But it wasn't, it wasn't really enough.
    We
  • 10:30 - 10:33
    needed something that was more visually appealing
    than just
  • 10:33 - 10:37
    updating some numbers on a table. So that's
    when
  • 10:37 - 10:40
    we turned to flex, because they happened to
    have
  • 10:40 - 10:44
    this bar chart library that everything updated
    in real
  • 10:44 - 10:45
    time. There was just a lot of stuff that
  • 10:45 - 10:47
    worked out of the box.
  • 10:47 - 10:49
    And it also just happened, out of sheer dumb
  • 10:49 - 10:54
    luck, that flash was installed on 99-some-odd-percent
    of, just
  • 10:54 - 10:57
    all machines out on the internet. But even
    more
  • 10:57 - 11:00
    compelling is that you could embed a flash
    asset
  • 11:00 - 11:05
    into a PowerPoint slide because of good-old
    ActiveX.
  • 11:05 - 11:07
    So we did this kind of weird hack where
  • 11:07 - 11:11
    we would embed these swifts that we would
    generate.
  • 11:11 - 11:13
    These Flex applications, and we would actually
    embed them
  • 11:13 - 11:16
    into a PowerPoint slide and send those out
    up
  • 11:16 - 11:18
    on the server so that people could download
    these
  • 11:18 - 11:22
    polls embedded right into PowerPoint slides.
    So whenever they
  • 11:22 - 11:25
    opened it, nothing really had to be loaded
    up
  • 11:25 - 11:28
    over the conference wifi connections in their
    slide. The
  • 11:28 - 11:30
    swift application would just connect out to
    our Rails
  • 11:30 - 11:34
    app and start pulling data out of it.
  • 11:34 - 11:37
    So we initially had this flex application
    in the
  • 11:37 - 11:42
    same code repository as we did our Rails application.
  • 11:42 - 11:44
    So as we started to build more customers,
    things
  • 11:44 - 11:47
    became more complex, and we were able to afford
  • 11:47 - 11:49
    a contractor who came in and just started
    shredding
  • 11:49 - 11:51
    it on this Flex app and really making a
  • 11:51 - 11:54
    lot of progress. To the point where we started
  • 11:54 - 11:57
    getting annoyed at just how many commit messages
    that
  • 11:57 - 11:59
    he would have in our, I believe it was
  • 11:59 - 12:02
    actually SVN at the time. So we broke that
  • 12:02 - 12:05
    out into a, a separate application. And we
    were
  • 12:05 - 12:08
    able to move a lot quicker, in the fact
  • 12:08 - 12:10
    that we got to separate deployments.
  • 12:10 - 12:12
    So, we had this contractor working over here
    on
  • 12:12 - 12:14
    the Flex app, and he was able to deploy
  • 12:14 - 12:16
    those Swift assets out to production. And
    meanwhile the
  • 12:16 - 12:19
    Rails app team was able to do their work
  • 12:19 - 12:22
    and, kind of, push their updates out through
    a
  • 12:22 - 12:24
    separate release cycle. And, of course, at
    the time,
  • 12:24 - 12:27
    it was a lot easier for Flex to work
  • 12:27 - 12:31
    with XML, so we had a very fashionable XML
  • 12:31 - 12:32
    API.
  • 12:32 - 12:35
    So, time went on, and mobile started to change.
  • 12:35 - 12:39
    It wasn't just about SMS anymore. So we had
  • 12:39 - 12:42
    to think about the smart phone thing that
    was,
  • 12:42 - 12:44
    that was taking off. Really it was the advent
  • 12:44 - 12:46
    of the iPhone.
  • 12:46 - 12:49
    So, having a lot of really good luck in
  • 12:49 - 12:53
    the past with frameworks, including Rails
    and, and some
  • 12:53 - 12:55
    of the visual components that Flex gave us,
    naturally
  • 12:55 - 13:00
    we gravitated towards using jQuery mobile.
    And the other
  • 13:00 - 13:03
    thing, dot mobe extension, was this thing
    that I
  • 13:03 - 13:07
    saw on RailsCasts about this new-fangled way
    to kind
  • 13:07 - 13:09
    of say, hey, this dot mobe format is gonna
  • 13:09 - 13:12
    serve up this, this mobile stuff that's kind
    of
  • 13:12 - 13:13
    like html.
  • 13:13 - 13:17
    So, it turned out that was a really bad
  • 13:17 - 13:21
    idea. The way that jQuery mobile worked got
    us
  • 13:21 - 13:23
    about 80% of the way there, but the other
  • 13:23 - 13:27
    20% was just extraordinarily painful. The
    jQuery mobile framework
  • 13:27 - 13:31
    was extremely opinionated. It wanted data
    in a certain
  • 13:31 - 13:32
    way. It wanted the DOM to be structured a
  • 13:32 - 13:35
    certain way. It felt kind of clunky and we
  • 13:35 - 13:37
    just felt like we were kind of stuck inside
  • 13:37 - 13:40
    of the, the jQuery mobile world.
  • 13:40 - 13:44
    So, our team had to, had to do some
  • 13:44 - 13:46
    soul searching on this front. And what we
    decided,
  • 13:46 - 13:49
    at the time, was, you know, instead of trying
  • 13:49 - 13:52
    to pick a framework, let's actually focus
    at the
  • 13:52 - 13:55
    specific problems that we're trying to solve,
    and let's
  • 13:55 - 13:58
    focus on picking libraries.
  • 13:58 - 14:01
    So, that made our thinking a lot more clear,
  • 14:01 - 14:03
    and we were able to pick exactly what we
  • 14:03 - 14:07
    needed it. Or, yeah, pick exactly what we
    need,
  • 14:07 - 14:09
    and bring it in our application where we needed
  • 14:09 - 14:09
    it.
  • 14:09 - 14:11
    So, at the time, as well, there was still
  • 14:11 - 14:15
    a lot going on in the JavaScript MVC world.
  • 14:15 - 14:17
    You had sproutcore was one, was one of the
  • 14:17 - 14:20
    frameworks that we looked at. And that was
    not
  • 14:20 - 14:23
    really that good-looking in terms of where
    we came
  • 14:23 - 14:25
    from with jQuery mobile.
  • 14:25 - 14:29
    So, we decided to go full speed ahead and
  • 14:29 - 14:32
    use backbone.js, which was, I think, at version
    point
  • 14:32 - 14:33
    eight at the time. And we knew that we
  • 14:33 - 14:36
    would probably be swapping out libraries,
    because the space
  • 14:36 - 14:38
    was still maturing very rapidly, and there
    were a
  • 14:38 - 14:41
    lot of changes. So this approach really let
    us
  • 14:41 - 14:44
    hand-pick the libraries we need and swap them
    out
  • 14:44 - 14:46
    as something else kind of pulled ahead of,
    you
  • 14:46 - 14:48
    know, another library.
  • 14:48 - 14:51
    So we ended up with this single page mobile
  • 14:51 - 14:54
    application that we built entirely inside
    of middleman. So
  • 14:54 - 14:57
    middleman was handling all of the assets that,
    that
  • 14:57 - 15:00
    this application was using. And it uses kind
    of
  • 15:00 - 15:03
    the standard sprockets pipeline that, that
    you have in
  • 15:03 - 15:06
    Rails. So whenever you build this thing, we
    have
  • 15:06 - 15:08
    three files. We upload it to our EngineX server,
  • 15:08 - 15:12
    and we were pretty happy with how this stuff
  • 15:12 - 15:16
    ends up working out on production, especially
    for deployments.
  • 15:16 - 15:18
    So, if you go down this route of building
  • 15:18 - 15:21
    these single-page web applications, one thing
    that you need
  • 15:21 - 15:26
    to be very aware of is CORS. So whenever
  • 15:26 - 15:29
    you went to the pollit dot com single-page
    site
  • 15:29 - 15:32
    on your phone, that was actually making a
    AJAX
  • 15:32 - 15:36
    request to our polleverywhere dot com host
    to an
  • 15:36 - 15:39
    API endpoint on there.
  • 15:39 - 15:40
    So in order to do that without CORS is
  • 15:40 - 15:43
    you get all these cross-domain errors for
    AJAX. But
  • 15:43 - 15:46
    what CORS lets you do is, the pollit dot
  • 15:46 - 15:49
    com host says, hey, polleverywhere dot com,
    I'm from
  • 15:49 - 15:52
    a different domain. I want to make these types
  • 15:52 - 15:55
    of HTTP requests. A GET request, a POST request,
  • 15:55 - 15:58
    and, oh, by the way, I want access to
  • 15:58 - 16:00
    these headers. So our polleverywhere dot com
    service says,
  • 16:00 - 16:03
    OK, you're on our whitelist, polleverywhere
    dot com, so
  • 16:03 - 16:05
    here you go. Here's the data. Great. You want
  • 16:05 - 16:09
    to POST something. I'll accept that request.
    And if
  • 16:09 - 16:13
    another domain tried to access it, it would
    just
  • 16:13 - 16:15
    give them the cross-domain error.
  • 16:15 - 16:17
    So that's how we, we got around that issue.
  • 16:17 - 16:21
    And then another really great thing about
    the way
  • 16:21 - 16:23
    that we deploy this mobile app is, it's really
  • 16:23 - 16:26
    easy to deploy this to a CDN. You actually
  • 16:26 - 16:29
    have these assets that you can push out to
  • 16:29 - 16:33
    other servers. So you can't really do that
    with
  • 16:33 - 16:35
    a Rails app, per se. You can't just take
  • 16:35 - 16:37
    it and stick it over here on this file
  • 16:37 - 16:40
    system on this server without having to boot
    a
  • 16:40 - 16:44
    bunch of stuff and go through all that.
  • 16:44 - 16:47
    So another interesting kind of feature of
    that is
  • 16:47 - 16:50
    that you can deploy to floppy discs. So when's
  • 16:50 - 16:54
    the last time that anybody's seen one of these?
  • 16:54 - 16:56
    And we have these readers here. You pick these
  • 16:56 - 16:59
    up for about fifteen bucks off of Amazon.
    And
  • 16:59 - 17:01
    what I'm actually going to do is a live
  • 17:01 - 17:05
    hardware demo. Possibly the only one at RailsConf.
    And
  • 17:05 - 17:10
    let's plug this in. The really surprising
    thing, to
  • 17:10 - 17:16
    me, was that Mac OS actually recognizes floppy
    drives.
  • 17:16 - 17:22
    So let's plug this guy in here. Op.
  • 17:22 - 17:29
    Devices. I think that's devices. Oh, I got
    to
  • 17:33 - 17:40
    put the disc in. All right. So you can
  • 17:45 - 17:50
    hear the, hear the disc spinning. Oh, let's
    see.
  • 17:50 - 17:54
    There it is. Boy, that's hard to see up
  • 17:54 - 17:58
    here. All right. So here's the application.
    We'll just
  • 17:58 - 18:03
    launch this.
  • 18:03 - 18:10
    [laughter]
  • 18:12 - 18:15
    So hopefully your network connection is faster
    than a,
  • 18:15 - 18:18
    a floppy disc, but if you have a customer
  • 18:18 - 18:20
    living somewhere remote and the only way to
    get
  • 18:20 - 18:23
    something to them is by Pony Express, you
    can
  • 18:23 - 18:26
    just put this floppy disc in a satchel and,
  • 18:26 - 18:29
    and send the pony on its way.
  • 18:29 - 18:32
    The really fun thing is opening network inspector
    on
  • 18:32 - 18:35
    this and seeing how Chrome measures this.
    Is it
  • 18:35 - 18:37
    latency, or is the file really taking that
    long
  • 18:37 - 18:38
    to load?
  • 18:38 - 18:41
    So, here you go. You just saw a web
  • 18:41 - 18:46
    application booted from a floppy disc. I can
    go
  • 18:46 - 18:53
    to my pollev page and submit a vote. So,
  • 18:55 - 18:58
    we joke about coming up with a floppy.js library,
  • 18:58 - 19:01
    because if you can see the inspector down
    there,
  • 19:01 - 19:03
    I don't know if it shows, but the retina
  • 19:03 - 19:05
    assets aren't loaded. Those were too big to
    fit
  • 19:05 - 19:08
    on this floppy disc, so we came up with
  • 19:08 - 19:11
    some fun ideas to span our JavaScript across
    floppy
  • 19:11 - 19:14
    discs. But we had better things to do like
  • 19:14 - 19:17
    fix bugs in production.
  • 19:17 - 19:21
    So, great. You can put this on floppy discs.
  • 19:21 - 19:23
    But I think more importantly there is, you
    can
  • 19:23 - 19:26
    put them inside of phone gap or Cordova apps
  • 19:26 - 19:27
    or we have some customers that they want to
  • 19:27 - 19:31
    bundle our voting application with one of
    their mobile
  • 19:31 - 19:33
    applications. So we can say, here is our html
  • 19:33 - 19:36
    assets, you can put them within your application,
    and
  • 19:36 - 19:38
    then whenever there's three-hundred people
    sitting in a conference
  • 19:38 - 19:44
    room, it won't overload the wifi.
  • 19:44 - 19:47
    So, caching aside, there's, there's another
    component to this.
  • 19:47 - 19:51
    Flex, Flex started getting old. It started
    getting outdated.
  • 19:51 - 19:53
    The writing was on the wall that this stuff
  • 19:53 - 19:56
    was going to die. So, you know, we set
  • 19:56 - 19:57
    out to write a utilization app, it was very
  • 19:57 - 20:00
    natural for us to think, oh, you know what,
  • 20:00 - 20:02
    let's use middleman. We want this thing to
    work
  • 20:02 - 20:05
    on tablets, iPhones, and everywhere, so naturally
    we're going
  • 20:05 - 20:07
    to use - oh, what do we call it
  • 20:07 - 20:09
    today? HTML5. Let's use that.
  • 20:09 - 20:12
    Let's use that HTML5 thing to talk to our
  • 20:12 - 20:15
    JSON API. And that worked great. We got this
  • 20:15 - 20:19
    application out there. It's actually what
    you saw today,
  • 20:19 - 20:22
    it's that HTML5 application. We have all the
    benefits
  • 20:22 - 20:25
    of caching and the CDN and whatnot. But, but
  • 20:25 - 20:28
    something came up. Whenever we were looking
    at these
  • 20:28 - 20:31
    visualizations day in and day out, we just
    said,
  • 20:31 - 20:33
    jeez, these feel really slow, because we were
    using
  • 20:33 - 20:35
    short polling. We were hitting our server
    once every
  • 20:35 - 20:38
    couple of seconds to get the new data from
  • 20:38 - 20:42
    our server to, to update on the graph.
  • 20:42 - 20:43
    So we decided we wanted to do better than
  • 20:43 - 20:46
    that. We rolled out a Stream API. We actually
  • 20:46 - 20:49
    wrote our own server at the time, because
    socket
  • 20:49 - 20:51
    io wasn't quite what we wanted. I, I actually
  • 20:51 - 20:55
    gave a talk in 2012 about this, about streaming
  • 20:55 - 20:58
    resources. So we threw up that streaming API
    server,
  • 20:58 - 21:00
    but there were some problems with it.
  • 21:00 - 21:03
    Back in 2012, when I gave that talk, we
  • 21:03 - 21:06
    were using AMQP on the backend of this thing.
  • 21:06 - 21:08
    And there were just a lot of stability issues
  • 21:08 - 21:10
    with that. It wasn't quite working with the,
    with
  • 21:10 - 21:13
    the grain of the web and how resources work
  • 21:13 - 21:16
    and, and how caching and all that stuff works.
  • 21:16 - 21:19
    So, we had these stability issues that we
    were
  • 21:19 - 21:22
    trying to deal with, and what was really nice
  • 21:22 - 21:25
    about having these client-side applications,
    is we were able
  • 21:25 - 21:27
    to spit up our stream server on its own
  • 21:27 - 21:31
    host, its own completely different host, and
    isolate it.
  • 21:31 - 21:32
    Our team had a lot of learning to do
  • 21:32 - 21:35
    to understand how to, not only build these
    real
  • 21:35 - 21:38
    time web applications, how to operate them.
    How to
  • 21:38 - 21:39
    scale them.
  • 21:39 - 21:41
    So whenever we rolled this thing out, we'd
    have
  • 21:41 - 21:45
    crashes, and our client-side application was
    able to seamlessly,
  • 21:45 - 21:50
    basically fail over to HTTP short polling.
    So over
  • 21:50 - 21:52
    time, our team got much better at just kind
  • 21:52 - 21:59
    of managing all these pieces. And we had client-side
  • 21:59 - 22:02
    SOA going on there. So, you can also, with
  • 22:02 - 22:04
    CORS, if there's several APIs that you have
    out
  • 22:04 - 22:08
    there, you can consume those from your JavaScript
    and
  • 22:08 - 22:11
    kind of munch all that stuff together client
    side
  • 22:11 - 22:14
    and just do whatever it is that you please
  • 22:14 - 22:15
    with that data.
  • 22:15 - 22:19
    So, we had so much success with all these
  • 22:19 - 22:23
    middleman, these single-page middleman applications,
    that we started to
  • 22:23 - 22:25
    build all of our other applications in these.
    So
  • 22:25 - 22:28
    our approach towards native integrations has
    been, basically, let's
  • 22:28 - 22:31
    build a special web browser that has these
    certain
  • 22:31 - 22:34
    hooks into JavaScript so that our web developers
    can,
  • 22:34 - 22:39
    can be more productive and interact more with
    basically
  • 22:39 - 22:41
    the native application.
  • 22:41 - 22:43
    So we can control a lot of different things
  • 22:43 - 22:47
    with these integrations from JavaScript. So
    we start having
  • 22:47 - 22:51
    all these backbone applications pop up. Now,
    if you've
  • 22:51 - 22:54
    dealt with several applications, you may be
    thinking, jeez,
  • 22:54 - 22:57
    you know, you're probably repeating yourself
    with a lot
  • 22:57 - 22:59
    of different things. So how do you get a
  • 22:59 - 23:03
    handle on this stuff in this world of sprockets
  • 23:03 - 23:05
    and middleman?
  • 23:05 - 23:07
    So what we did is we took all of
  • 23:07 - 23:10
    kind of the common components of this, the
    session
  • 23:10 - 23:13
    components, the models and backbone. We pulled
    all these
  • 23:13 - 23:18
    into this one asset gem that then everything
    consumes
  • 23:18 - 23:21
    from there. So to make those gems, it's just
  • 23:21 - 23:25
    like making any other gem. You just say bundler
  • 23:25 - 23:27
    gem and then whatever the name is of your
  • 23:27 - 23:30
    gem. Here we have pollitassets. And the kind
    of
  • 23:30 - 23:33
    different thing about this gem is that, you
    check
  • 23:33 - 23:34
    is sprockets is there. And if it is, then
  • 23:34 - 23:37
    you start appending all these paths toward
    the assets
  • 23:37 - 23:38
    where your asset gem lives.
  • 23:38 - 23:43
    So, for example, in our lib/assets JavaScripts
    gem, we
  • 23:43 - 23:46
    have a user backbone model. We have a poll
  • 23:46 - 23:51
    backbone model. The stylesheets. We actually
    use font icons
  • 23:51 - 23:53
    everywhere, so that we can fit all this stuff
  • 23:53 - 23:56
    on a floppy drive.
  • 23:56 - 23:59
    So, we can have all these assets located here,
  • 23:59 - 24:02
    which whenever all the other applications
    consume that, they
  • 24:02 - 24:04
    can have a consistent look and feel that uses
  • 24:04 - 24:06
    kind of the visual language that we want to
  • 24:06 - 24:09
    use throughout all of our applications and
    all the
  • 24:09 - 24:11
    different platforms.
  • 24:11 - 24:13
    And of course you have your vendor JavaScript
    assets.
  • 24:14 - 24:16
    So if you have four different projects out
    there,
  • 24:16 - 24:19
    you're probably using four different versions
    of jQuery. This
  • 24:19 - 24:21
    lets us use one version of jQuery and one
  • 24:21 - 24:24
    version of backbone.
  • 24:24 - 24:27
    The way that we manage these in our development
  • 24:27 - 24:30
    environment is just through bundler. So you
    can imagine
  • 24:30 - 24:33
    if you have one version of jQuery, well what
  • 24:33 - 24:35
    happens whenever you bump from the one dot
    x
  • 24:35 - 24:37
    to two dot x? You're probably gonna break
    a
  • 24:37 - 24:40
    lot of stuff.
  • 24:40 - 24:42
    But we actually don't have that problem, because
    like
  • 24:42 - 24:45
    with RubyGems, you don't really care if there's
    an
  • 24:45 - 24:47
    upgrade happening. What you care about is
    that you're
  • 24:47 - 24:51
    getting the version that you asked for in
    your
  • 24:51 - 24:56
    gem bundle. So we're able to control that
    by
  • 24:56 - 25:00
    pushing our pollev assets up to a basic Git
  • 25:00 - 25:03
    repository, and we reference that from this
    gemfile. You
  • 25:03 - 25:05
    don't actually see the, the git reference
    in there,
  • 25:05 - 25:07
    but you can see that, in this case, we're
  • 25:07 - 25:09
    saying, hey, I want to use the new feature
  • 25:09 - 25:14
    branch of pollev assets. The assets path thing
    above
  • 25:14 - 25:17
    that is a nice little hack so that if
  • 25:17 - 25:22
    you're making changes to the pollev assets
    project, you
  • 25:22 - 25:24
    can pull those locally so that you don't have
  • 25:24 - 25:26
    to run bundle update every time.
  • 25:26 - 25:28
    And what's cool about middleman is, if you're
    developing
  • 25:28 - 25:32
    these pollev assets locally, whenever you
    reload middleman, it
  • 25:32 - 25:35
    actually picks up the changes from the, the
    assets
  • 25:35 - 25:38
    gem. You don't have to reboot the server or
  • 25:38 - 25:40
    do anything crazy like that.
  • 25:40 - 25:44
    So, the way that we can build new features
  • 25:44 - 25:47
    now, let's say that, let's say the worst case
  • 25:47 - 25:48
    scenario, I have to build a new API to
  • 25:48 - 25:52
    support a new feature. I can branch my Rails
  • 25:52 - 25:54
    app project, and I can say, hey, branch this
  • 25:54 - 25:58
    off. It's called new feature. I'm gonna add
    some
  • 25:58 - 26:00
    kind of new visualization to it that needs
    a
  • 26:00 - 26:02
    new API. So I can build that API out
  • 26:02 - 26:04
    on my server. I can develop that locally.
    And
  • 26:04 - 26:08
    I can point my middleman project at my local
  • 26:08 - 26:09
    server.
  • 26:09 - 26:10
    And I can branch it in here and I
  • 26:10 - 26:13
    can branch pollev assets, and basically have
    three different
  • 26:13 - 26:16
    branches or, sorry, one branch and three different
    repos,
  • 26:16 - 26:19
    all working on the same feature. And then
    whenever
  • 26:19 - 26:23
    I go to deploy, obviously deploy the API server
  • 26:23 - 26:26
    functionality first, and then it would go
    on to
  • 26:26 - 26:29
    roll out these middleman single page websites.
  • 26:29 - 26:34
    So, does it work? I think so. It's, it's
  • 26:34 - 26:37
    worked really well for us. We have to deal
  • 26:37 - 26:41
    with some weird kind of bandwidth constrained
    environments, where
  • 26:41 - 26:46
    you can't trust conference wifi connections.
    And it also,
  • 26:46 - 26:48
    I realized that it worked really well for
    us
  • 26:48 - 26:52
    when, about two months ago, Microsoft wanted
    to launch
  • 26:52 - 26:59
    their PowerPoint 2013 store inside of the
    Microsoft Office
  • 26:59 - 27:00
    Applications. They actually have an app store
    inside of
  • 27:00 - 27:03
    there. And we were able to pull a bunch
  • 27:03 - 27:06
    of assets from our mobile application into
    our sprockets
  • 27:06 - 27:10
    asset gem and reuse all of that stuff, most
  • 27:10 - 27:13
    of it, in the PowerPoint 2013 app. And then
  • 27:13 - 27:16
    we were able to quickly make some customizations
    to
  • 27:16 - 27:18
    that whole user experience to make it fit
    in
  • 27:18 - 27:20
    with Office 2013 a little bit better.
  • 27:20 - 27:23
    And, of course, whenever you're running a
    single-page JavaScript
  • 27:23 - 27:27
    application inside of this little web iframe,
    essentially in
  • 27:27 - 27:31
    Office, it feels very close. It feels very
    native.
  • 27:31 - 27:32
    So that, that worked pretty well for us. But
  • 27:32 - 27:36
    I think, even better than that, than reusing
    functionality
  • 27:36 - 27:39
    is, inevitably, whenever you work on some
    of these
  • 27:39 - 27:41
    projects, you make some kind of improvement.
    Something just
  • 27:41 - 27:44
    feels better about maybe handling a login
    or some
  • 27:44 - 27:46
    kind of status code or something.
  • 27:46 - 27:49
    So these improvements that we make in these
    individual
  • 27:49 - 27:51
    projects, we're able to pull them back into
    the
  • 27:51 - 27:54
    sprockets assets gem and then push them back
    out
  • 27:54 - 27:55
    to all of our other projects. So all these
  • 27:55 - 27:58
    other projects you see up here benefit from
    the
  • 27:58 - 28:03
    PowerPoint 2013 app, and that just keep, kind
    of
  • 28:03 - 28:04
    reinforces itself. Reinforcing itself.
  • 28:04 - 28:08
    So, in a sense, the sprockets assets gem turns
  • 28:08 - 28:11
    into this little, perfect little framework
    for your organization
  • 28:11 - 28:14
    that's extracted in the right way, where it's
    being
  • 28:14 - 28:17
    extracted from stuff that's actually being
    used and being
  • 28:17 - 28:22
    proven as successful by customers.
  • 28:22 - 28:26
    So, that's a pretty good overview of one of
  • 28:26 - 28:30
    the more complex middleman deployments I would
    say is
  • 28:30 - 28:33
    out there, and just managing kind of multiple
    projects.
  • 28:33 - 28:36
    One of the downsides and also plus sides of
  • 28:36 - 28:41
    middleman is that there's no out-of-the-box
    JavaScript MVC app
  • 28:41 - 28:45
    solution in there. So in the case of backbone,
  • 28:45 - 28:47
    it's up to you to organize all the assets
  • 28:47 - 28:50
    in some way that, that makes sense. And different
  • 28:50 - 28:53
    JavaScript frameworks have, some are more
    organized than others.
  • 28:53 - 28:56
    So that's both a blessing and a curse.
  • 28:56 - 28:59
    It worked out for us because there really
    wasn't
  • 28:59 - 29:00
    a framework. We kind of came up with our
  • 29:00 - 29:01
    own and we didn't have to deal with, with
  • 29:01 - 29:05
    somebody else's bad framework.
  • 29:05 - 29:09
    So, that was the overview of the highly dynamic
  • 29:09 - 29:11
    website, which has all these static
  • 29:11 - 29:14
    applications stashed everywhere.
  • 29:14 - 29:18
    What about static websites? The other side
    of the
  • 29:18 - 29:21
    kind of token where Rails fills the middle
    ground?
  • 29:21 - 29:26
    So, we're developing a lot of content for,
    for
  • 29:26 - 29:30
    our website. There's an explosion of use cases
    and
  • 29:30 - 29:33
    all sorts of stuff that we have to implement.
  • 29:33 - 29:34
    So one thing that we'll probably do on this
  • 29:34 - 29:39
    front is extract out a content directory from
    Rails
  • 29:39 - 29:42
    app. How many of you have a, in your
  • 29:42 - 29:44
    Rails app, it starts out. You have kind of
  • 29:44 - 29:46
    the home page, and then it turns into this
  • 29:46 - 29:49
    directory called content, and then you have
    all these
  • 29:49 - 29:51
    content pages. Maybe you end up with twenty
    or
  • 29:51 - 29:53
    thirty of them one day and, before you notice
  • 29:53 - 29:56
    this big junk drawer of content, and you have
  • 29:56 - 29:57
    to look in your routes file and kind of
  • 29:57 - 29:58
    make sense of all this stuff.
  • 29:58 - 30:03
    So, in middleman, you don't, the directory
    structure is
  • 30:03 - 30:05
    the routing structure. So that stuff checks
    out a
  • 30:05 - 30:08
    lot nicer. And it's just much easier to handle
  • 30:08 - 30:11
    this content. And there's also much better
    support in
  • 30:11 - 30:14
    there for different things like image compression.
    You can
  • 30:14 - 30:18
    png crush everything. So if you have designers
    building
  • 30:18 - 30:21
    image assets and they don't understand the
    technicalities of
  • 30:21 - 30:25
    making pngs much smaller, middleman can take
    care of
  • 30:25 - 30:26
    that in its asset pipeline.
  • 30:26 - 30:31
    And, of course, on a static website like that,
  • 30:31 - 30:34
    you still have some dynamic components. You
    can't just
  • 30:34 - 30:37
    throw a static website out there and just
    tell
  • 30:37 - 30:41
    everybody, like, oh, no, forget about login
    state. There's
  • 30:41 - 30:43
    some common things that people want to see,
    so
  • 30:43 - 30:45
    you can take care of that with JavaScript,
    and
  • 30:45 - 30:47
    you can run all that stuff client-side.
  • 30:47 - 30:49
    So you can have some really lightweight JS
    that
  • 30:49 - 30:51
    checks with the server. Maybe it checks for
    the
  • 30:51 - 30:54
    presence of a cookie to see if, if the
  • 30:54 - 30:56
    user's logged in or not. And then, of course,
  • 30:56 - 30:58
    if you have a contact us form or anything
  • 30:58 - 31:02
    like that, you would test these integration
    points with
  • 31:02 - 31:04
    Rails so that whenever somebody types in stuff
    into
  • 31:04 - 31:06
    a form and submits it, it hits your Rails
  • 31:06 - 31:08
    app and hopefully it doesn't blow up.
  • 31:08 - 31:11
    And, of course, you have other JavaScript
    applications, like
  • 31:11 - 31:13
    Google Analytics, Optimize the Stripe.
  • 31:14 - 31:15
    All these little JavaScript-y
  • 31:15 - 31:19
    tools that you can throw in there. And, you
  • 31:19 - 31:21
    know, it makes it a little more dynamic.
  • 31:21 - 31:23
    So the nice thing about a static website is
  • 31:23 - 31:27
    that you can't get taken down that easily,
    especially
  • 31:27 - 31:28
    if you have this stuff up in an S3
  • 31:28 - 31:31
    bucket or stashed in CDNs. I was at a
  • 31:31 - 31:33
    middleman meet up about a year ago, and the
  • 31:33 - 31:36
    folks from nest dot com were there. And they
  • 31:36 - 31:38
    said they were using some CNS or some, some
  • 31:38 - 31:41
    dynamic backend, and they kept being mentioned
    in the
  • 31:41 - 31:44
    press. And their website kept getting really
    slow.
  • 31:44 - 31:46
    So they looked at a few things and I
  • 31:46 - 31:48
    think one option involved just throwing hardware
    at the
  • 31:48 - 31:51
    problem. And they decided that wasn't sane.
    Let's just
  • 31:51 - 31:54
    build a static website with middleman and
    push this
  • 31:54 - 31:56
    stuff out there on a really simple server.
    And
  • 31:56 - 31:59
    they no longer had any of these problems where
  • 31:59 - 32:00
    their site would get taken down from a, an
  • 32:00 - 32:04
    influx of, of traffic.
  • 32:04 - 32:07
    So there's a lot of things to think about
  • 32:07 - 32:10
    whenever you're building these middleman applications.
  • 32:10 - 32:10
    I could probably
  • 32:10 - 32:12
    give another two or three talks just on these
  • 32:12 - 32:16
    items alone. If you want, ask me questions
    about
  • 32:16 - 32:19
    this stuff later. But I don't have time to
  • 32:19 - 32:20
    cover that now.
  • 32:20 - 32:23
    And, of course, I encourage you to get out
  • 32:23 - 32:26
    there. Build your next website with middleman,
    even if
  • 32:26 - 32:28
    it's a personal website or a blog or something.
  • 32:28 - 32:32
    Try it out. If you're working on single web
  • 32:32 - 32:35
    page applications, you could take your handcrafted
    stuff and
  • 32:35 - 32:37
    throw it into middleman and start using that.
    Start
  • 32:37 - 32:39
    using the asset pipeline.
  • 32:39 - 32:41
    A lot of these ideas that I've talked about
  • 32:41 - 32:44
    today, and some of the things I didn't talk
  • 32:44 - 32:46
    about, our company polleverything is
  • 32:46 - 32:47
    actually abstracting out this
  • 32:47 - 32:51
    framework and we're going to be releasing
    these bits
  • 32:51 - 32:54
    into gitfannypack, or fannypack is gonna be
    the name
  • 32:54 - 32:57
    of this, this kind of framework that uses
    middleman
  • 32:57 - 32:59
    and deals with stuff like testing, binding
    to different
  • 32:59 - 33:02
    environments and all that stuff.
  • 33:02 - 33:04
    And, of course, if you want to work on
  • 33:04 - 33:06
    this stuff every day and get paid for it,
  • 33:06 - 33:12
    you can join at team at polleverywhere. So,
    that's
  • 33:12 - 33:16
    my talk. I'm Brad Gessler. I'll be posting
    slides,
  • 33:16 - 33:19
    links, and, and code, up on Twitter whenever
    I'm
  • 33:19 - 33:22
    not working on these slides. Thanks.
Title:
RailsConf 2014 - Middleman: the Missing View in the Rails API Stack
Description:

more » « less
Duration:
33:48

English subtitles

Revisions