URLs determine how your content / site is organized. They should be designed with clarity and longevity (we want URLs that don't disappear or change) in mind! What makes a good URL? →
/posts
or /post
/post/[date]/[name-of-post]
order/762190
post/how-to-make-good-urls
post/create
In general, good URLs are meaningful (their relevance to your content helps site usability and even search engine optimization)!
Some additional best practices that should be followed when creating URLs include: →
One of the advantages of using a web framework is that most frameworks come with routing.
Routing is the mechanism by which requests (as specified by a URL and an HTTP method) are routed to the code that handles the request.
How does routing usually work for URLs in our application? How about routing for static files? →
app
or router
objects (app.get
, app.post
or router.get
and router.post
)Which brings us to… what's a router again (an actual router object)? →
A router is an isolated instance of route handlers and middleware. It's an object that's essentially a mini-application →
A few other notes:
In our previous examples of route handlers, we've matched paths exactly (well, with the exception of trailing slashes and casing):
/about
Sometimes, an exact match isn't what we want, though. In some cases we may want a single route handler for multiple, similar, paths (for example posts/some-post-title
may always map to a route handler that retrieves a post with some-post-title)
.
Route handlers can use regular expressions to capture incoming requests that are all going to similar paths. We can specify patterns to match URLs.
A regular expression is a series of characters that define a pattern. These patterns can be made up of:
What are some examples of regular expression special characters? →
In JavaScript, regular expressions are bounded by forward slashes (they're not strings, so no quotation marks).
Here are a few examples of regular expressions using a String
's match
method (searches for regular expression in string):
'hello'.match(/ell/) // exactly ell
'swell'.match(/.ell/) // any character and ell
'hello'.match(/^.ell/) // starts with any character and ell
'swell'.match(/^.ell/) // starts with any character and ell
// these all demonstrate how to specify number of matches
'hello'.match(/el*/) // e, then 0 or more l's
'he'.match(/el*/) // e, then 0 or more l's
'hello'.match(/el+/) // e, then 1 or more l's
'he'.match(/el+/) // e, then 1 or more l's
'helllllo'.match(/el+/) // e, then 1 or more l's
'hello'.match(/el{1,2}/) // e, then at least one l, at most 2 l's
'helllllo'.match(/el{1,2}/) // e, then at least one l, at most 2 l's
/\d\d\d/
- 3 digits/h.\*$/
- h followed by 0 or more of any character up to the end of the line^\w\d?\d?$
- one letter at the beginning of a line followed by exactly 0, 1 or 2 digitsIn one of route handlers, let's try to use a regular expression that matches the following URLs:
/class01
/class02
...
etc.
// notice that the first argument, the path, is a regular expression
router.get(/class\d\d/, function(req, res) {
res.send('All the classes!');
});
What path would you specify in your router to make all of these URLs match? →
But doesn't match
router.get(/^\/j.+m$/, function(req, res) {
res.send('Matched');
});
What if the path you're responding to has some meaningful information trapped in the URL? For example, maybe we want take the class number out of our class\d\d
URL?
Or perhaps you've seen a URL like this:
posts/2015-10-27/paths-are-great
What are some bits of this URL that may be important to our applications? →
We can capture the values in a path by:
req.params
to access that variable
'/some/other/parts/:var1/:var2'
var1
and var2
can be accessed through:
req.params.var1
req.params.var2
router.get('/some/other/parts/:var1/:var2', function(req, res) {
res.send(req.params.var1 + ', ' + req.params.var2);
});
In your browser:
http://localhost:3000/some/other/parts/hello/world
We can also group parts of a regular expression so that they're captured in params as well!.
/class(\d\d)/
(captures the 2 digits after class)req.params
, with 0 being the first group, 1 the next, etc. … req.params[0]
Using our previous /class\d\d/
class example… to grab just the digits, we could:
router.get(/class(\d\d)/, function(req, res) {
res.send(req.params[0]);
});