00:00:15.240
all right so I'm super happy to be here
00:00:16.400
at Ruby comp to talk about Roa so Roda
00:00:19.119
is a web toolkit that I launched in
00:00:21.600
2014 I had the pleasure of presenting
00:00:23.840
the newly launched Roa at Ruby conf 14
00:00:26.279
2014 and it's great to be back at Ruby
00:00:28.519
conf 10 years later to discuss roa's
00:00:30.960
progress so in this presentation I'll be
00:00:33.360
going over the advantages of using Roa
00:00:35.920
uh discussing the progress made in the
00:00:37.480
last 10 years since launch and looking
00:00:40.079
at how some open-source software uses
00:00:42.039
Roa my name is Jeremy Evans I maintain
00:00:44.800
Roa and many other rubby gems I'm also a
00:00:47.360
ruby committer who focuses on fixing
00:00:49.120
bugs in Ruby additionally I'm the author
00:00:51.559
of polished Ruby programming a book
00:00:53.399
aimed at intermediate Ruby programmers
00:00:56.320
so before discussing the first 10 years
00:00:58.320
of Roa I'm going to dive into a simple
00:01:00.879
Roa example in case you were not
00:01:02.840
familiar with it and while a little bit
00:01:05.080
more complex than hello world this
00:01:07.000
example shows R's key advantage over
00:01:09.119
other Ruby web Frameworks which is the
00:01:11.119
ability to handle requests during
00:01:12.960
routing instead of separating the
00:01:14.880
routing process from the request
00:01:17.000
handling process so with Roa all
00:01:19.960
requests to the application are yielded
00:01:22.320
to the route block and the route block
00:01:24.479
is responsible for handling all requests
00:01:27.320
by convention Ro uses r as the rout rout
00:01:30.079
block variable at any point in the route
00:01:32.680
block you can do processing related to
00:01:34.600
the request for example if you want to
00:01:36.680
check access by IP you could have that
00:01:38.960
check at the top of the route block and
00:01:41.399
this would be the equivalent of an
00:01:42.880
application Level before hook in other
00:01:45.280
Frameworks now assuming we pass the
00:01:47.320
access check we get to the first routing
00:01:49.280
method so the r.on method is used to
00:01:51.680
handle branches in the routing treat in
00:01:55.119
this example the r.on method is passed
00:01:57.200
two arguments called matchers and the
00:01:59.960
first is the string employee which will
00:02:02.399
match if the next segment in the request
00:02:05.039
path is
00:02:06.360
employee and the second is a class
00:02:08.280
integer which will match if the next
00:02:10.080
segment in the ring path is an integer
00:02:12.879
so if you look at the combination of
00:02:14.680
these two matchers they will match
00:02:16.800
request path such as SL employee sl7 and
00:02:20.080
since the entire request path has been
00:02:21.920
consumed by the matchers the remaining
00:02:24.160
path is empty the matchers will also
00:02:27.000
match requests such as/ employee sl7
00:02:30.000
slash name and the remaining path after
00:02:32.760
this would be slash name which is what
00:02:35.160
routing methods inside the block would
00:02:37.480
operate on it would not match a path
00:02:40.080
such as SL vendor sl9 since the first
00:02:42.760
segment is not employee and it would
00:02:45.440
also not match a path such as SL
00:02:47.840
employee slame because name is not an
00:02:51.120
integer now if the request does not
00:02:53.280
match the r.on call r.on will return nil
00:02:56.760
without yielding to the block and in
00:02:59.319
this example it would reach the end of
00:03:00.879
the route block resulting in a 404
00:03:03.519
response because the request was never
00:03:06.680
handled the request does match the art
00:03:09.040
on call it will yield to the provided
00:03:11.319
block and because the integer class
00:03:13.840
matcher was used the block would be
00:03:16.000
yielded that segment of the request path
00:03:18.799
converted to an integer so for a get
00:03:21.319
request for SL employee sl7 name the
00:03:24.879
employee ID block variable would be the
00:03:27.080
integer 7 now inside the block the first
00:03:29.959
line is this code which shows the
00:03:32.080
primary advantage of Rota which is at
00:03:34.480
any point during routing you can do
00:03:36.920
processing related to the request now in
00:03:39.680
this case we're using that employee ID
00:03:41.319
block variable to look up the employee
00:03:43.400
by ID and then setting the employee
00:03:45.439
variable all routes under this block can
00:03:48.159
then access the employee now you can get
00:03:50.840
similar behavior in other Frameworks
00:03:52.599
using before hooks but this provides a
00:03:54.840
simpler approach that avoids indirection
00:03:57.760
if you've ever had a debug issues in
00:03:59.200
your application
00:04:00.280
involving the use of hooks I think you
00:04:02.519
can appreciate this approach now what if
00:04:05.239
there is no matching employee for the ID
00:04:08.120
well in that case you can use the next
00:04:09.720
keyword to return nil From the Block
00:04:12.159
which Roto will treat as a 404 response
00:04:15.640
now this ensures there is a valid
00:04:17.199
employee for the rest of the block so
00:04:20.479
the next writing method is r. is with a
00:04:23.919
string name matcher now r. is is similar
00:04:27.639
to r.on except that it requires s that
00:04:30.120
the request path has been fully consumed
00:04:33.520
after all the mattress have been applied
00:04:35.880
so for our request since the employe and
00:04:38.120
segment seven segments have already been
00:04:40.360
consumed the remaining path is slash
00:04:42.840
name and the string name matcher will
00:04:45.400
match that segment and since the entire
00:04:48.280
request path has now been consumed by
00:04:50.680
the matchers given to the routing
00:04:52.000
methods the r. is Method will match and
00:04:54.560
it will yield to the block now inside
00:04:57.120
the r do is block the first method call
00:04:59.280
is r .g get which will match because the
00:05:02.280
request being handled uses the get
00:05:04.800
request method now the R.G block returns
00:05:08.320
a string hello followed by the employees
00:05:10.960
name and as the block returns a string
00:05:13.840
this string will be used as the response
00:05:16.240
body so let's see how a post request to
00:05:19.280
the same path will be handled so the
00:05:22.120
path of the request will still be fully
00:05:24.280
consumed by the matchers given to the
00:05:27.199
r.on and r.is methods
00:05:30.639
however the R.G method call will not
00:05:32.720
match as this is a post request and not
00:05:35.400
a get request so R.G will return nil
00:05:38.479
without yielding to the block the next
00:05:41.319
method in the block is r. poost which
00:05:43.840
will match because this request is a
00:05:45.880
post request so r. poost will yield to
00:05:48.479
the block now in this case we will use
00:05:50.560
the name parameter to update the
00:05:52.440
employees name and then we will redirect
00:05:54.880
the request and since no arguments are
00:05:57.440
given this will redirect to the same
00:05:59.800
path but using a get request and not a
00:06:02.479
post request so hopefully this example
00:06:05.560
was give able to give you a basic idea
00:06:08.240
for how roa's routing tree works the
00:06:10.599
most important part to remember is that
00:06:12.520
Roa gives you the power to do processing
00:06:14.720
related to the request at any point
00:06:17.440
during the routing process this reduces
00:06:20.000
duplication and indirection and results
00:06:22.759
in applications that are simpler and
00:06:24.840
easier to understand Simplicity is one
00:06:27.919
of R's four goals after 10 years
00:06:30.440
developing Roa I still think that the
00:06:32.400
primary benefit of Roa is it allows the
00:06:34.960
same application to be built more simply
00:06:37.919
than in other Frameworks another of
00:06:40.400
roa's goals is performance and unlike
00:06:42.759
the Simplicity goal where the benefits
00:06:44.560
are subjective you can see objective
00:06:46.720
differences between the performance of
00:06:48.400
Roa and other web Frameworks we're going
00:06:50.639
to look at two benchmarks the first is
00:06:53.400
r10k which is a synthetic Benchmark that
00:06:56.360
measures per request overhead and
00:06:58.759
scalability for large numbers of routes
00:07:01.360
now r10k benchmarks applications with 10
00:07:04.759
100 1,000 and 10,000 routes and to avoid
00:07:08.599
web server overhead it benchmarks using
00:07:10.759
the rack API directly so here are the
00:07:13.800
request per second results for Roa rails
00:07:16.800
Sinatra anami and camping and it shows
00:07:19.759
ra Roa is much faster than other
00:07:21.599
Frameworks now unfortunately the scale
00:07:23.840
of the graph makes it difficult to see
00:07:26.400
how the other Frameworks compare so
00:07:28.440
here's the same graph but using a
00:07:29.840
logarithmic scale and this still shows
00:07:31.840
Roa is much faster but it also shows
00:07:34.440
that Roa rails and Hanami all scale well
00:07:37.560
for large numbers of routes it shows
00:07:39.840
that snra and camping do not scale well
00:07:41.800
for large numbers of routes and that's
00:07:43.800
because both use a linear search of
00:07:45.960
routes during request
00:07:47.919
handling now rnk also provides memory
00:07:50.720
benchmarks and these show that RTO uses
00:07:53.120
less memory than other Frameworks rails
00:07:55.440
uses about three to four times more
00:07:57.800
memory than Roa in this bench mark
00:08:00.479
and while the r10k benchmarks are useful
00:08:02.759
they don't tell you much about the real
00:08:04.240
world performance differences so for
00:08:06.440
that the tech empow web framework
00:08:08.199
benchmarks do a better job teeken power
00:08:10.599
has been benchmarking web Frameworks in
00:08:12.360
many languages for over 10 years and Roa
00:08:15.159
has led the Ruby web framework
00:08:16.360
benchmarks ever since it was added in
00:08:19.560
2017 so here are the composite score
00:08:22.000
results for the most recent round of
00:08:24.159
tech and power benchmarks for Ruby web
00:08:26.159
Frameworks and Roa leads in every
00:08:28.560
category the way score for Roa it's
00:08:30.720
about twice what the rated score is for
00:08:32.599
rails and that lines up with results
00:08:35.120
I've seen from applications converted
00:08:37.279
from rails to Roa where the converted
00:08:39.839
Roa application is about twice as fast
00:08:42.760
as the benchmarks show Roa achieves its
00:08:44.760
performance goals it's the fastest Ruby
00:08:46.760
web framework scales well and it uses
00:08:49.320
the least memory it's the fastest
00:08:51.519
framework largely because it has the
00:08:53.480
lowest per request overhead road is
00:08:56.240
designed to minimize the amount of work
00:08:58.480
between when it receives IES the rack
00:09:00.160
request environment and when it starts
00:09:02.440
processing the routing tree R to scales
00:09:04.959
well because it uses a routing tree as
00:09:06.839
soon as a branch of the routing tree is
00:09:08.560
taken other branches at the same level
00:09:10.880
are no longer considered and finally Ro
00:09:13.519
to uses the least amount of memory
00:09:15.680
because it is designed around a small
00:09:17.440
core and that small core handles basic
00:09:20.399
routing and request handling all other
00:09:23.079
features are added via plugins rotus
00:09:26.040
core is itself a plugin and plugins can
00:09:28.519
override any part of Corea and any
00:09:31.079
previously loaded plugins as an example
00:09:33.959
of its minimalism rota's core does not
00:09:36.360
include template rendering template
00:09:37.920
rendering is supported via a plugin and
00:09:40.680
it's common to use this plugin if you're
00:09:42.399
writing applications that are targeting
00:09:44.519
browsers however if you're designing an
00:09:46.720
application that just serves API
00:09:49.079
responses via Json you wouldn't need it
00:09:51.959
in that case you'd probably want to use
00:09:53.560
the Json plugin which allows route
00:09:55.519
blocks to return arrays or hashes and
00:09:58.079
have those converted automatically Jason
00:10:00.000
and used as response bodies the reason I
00:10:03.040
refer to Roda as a toolkit is you can
00:10:05.519
think of each plugin as a tool and
00:10:07.560
different applications require different
00:10:09.279
tools and with Roa you only pay the
00:10:12.279
overhead cost for the tools that you
00:10:14.640
choose to use R ships with over 120
00:10:17.839
plugins to handle the needs of a wide
00:10:19.959
variety of web applications and there
00:10:22.079
are numerous external rooto plugins to
00:10:24.680
handle additional needs so this approach
00:10:27.240
of having a small core and shipping all
00:10:29.320
all optional features as plugins is how
00:10:31.640
Roa achieves its goal of
00:10:33.800
extensibility roa's final goal is
00:10:36.000
reliability and Rota achieves this goal
00:10:38.519
by combining two development approaches
00:10:40.839
the first is immutability so Rota
00:10:43.480
applications are designed to be frozen
00:10:45.680
in production and when testing and this
00:10:47.839
reduces the possibility for thread
00:10:49.480
safety issues as well as memory leaks
00:10:51.839
due to unexpected object retention now
00:10:54.440
immutability is not just for reliability
00:10:57.079
in Roa either in Roa immutability also
00:11:00.720
improves performance when you freeze
00:11:03.160
your Roa application Roa knows there'll
00:11:05.480
be no further configuration changes to
00:11:07.720
it Roa then determines whether the
00:11:10.000
methods that it offers that are designed
00:11:11.720
for extensibility have not been
00:11:13.720
overridden and in that case it overrides
00:11:16.320
the default extensible methods with
00:11:18.760
optimized methods and that gives you the
00:11:20.920
best of both worlds extensibility when
00:11:23.320
you need it and maximum performance when
00:11:25.920
you don't the second development
00:11:28.200
approach related to reliability I refer
00:11:29.920
to as Pollution Control more explicitly
00:11:32.839
namespace pollution control or it limits
00:11:35.800
the constant the pollution of your
00:11:38.079
constant method and instance variable
00:11:40.240
name spaces in your
00:11:42.000
application all of the internal
00:11:43.880
constants in Roa are prefixed with Roa
00:11:46.680
So to avoid conflicting with userdefined
00:11:49.200
constants Roa limits instance variable
00:11:51.720
pollution by prefixing all internal
00:11:54.320
instance variables in route block scope
00:11:56.560
with an underscore if you've ever
00:11:58.639
developed a notra application and Tred
00:12:00.519
to use request or response instance
00:12:02.480
variables you will appreciate this Ro
00:12:05.519
limits method pollution by only defining
00:12:07.839
six methods in rot to block scope beyond
00:12:10.560
the methods that are defined in object
00:12:12.240
and some private methods that begin with
00:12:13.600
an underscore and this makes it less
00:12:15.440
likely that a user user defined method
00:12:17.760
will conflict with a Roa method so now
00:12:20.839
that I've given you a brief Taste of Roa
00:12:22.639
and discussed how Roa has achieved its
00:12:24.480
goals I can start discussing the first
00:12:26.720
10 years of Roa now roa's first Rel
00:12:29.160
release was on July 30th 2014 and its
00:12:32.240
most recent release the 125th release
00:12:35.360
was 3 days ago now I don't like waiting
00:12:38.000
long to use new features so Roto Falls a
00:12:40.880
simple to understand release schedule
00:12:43.079
there's a new rotto release every month
00:12:45.279
around the middle of the month ever
00:12:46.920
since
00:12:48.560
2014 I also don't like it when changes
00:12:50.760
to a library break my applications so
00:12:53.279
roota places a high priority on
00:12:55.160
backwards compatibility I think the
00:12:57.600
compatibility is so good that the
00:12:59.440
majority of applications that worked
00:13:01.079
with the first release Roa 0.9 would
00:13:04.000
still work if you upgraded them to the
00:13:05.600
latest release R to 3.86 with one main
00:13:09.160
exception if we go back to our first
00:13:11.199
example we see that it uses the integer
00:13:13.440
class matcher however Roa did not
00:13:15.560
support using the integer class as a
00:13:17.279
matcher until Roto
00:13:18.839
2.27 before Roto 2.27 this type of
00:13:22.000
matcher would generally be written using
00:13:23.760
what is referred to as a placeholder
00:13:25.240
string with placeholders in the string
00:13:27.320
being prefixed by colon now this style
00:13:30.160
resulted in two issues first it resulted
00:13:33.000
in redundancy most developers would name
00:13:35.440
the placeholders similar to The Block
00:13:37.440
variables that's not technically a
00:13:39.360
problem but it is a tad annoying the
00:13:41.959
actual problem was a performance problem
00:13:44.120
which is that you needed to scan all
00:13:45.800
strings that are used as matchers to see
00:13:47.959
if the strings contain placeholders and
00:13:50.160
then treat the string differently if it
00:13:51.800
had a placeholder strings are the most
00:13:54.079
common type of matcher so this check
00:13:56.079
resulted in a measurable slowdown even
00:13:58.639
if you not using placeholders so Rota 3
00:14:01.720
removed support for placeholders in
00:14:04.000
string matchers by default and in order
00:14:06.000
to support backwards compatibility Rota
00:14:08.360
3 shipped with a placeholder string
00:14:09.920
mattress plugin now I analyzed a couple
00:14:12.360
of my open source applications checking
00:14:14.480
out the commit where the application was
00:14:16.600
converted from Sinatra or rails to Roa
00:14:19.639
0.9 and trying it with the current
00:14:21.959
version of Roa and in both cases adding
00:14:24.839
the placeholder string matchers plugin
00:14:26.839
was the only rotor related change NE
00:14:29.120
necessary to get the specs passing with
00:14:31.360
the current version of Roa I mentioned
00:14:34.440
that one of the reasons for breaking
00:14:35.800
backwards compatibility was to improve
00:14:38.440
performance so how much did this change
00:14:40.600
and other changes improve roa's
00:14:42.639
performance over the last 10 years to
00:14:45.880
determine that we're going to look at
00:14:46.880
some more r10k benchmarks to see how
00:14:49.120
roa's performance has improved over time
00:14:52.279
additionally as Roa is a fork of another
00:14:54.079
web framework named Cuba we're also
00:14:56.079
going to compare Roa to Cuba so let's
00:14:58.279
start with Roda as initial release
00:14:59.839
compared against the current Cuba
00:15:01.320
release at the time as you can see
00:15:03.279
performance is basically the same for
00:15:05.480
the initial release I was focused on
00:15:07.399
differences in route block handling
00:15:09.199
handling block responses and getting the
00:15:11.399
plugin system working I wasn't focused
00:15:13.519
on performance since CUO was already
00:15:16.000
much faster than other Ruby web
00:15:17.519
Frameworks at the time less than a month
00:15:20.120
after the initial release I released Roa
00:15:22.440
1.0 and this had a massive boost in
00:15:25.079
performance over the initial release
00:15:26.639
with a number of additional
00:15:27.959
optimizations at the time most of the
00:15:30.480
matchers in Roa were based on regular
00:15:33.000
expression scanning and the most
00:15:34.759
important optimization was the caching
00:15:36.600
of regular Expressions instead of
00:15:38.600
generating a new regular expression for
00:15:40.800
every matcher about 6 months after
00:15:43.360
releasing Roa 1.0 I released Ro to 2.0
00:15:46.480
which improved performance over 1.0 by
00:15:48.880
about 20% now this performance
00:15:51.240
Improvement was due to reducing
00:15:52.759
allocations during matching so that each
00:15:55.279
match attempt did not modify the request
00:15:58.000
environment
00:15:59.759
about 2 and a half years after that I
00:16:01.440
released order a 3.0 which improved
00:16:03.360
performance over 2.0 by about
00:16:06.279
40% so this performance Improvement was
00:16:09.199
mostly due to avoiding regular
00:16:11.079
Expressions during matching and the
00:16:12.839
remover of placeholders during string
00:16:14.519
matching instead of regular Expressions
00:16:17.279
string Methods such as start with an
00:16:19.360
index are used and this idea was taken
00:16:21.680
from syyro a routing Library by the same
00:16:24.079
author as Cuba by January 2021 with the
00:16:27.720
release of Rota 3.4 40 performance had
00:16:29.920
increased another
00:16:31.160
15% this performance increase was due to
00:16:33.680
a couple of optimizations during this
00:16:35.720
time period is when I added the
00:16:37.240
optimization during application freezing
00:16:40.120
additionally the performance of string
00:16:41.560
and segment matchers was improved about
00:16:43.560
15% and terminal matching by about
00:16:46.880
400% between R to 3.40 and 3.60
00:16:50.560
performance increased another 30% and
00:16:53.199
this was due to additional optimizations
00:16:54.839
on the most common matchers R's current
00:16:57.079
performance is about the same as Roa 3
00:16:59.120
60 so between roa's initial release and
00:17:01.959
the current release performance in this
00:17:03.839
Benchmark improved by a factor of 12 I
00:17:07.760
think that's pretty amazing considering
00:17:09.160
that even at roa's initial release it
00:17:11.199
was one of the fastest Frameworks
00:17:13.600
however this is not the limits of roa's
00:17:15.280
performance using the optimized string
00:17:17.439
matchers optimized segment matchers and
00:17:19.480
plane hash response
00:17:21.000
headers uh plugins performance can be
00:17:23.799
increased another
00:17:25.439
35% and this does require some small
00:17:28.199
sacrifices usability though now r10k is
00:17:32.320
a routing and per request overhead
00:17:34.520
Benchmark and Roa has improved greatly
00:17:36.320
over the years at that however that's
00:17:38.720
not the only way that Roa has improved
00:17:40.559
performance many of the plugins that
00:17:42.600
ship with Roa have been optimized as
00:17:45.000
well for example the render plugin has
00:17:47.240
shipped with every release of Roa but it
00:17:49.440
and related plugins were extensively
00:17:51.240
optimized a few years ago for simple
00:17:53.520
templates the render plugin is about
00:17:55.039
four times faster than it was originally
00:17:58.440
speaking of plugins rot to 0.9 shipped
00:18:01.159
with 15 plugins and R to 3.86 ships with
00:18:04.240
over 120 plugins more than eight times
00:18:06.840
as many as the initial release so I'm
00:18:09.720
going to take you on a quick tour of the
00:18:11.679
last 10 years of Roto plugins in the
00:18:14.720
initial release in addition to rendering
00:18:16.679
Ro ship with plugins for handling
00:18:18.880
exceptions customizing default headers
00:18:21.320
and 404 responses handling flas messages
00:18:25.360
streaming responses and operating as
00:18:27.559
rack middleware however one of the most
00:18:29.919
important plugins was the ability to use
00:18:32.679
separate route blocks if you remember
00:18:34.960
back to our original example I mentioned
00:18:37.280
that all requests are yielded to the
00:18:39.240
route block and the route block
00:18:40.600
determines the response now in Ruby you
00:18:43.400
cannot split a block across multiple
00:18:45.919
files and having all routes in a single
00:18:48.240
file only makes sense for small
00:18:50.679
applications to handle large
00:18:52.400
applications you need a way to separate
00:18:54.360
the route block and even the very first
00:18:56.760
release of Rus supported that via the
00:18:58.880
multiroute plugin so with the multiroute
00:19:01.120
plugin you could call r. multiroute in
00:19:03.640
your main routing block and it would
00:19:05.480
dispatch to separate routing blocks
00:19:07.320
based on the next segment in the
00:19:09.400
remaining path this these those routing
00:19:12.120
blocks would generally be stored in
00:19:13.919
separate files based on the route
00:19:15.520
segment name like this and that made it
00:19:17.760
simple to organize large applications in
00:19:19.960
Roa and allowed even the first release
00:19:21.880
of Roa to scale from simple single file
00:19:24.760
applications to decent sized
00:19:27.720
applications order 1.0 added 11 new
00:19:30.520
plugins not in the initial release and
00:19:33.000
these included plugins for returning
00:19:35.039
arrays and hashes as Json cross-site
00:19:38.039
request forgery protection rendering a
00:19:40.400
collection of partials in one call and
00:19:42.799
having a separate view subdirectory for
00:19:45.159
separate branches in the routing tree
00:19:47.799
Additionally the render plugin was
00:19:49.360
expanded to support the automatic
00:19:51.200
escaping of output and templates greatly
00:19:53.840
reducing the likelihood for cross-site
00:19:55.640
scripting issues I think my favorite
00:19:57.919
plug-in Edition in 1.0 is symbol views
00:20:00.720
so the symbol views plug-in is very
00:20:02.480
simple but it allows you to replace
00:20:04.720
manual calls to view to render templates
00:20:08.039
and just have the route block return a
00:20:09.520
symbol and this small change dries up a
00:20:12.080
lot of Route code and makes the common
00:20:14.000
case of rendering a template inside a
00:20:16.240
layout even simpler than it is in
00:20:18.559
Sinatra or rails now not everyone is a
00:20:21.480
fan of this tur style however just
00:20:24.000
because I think a particular style is
00:20:25.720
nicer does not mean I think I should
00:20:27.640
force it on all R users between R 1.1
00:20:31.440
and 1.3 25 more plugins were added
00:20:34.600
including plugins for managing HTTP
00:20:37.080
caching incrementally rendering
00:20:39.039
templates and compiling compressing and
00:20:41.240
serving asset files R 1.2 added the
00:20:44.320
mailer plugin which brought the benefit
00:20:46.240
of routing trees to sending emails from
00:20:49.120
applications so here's an example that
00:20:51.080
uses the mailer plugin generally you use
00:20:53.600
the mailer plugin in a Rota sub class
00:20:55.840
designed specifically for sending emails
00:20:58.799
unlike a ro to web application which is
00:21:00.679
designed to handle HTTP requests a rot
00:21:03.520
to mail application is designed to
00:21:05.080
handle internal requests however sending
00:21:07.799
mail with a mailer plug-in is done by
00:21:09.559
providing a path just like with an HTTP
00:21:12.440
request a Rota mail application uses the
00:21:15.080
same basic routing methods that a r to
00:21:17.200
web application uses and just like in a
00:21:19.600
r to web application at any point when
00:21:22.080
handling a mail requests the root to
00:21:24.360
mail application can do processing
00:21:26.159
related to the mail so here we are
00:21:28.159
setting the sender and recipient
00:21:29.919
addresses so those don't need to be
00:21:32.000
duplicated inside every maale handling
00:21:34.720
block now the r. mail method is used to
00:21:37.240
handle mail routes and it operates
00:21:39.320
similarly to R.G get and r. poost in
00:21:42.840
this case the time off matcher matches
00:21:44.919
the remaining path so the method will
00:21:47.080
yield to the block and the block sets
00:21:49.320
the subject for the mail and Returns the
00:21:51.520
symbol for the male template to render
00:21:53.600
and returning a symbol works here
00:21:55.000
because this mail application also uses
00:21:57.200
the symbol of views plugin
00:21:59.960
now between Rota 2.0 and 2.29 22 more
00:22:03.480
plugins were added these included
00:22:05.360
support for sending preload headers for
00:22:07.720
assets serving public files at specific
00:22:10.440
places in the routing tree rewriting
00:22:12.880
paths prior to routing Parson Jing
00:22:15.520
request bodies to parameters fast 01
00:22:18.520
routing to static paths and having the
00:22:21.000
routing tree support file extensions in
00:22:23.400
the request path especially order 2.27
00:22:26.760
added the class matchers plug-in which
00:22:28.840
allows you to specify the handling of
00:22:30.840
arbitrary classes that are used as
00:22:33.240
matchers going back to our initial
00:22:35.240
example we see that we are using the
00:22:37.080
integer matcher which yields an integer
00:22:39.440
we're then looking up the employee using
00:22:41.360
the integer and have to manually handle
00:22:43.600
the case where that lookup fails using
00:22:46.120
the class matchers plugin we can
00:22:47.480
simplify this we can register the
00:22:49.840
employee class as a matcher and build on
00:22:52.559
top of the integer matcher if there's a
00:22:54.760
match by the integer matcher if the
00:22:56.480
value is yielded to the block as an
00:22:58.080
integer
00:22:59.039
and the block can then do the employee
00:23:00.799
lookup and that allows the routing tree
00:23:02.919
to be simpler every case where you're
00:23:04.919
trying to match an employee you can pass
00:23:07.279
the employee class as a matcher and it
00:23:09.679
will yield the employee object to the
00:23:12.039
routing block if the segment was for a
00:23:14.520
valid employee and if the segment was
00:23:16.880
not for a valid employee it just
00:23:18.840
wouldn't
00:23:19.840
match between Rota 3.0 and 3.29 12 more
00:23:24.320
plugins were added including support for
00:23:26.840
encrypted sessions early hints content
00:23:29.799
security policies processing incoming
00:23:32.440
emails using a routing tree logging in
00:23:35.039
common log format showing nice exception
00:23:37.600
handling pages in development splitting
00:23:40.080
the rotting tree into subt trees without
00:23:42.159
using regular expressions and supporting
00:23:44.679
stronger cross-site request forgery
00:23:46.480
protection with tokens specific to the
00:23:48.960
request method and path order 3.3 added
00:23:52.400
a typ cast prams plugin for handling the
00:23:54.880
typ casting of submitted parameters to
00:23:56.840
expected types so here's an example of
00:23:59.360
use showing automatic conversion of a
00:24:01.360
given parameter to a positive integer
00:24:03.640
ensuring that ATT attackers cannot try
00:24:05.080
to submit an array or hash Now typ cast
00:24:08.039
prams has support for nested parameters
00:24:10.520
typecasting arrays of values to expected
00:24:12.799
types and custom parameter types it's
00:24:15.039
designed to be simple and not ver
00:24:17.360
Bose between Rota 3.30 and 3.59 17 more
00:24:21.679
plugins were added and these included
00:24:23.679
support for host authorization trying
00:24:26.440
multiple render engines and multiple
00:24:28.159
view directories when rendering
00:24:29.799
templates using arbitrary objects as
00:24:32.279
matchers during routing supporting
00:24:34.480
multiple directories for public file
00:24:36.080
serving at different places in the
00:24:37.760
routing tree and a simpler approach to
00:24:40.000
dispatching to separate routing trees
00:24:42.000
which can automatically set the view
00:24:43.520
subdirectory during the dispatch now
00:24:46.200
between R 3.60 and the current version
00:24:48.640
3.86 19 more plugins were added and
00:24:51.679
these plugins included support for
00:24:53.720
handling arbitrary objects returned from
00:24:55.919
routing blocks autoloading hash branch
00:24:58.880
for faster development and testing
00:25:01.039
setting a permissions policy enforcing
00:25:03.399
cookie Flags handling invalid request
00:25:06.039
bodies and measuring line and Branch
00:25:08.399
coverage of templates even in rby
00:25:10.600
versions that do not support coverage
00:25:12.480
for eval code order 3.79 added an hmac
00:25:16.880
paths plugin which allows you to easily
00:25:19.279
prevent path enumeration by including an
00:25:21.640
hmac in the path so going back to our
00:25:24.039
initial example we see that this allows
00:25:26.320
anyone to issue requests for this Branch
00:25:29.360
what if you want to prevent someone with
00:25:31.159
access to the application from
00:25:32.720
enumerating the employees well using the
00:25:35.440
hmac paths plugin we can wrap the
00:25:37.559
routing Block in r. hmac path and when
00:25:40.880
generating paths in your application you
00:25:43.080
would call hmac path with the path which
00:25:45.799
would prefix an hmac and some metadata
00:25:48.520
such that r. hmac would consider it
00:25:50.559
valid and the hmac paths plugin was
00:25:53.640
expanded in R to 3.80 to support session
00:25:56.200
specific hmax so that paths valid for
00:25:58.679
one logged in user would not be valid
00:26:00.799
for a different logged in user it was
00:26:02.760
expanded again in Moda 3.81 to support
00:26:05.320
paths that are only valid for a limited
00:26:07.799
time so that's a brief tour of plugins
00:26:10.760
that Roa has added in the first 10
00:26:13.520
years going to finish up this
00:26:15.279
presentation by discussing two open
00:26:17.600
source applications that are built on
00:26:19.320
top of Roa and how they are using roa's
00:26:21.760
features the first application is KFA
00:26:24.520
web which is a web front end for KFA a
00:26:27.520
ruby gem for with cfco which is a
00:26:29.360
distributed publish subscribe Cube now
00:26:31.919
crafco web ships all of its asset files
00:26:34.279
inside the gem and it uses Rus public
00:26:36.600
plugin and it serves the assets using a
00:26:39.480
path based on the gem version and this
00:26:42.039
automatically handles cash and
00:26:43.520
validation by using A New Path for each
00:26:46.279
gem version craft web uses the custom
00:26:49.279
block results plugin so that route
00:26:51.039
blocks can return craft web specific
00:26:53.159
objects which are translated into HTTP
00:26:55.559
responses and this reduces duplication
00:26:58.720
inside the routing blocks now the second
00:27:01.320
application is UB Cloud UB cloud is an
00:27:03.320
open source alternative to Amazon web
00:27:05.279
services it's being developed by a
00:27:07.080
startup also called UB Cloud now UB
00:27:09.640
Cloud uses the rodo authentication
00:27:11.240
framework to handle authentication rodo
00:27:13.600
is Ruby's most advanced authentication
00:27:15.960
framework with built-in support for
00:27:18.200
multiactor authentication such as top
00:27:20.840
and webo in now rodo is a Roa plugin but
00:27:24.480
you can use rodo even in non-r
00:27:26.320
applications by using R's middle plugin
00:27:29.000
and using the Roo application as
00:27:30.960
middleware now UB Cloud uses multiple
00:27:33.399
rodo configurations because it uses rodo
00:27:35.760
to handle authentication both for
00:27:37.440
browser logins as well as for its Json
00:27:41.080
API this is the section of UB Cloud's
00:27:43.440
main route block which is designed to
00:27:45.240
handle browser requests and GitHub web
00:27:47.799
hooks now UB cloud is a decent sized
00:27:50.240
application so it uses the hash branches
00:27:52.519
plugin to separate the routing trees it
00:27:55.120
actually has two separate dispatches to
00:27:56.919
routing trees here this one is for the
00:27:58.960
main application and it's used for
00:28:01.120
logged in users web hooks dispatch to a
00:28:04.000
different set of routing trees as they
00:28:05.880
don't need cross-site request forgery
00:28:07.679
checks nor do they require the same
00:28:09.760
authentication as logged in users and
00:28:12.080
this type of setup is possible in other
00:28:13.679
Frameworks but it is significantly
00:28:15.480
simpler in Roa so that's how some
00:28:17.880
production open source applications are
00:28:19.919
using Roa to simplify their web
00:28:22.000
development as we get near the end of
00:28:23.760
this presentation I'm happy to announce
00:28:25.720
that after 10 years Rota recently passed
00:28:28.279
10 million downloads so if you haven't
00:28:30.440
already tried using Roa now is a great
00:28:32.799
time to start if you're wondering about
00:28:35.080
the future of Roa I'm happy to announce
00:28:37.120
that I've joined UB cloud and part of my
00:28:39.080
job is continuing to maintain Roa and
00:28:41.559
other open source libraries on top of
00:28:43.440
which UB cloud is built I hope you had
00:28:46.080
fun learning about the first 10 years of
00:28:47.960
Roa if you're looking to reducing your
00:28:49.919
Cloud spend or you want an easy way to
00:28:51.840
deploy Ruby apps to the cloud with Kamal
00:28:54.000
stop by the UB Cloud booth and talk to
00:28:55.640
us we would love to work with you on it
00:28:58.640
and that concludes my presentation I'd
00:29:00.200
like to thank all of you for listening
00:29:01.440
to me I have maybe a minute for
00:29:03.679
questions yeah is there an instance
00:29:05.679
where you wouldn't want to use Roa well
00:29:07.440
it depends on what sort of what you're
00:29:09.240
doing obviously like compared to rails
00:29:11.519
uh if you're dealing with a lot of
00:29:12.600
people that already know rails or you're
00:29:14.080
using libraries that work with rails
00:29:16.000
you'd have to find equivalent stoa now I
00:29:17.919
think for a lot of the major stuff
00:29:19.399
that's probably uh possible um but you
00:29:22.799
might have three or four options in
00:29:24.240
rails and only one in Roa for more Niche
00:29:26.559
cases you might have options in and not
00:29:28.679
have options in Roda so a lot of it
00:29:30.440
depends on what you're doing and how
00:29:31.600
much code you want to reuse out there um
00:29:33.919
and whether or not there's Alternatives
00:29:35.360
that you can use in Roa so also depends
00:29:38.760
on how familiar the team is with rails
00:29:41.240
versus uh with Roa