Validating Route Parameters
In this lesson, we'll learn how we can return a 404 Not Found exception when someone tries to view a movie that doesn't exist. We'll then learn how we can validate our route parameters using Regular Expressions or matchers.
- Author
- Tom Gobich
- Published
- Jan 24
- Duration
- 6m 6s
Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
Validating Route Parameters
-
(music)
-
- So at this point, we're pulling a movie information
-
directly from the file system of our project,
-
but we don't have anything saying,
-
hey, this movie doesn't exist.
-
Currently, if we tried that, we would just get an error.
-
So for example, if we jumped in here
-
and we did another awesome movie, The Movie,
-
we'd get an error saying, no such file or directory,
-
and then it would point to the path that it tried to read to.
-
So instead of that happening, what we would prefer to do
-
is show the user back a 404 page
-
or something stating that that file
-
or the requested resource does not exist within our system.
-
In addition to that, there's an additional step
-
that we can do that will restrict
-
what exactly makes up a valid slug
-
in terms of our route parameter.
-
So currently, if we did something like capitalized
-
another plus awesome plus movie,
-
we don't have anything in our system
-
invalidating this particular slug,
-
and it would attempt to read out a file at that location.
-
So let's take care of both of those instances
-
within our route definition in this lesson.
-
So let's hide our browser back away,
-
head back into our routes,
-
and let's first determine whether or not the movie exists.
-
The most simple way to do this
-
is going to be wrapping the read file
-
within a try catch call.
-
So we can cut this line out,
-
give ourselves a couple of line breaks here
-
to give us space, do a try.
-
Within that try, we can try to fetch the movie information.
-
If it fails at all, we can catch that error
-
and do something with it.
-
Now, the first thing you're gonna notice
-
is our movie down here is now showing a red squiggly
-
indicating that there's some form of an error.
-
The reason for this is because now a variable
-
doesn't exist called movie within the same scope.
-
So try here is a block level code block,
-
and we moved our movie declaration into said code block
-
so it no longer exists outside of the try call.
-
So we do have a couple of options
-
in terms of how we can provide the movie
-
back into our EdgeJS page.
-
We could do let movie right up here.
-
We don't necessarily have a particular type
-
as of yet that we can assign this movie,
-
so we'll just do type any right now,
-
and then get rid of the const declaration
-
and then just set movie to that variable.
-
So now movie exists again.
-
We can give this a save, jump back into our browser,
-
go back to a valid URL that we have right here,
-
give the page a refresh for sanity's sake,
-
and it still works, but there's an alternative approach
-
that we could take here as well.
-
If you remember back before,
-
whenever we were first learning
-
how we can provide stateful information into EdgeJS,
-
within the view property on our context,
-
there's a share method.
-
So let's go backwards a couple of steps here.
-
So we have an option to,
-
instead of providing movie directly
-
into the state of the page,
-
we can get rid of that state,
-
and instead we can share it
-
within the block level declaration here.
-
So if we have a movie, we could do ctx view share,
-
and now we can share that movie via this call.
-
There is a difference between sharing information
-
and providing information directly into the state,
-
but we don't need to learn about that quite yet.
-
We can focus on that later on.
-
So we can give this page a save,
-
jump back into our browser and do a sanity check.
-
Let's switch from another awesome movie to my awesome movie,
-
and it still works A-okay.
-
So now that we have our movie's fetch
-
wrapped around the try-catch,
-
let's see what we get whenever we try to attempt
-
a non-exist movie.
-
So let's do not exist,
-
and since we have that wrapped around the try-catch,
-
we still get our underlying page rendered out A-okay.
-
The only difference here is now our movie is undefined
-
rather than having information.
-
So instead of showing undefined now,
-
we wanna show that that resource does not exist,
-
and that's where the do something comes into play.
-
So whenever we do catch an error,
-
whenever we attempt to read from the file,
-
what we wanna do is provide some form
-
of standardized exception or error
-
that allows us to set a status and a message
-
to return back to the underlying page.
-
For this, AdonisJS provides a class called exception,
-
and we can throw that exception.
-
So let's throw new exception.
-
This allows us to set a message as well as some options,
-
which includes a code and a status number.
-
So we can say for our message,
-
could not find a movie called,
-
and then we can provide our CTX params slug within there.
-
For our options, the code, we can provide an E,
-
which is short for exception or error,
-
whichever way is easiest for you to remember, not found.
-
And then lastly, we can set the status to 404,
-
which is the HTTP status code for not found.
-
Now we can give this a save.
-
Let's jump back into our browser,
-
give the page one more refresh.
-
And now we get the error page stating
-
that could not find a movie called,
-
my awesome movie not exists, and the status is 404.
-
Awesome, so now we have our application properly handling
-
whenever somebody tries to request a movie
-
that doesn't exist.
-
But what about the use case where somebody tries
-
to provide a slug that's invalid,
-
at least in the eyes of our system.
-
So let's hide our browser back away
-
and take care of that one next.
-
For that one, we can use a route parameter validator.
-
That's something that we chain off of our route definition,
-
similarly to how we're giving the route a name.
-
We can do this via a method called where.
-
Within where we provide the parameter name,
-
in our case, our parameter name slug,
-
and then we provide some form of a matcher.
-
Now, Nonstjs does provide a couple of matchers
-
automatically for us.
-
We could do router.matchers,
-
and they have one for number, slug, and UUID.
-
Well, slug happens to match exactly what we're looking for,
-
so let's go ahead and utilize that one.
-
And before we round this out,
-
you'll note that it's highlighted in purple
-
within my system.
-
In yours, it might be a different color,
-
but this notes that it is a method,
-
so we wanna call it.
-
Cool, now, before we give this a save,
-
I do wanna note that we can also provide regex
-
directly into here as well.
-
So if you had a particular regex string
-
that you wanted to validate to,
-
you could provide that here too.
-
So something like a case insensitive regex,
-
you could do something like A through Z,
-
and something like that would work.
-
I'm gonna paste the slug route matcher back in here.
-
And now if we try to jump back into our URL
-
and request something like my plus awesome plus movie,
-
give that a run.
-
We still get back an error,
-
but now you'll notice that the 404 error
-
we're getting is different.
-
It's no longer that it can't find the movie,
-
but now it's that it cannot find a route
-
for the particular request.
-
It's stating it cannot find a get request route
-
for the path slash movies, my awesome movie.
-
But if we go back to a valid URL,
-
give it refresh for sanity sake,
-
everything still works A-okay.
-
So now in order for AdonisJS to use our movies slug route,
-
our slug needs to match against our validator
-
for the route parameter,
-
giving us just an extra level of safety.
-
And it also allows us to define additional routes
-
that are relatively similar
-
to slash movies slash something later on.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
7.0The Flow of Middleware7m 49s
-
7.1Authenticating A Newly Registered User4m 14s
-
7.2Checking For and Populating an Authenticated User2m 10s
-
7.3Logging Out An Authenticated User2m 24s
-
7.4Logging In An Existing User6m 54s
-
7.5Remembering A User's Authenticated Session6m 55s
-
7.6Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
-
8.0Creating A Movie List Page3m 43s
-
8.1Filtering A Query By Pattern Likeness7m 9s
-
8.2Filtering Our List by Movie Status5m 47s
-
8.3How To Apply A Dynamic Sort Filter To Your Query7m 12s
-
8.4Joining SQL Tables To Order By A Related Column4m 49s
-
Validating Query String Filter Values7m 23s
-
How To Paginate Filtered Query Results9m 15s
-
Pagination First, Last, Next, and Previous Buttons4m 2s
-
-
User Watchlist
-
An Alternative Approach to Many-To-Many Relationships4m 56s
-
Toggling A Movie in an Authenticated User's Watchlist9m 56s
-
Listing and Filtering User Watchlist Items7m 34s
-
Allowing Users To Toggle A Movie As Watched4m 44s
-
Filtering By User's Watched Status6m 7s
-
Defining A Composite Unique Constraint4m 46s
-
Join The Discussion! (1 Comments)
Please sign in or sign up for free to join in on the dicussion.
qu35t
Warning: When using the fs readFile function, or another readfile function, if you don't check the user input properly, you can expose yourself to the possibility of someone going back into your tree and reading arbitrary files on your server.
For example :
* fs.readFileSync('../../../../../../../etc/passwd', 'utf8')
* fs.readFileSync('%2e%2e%2f%2e%2e%2f%2e%2e%2f%2e%2e%2e%2e%2e%2f%2e%2e%2fetc%2fpasswd', 'utf8')
Please sign in or sign up for free to reply