Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Filters come in handy when you want to process all requests a certain way, to avoid duplicating that code in each of your controllers. Request attributes in Spark allow you to share data on a single request as it flows through your site, allowing each filter and controller to access its properties.
You might have felt the want to
start including the same code in
0:00
each of your route methods here.
0:04
Now like we talked about,
0:05
we really want to know the username before
the idea's page is able to be accessed.
0:06
So a common way to do this is by applying
what is known as HTTP middleware.
0:12
What this allows you to do is this.
0:17
A request comes in, and
the framework first looks for
0:20
any handler that should run
before the request is processed.
0:23
This handler has access to request and
response, and
0:27
it can add or change things,
including stopping the request altogether.
0:31
[SOUND] If things are to continue,
0:35
the request is handled
using the proper methods.
0:37
Finally, any matching
after-methods are run.
0:40
Now this pattern is pretty powerful for
0:43
things like authentication, like logging
into a site with a username or a password.
0:46
If you wanna make sure that
proper access is granted for
0:52
a specific section, you simply need to
make a before-handler that checks that
0:54
the request is coming from someone
that is logged in, or authenticated.
0:59
Otherwise, you handle things.
1:03
In Spark, this HTTP middleware concept is
handled with something called filters.
1:05
There's one for before and
another for after.
1:11
Why don't we make sure that visiting the
ideas page requires a known user name, and
1:15
if not, let's redirect them.
1:19
Okay, so let's add a filter for
before the /ideas page renders.
1:22
In Spark, that is just using the Spark
static method called before.
1:28
So we'll put that up there.
1:33
So we'll say before, and it was right.
1:34
We want a static import that method,
Spark.before.
1:42
And the first optional parameter here,
is the URI that you wanna catch.
1:46
So this also takes wild card matching, but
1:51
we wanna catch specifically
this ideas page, right?
1:54
And then it takes a filter object and
1:58
it's very similar to the single abstract
method that our routes are using.
2:02
So it takes a request and a response.
2:06
And we can, of course,
represent that as a lambda.
2:09
What we wanna do is we wanna check and
see if the username is in the cookies, so
2:13
if it's not, null.
2:17
So let's go ahead and we'll say if
2:18
(req.cookie("username") != null)
2:23
then what we want to do is
we wanna redirect, right?
2:29
We wanna redirect to the home page.
2:37
So we'll say res.redirect.
2:39
And now, since we've already
dealt with this response,
2:45
we don't need to do any other processing.
2:48
So, let's stop the request from
hitting one of the other routes.
2:50
So, we can do this by calling the static
halt method, and nothing more will happen.
2:55
So, we just say halt.
2:59
When that redirect happens,
that's gonna be a little jarring.
3:02
So, I think we should probably
tell them a message, right?
3:04
Let's add a to do about that.
3:07
Let's add a to do.
3:09
We'll say, // TODO.
3:12
Send message about, whoops.
3:21
Send message about redirect...somehow.
3:26
We don't have any messaging in place,
do we?
3:31
We should fix that.
3:32
I don't know what's going
on with the indentation.
3:35
Let's fix that, there we go.
3:38
Okay, so let's double check
that that's working, right?
3:39
So we will restart the server,
flip over to our page.
3:42
There are no cookies.
3:47
So if I go to the /ideas, this before
filter should catch it and redirect us.
3:49
It did it, let's take a look at why.
3:53
I said not equal to null.
4:01
If it is equal to null, okay.
4:03
So if it doesn't exist,
we wanna flip them over there.
4:07
Common mistake,
I'm gonna keep that in there, enjoy.
4:10
All right, no cookies, let's go to
the ideas, I restarted the server.
4:14
See now it flipped to Welcome Students
instead of, what's your idea.
4:20
So it's working, but
we really should show a message, right?
4:25
We should say like, you need to log
in before you can see the ideas page,
4:28
something like that.
4:31
Okay, so
we already added a to do about that.
4:33
Let's see what other to
do's are out there, ooh!
4:35
TODO, this username is tied
to the cookie implementation.
4:38
Maybe we can take care of that.
4:42
I mean, that's one of the powers
of middleware, right?
4:44
We can abstract away parts of this flow.
4:46
So let's do that,
let's go take look at where that's at.
4:49
One thing that we can do, is we can
manipulate the request object and
4:52
we can add data to it, so that other
filters and routes can access it.
4:56
So, let's remove this dependence
on our cookie implementation and
5:00
we'll keep it in our middleware.
5:03
We'll keep it secret in our middleware,
just using filters.
5:05
So, let's do that.
5:07
We'll come up here.
5:08
Now, the way that before filters work
is it's the way that they're added.
5:10
So, we want it before this one.
5:14
Before this before,
that's a lot of beforing.
5:17
All right, if we don't put a path, what
that means is this is gonna happen for
5:20
every single request response.
5:23
Every single request.
5:26
So, here we'll check and
see if the cookie exists.
5:29
Now we'll use my inverted
logic that I did before.
5:33
If it exists, what we're going
to do is we're going to add
5:39
an attribute to the request, so
the rest of the request can use it.
5:44
So those, on Spark, are called attributes.
5:49
So we're gonna say, req.attribute,
and we're gonna set username.
5:51
And we're gonna pull that
right off of the cookie.
6:00
Now it's okay that it knows about it here,
right?
6:02
Because we could write any one of
these filters for later, okay?
6:05
So that should do it.
6:09
And now any place after this
request where we're doing this,
6:10
if we wanna find any time
that we talk about cookie.
6:15
Right, every time I talk
about a request cookie,
6:18
let's replace that now
with request attribute.
6:21
So, req.attribute,
6:23
that was a Cmd+R opened this up.
6:27
So let's go ahead and let's do Replace.
6:32
And it's gonna flip through each one.
6:34
We wanna replace that one, and
we wanna replace that one.
6:35
So now,
any time we talk about request cookie,
6:39
it's only up in the top area.
6:46
Every other time, it's looking for
request.attribute.
6:49
So, there we go.
6:52
The cookie implementation, at least
on the read side, has been removed.
6:53
Now as long as we set the attribute
username, anything can do this, right?
6:56
Any kind of middleware, we could do
facial recognition or voice recognition,
7:00
anything.
7:04
As long as it sets the username attribute,
the username will be used in present.
7:05
Pretty cool, right?
7:09
So we definitely can remove this to do.
7:11
And I guess, before we get too brave,
7:18
we should make sure that our
changes are working, right?
7:21
Cuz we don't have tests.
7:25
So I'm gonna restart this.
7:26
And I'm gonna try to go,
there are no cookies,
7:29
I'm gonna try to go to the ideas page.
7:31
And I can't, but if I do put in my ID,
a cookie comes across,
7:34
but it's using the request attribute.
7:39
So I want,
really want a course on Spark testing.
7:42
Things are looking good.
7:46
HTTP middleware is definitely powerful and
7:49
allows you to abstract away the
implementation of fairly difficult things.
7:51
I'm glad you got some hands
on experience with it.
7:56
When you feel yourself
duplicating code and
7:58
routes, consider leaning
on them as a solution.
8:01
I really enjoy Spark's simple approach
to the problem space of being
8:05
able to modify requests and responses.
8:08
You'll find similar solutions
in other frameworks.
8:11
But this is so nice and succinct, and
8:14
really, in my opinion, what makes these
micro frameworks like Spark shine.
8:16
Okay, now we can gather
awesome ideas from students,
8:20
let's allow you all to vote on them.
8:23
You need to sign up for Treehouse in order to download course files.
Sign up