3: Routers
We’ve already used Kitura’s Router class quite a bit in this book, and you might be thinking that you’ve already got a pretty good idea of how it works. Well, if that’s what you think… you’re probably right. Nonetheless, there are still a few new tricks we can learn.
HTTP Methods
As previously mentioned, routers have methods (in the Swift sense) for defining routes and handlers which correspond to various HTTP methods (also sometimes called HTTP verbs) available. In most cases, get()
and post()
are the only ones you’ll use, which obviously correspond to the GET and POST HTTP methods. But if you want to be really RESTy, there’s also put()
and options()
and lock()
and a bunch more available to you. See the RouterHTTPVerbs_generated.swift
file in the Kitura project for all of them; the code in this file is so monotonous that, as the filename implies, it was actually generated by a script rather than written by hand. (The script itself is at Scripts/generate_router_verbs.sh
in the Kitura project directory.) Use these methods to define routes and corresponding handlers that will only fire if a request using the corresponding HTTP method is made from the client. Let’s test that.
Let’s try accessing that route with both GET and POST requests.
And let’s try that again with one of the more unusual methods.
Curl’s --request
option will let us define any arbitrary HTTP method to send in the request, so let’s use that when we test.
Okay, so nothing too surprising there.
Aside from these methods, you may recall in an earlier example that we used all()
. Setting a handler with this method will cause the handler to fire no matter what HTTP method was used to access the path. This bit of code may look a little familiar:
Let’s test it out.
The request type still has to be one included in Kitura’s RouterMethod enum, however, so we can’t get too crazy.
If you enabled logging, you’ll also see “Failed to parse a request. Parsed fewer bytes than were passed to the HTTP parser” logged. Note that, despite the wording of the error, if you see it in the future, it may be because you’re using an incorrect HTTP method to make a request to your server. And remember, capitalization counts!
At any rate, I generally would not recommend using all()
in most cases and instead use get()
, post()
and friends. If you’re using all()
, then either you want the same thing to happen no matter what HTTP method was used to access a path, which is incorrect behavior speaking on a technical level and just generally silly, or you’ll have to implement a convoluted logic fork in your code along the lines of…
But this sort of thing is unnecessary. Remember way back in the first chapter when I mentioned that paths can have more than one handler assigned to them? The same holds true no matter what HTTP method you’re telling that path to use. So the above can be replaced with the following much nicer code:
Path Parameters
So far in this book, we have used static paths with our routes. However, dynamic paths are pretty easy to implement with Kitura using path parameters.
For example, consider a blog that uses a path like “blog/1” to show the first blog post, “blog/2” to show the second one, and so on. Now obviously it would be unwieldy to implement this in Kitura using static paths.
Instead, we can use a path with a parameter. To do so, add a path segment with a name prefixed with a colon character. You can then find the value of the parameter used to access the path by looking it up by that name in the parameters
property of the RouterRequest object passed to your handler; parameters
is a simple [String: String] dictionary.
Let’s test.
Note that you can easily use more than one parameter in your paths, and they don’t have to be at the end of the path.
We test, and it works as expected.
Okay, that’s pretty cool. But let’s go back and look at that simpler path parameter example one more time.
There’s a potential problem here in that the postId parameter can be anything. For example…
Okay, no sweat, right? If we want to make sure the post ID is a positive number, we can just do something like…
And, yes, this works well enough.
But there’s another way. We can use regular expressions to define that we want a path parameter to fit a certain format. So let’s do it that way instead. To implement a path parameter with a regular expression, name it with a colon as normal, but then follow the name with the regular expression pattern in parentheses. The pattern to match one or more digits is \d+
, but we need to escape that backslash with another backslash. So let’s implement it this way.
Now let’s test. You’ll see that trying a non-numeric path parameter now causes Kitura to return its standard 404 Not Found error; we didn’t have to write any extra code in our handler to make it happen.
Note that you don’t want to use the ^
and $
regular expression tokens in your pattern to signify the beginning and end of the path parameter value; they are effectively implicitly added by Kitura.
Last updated