gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Inside our JavaScript, we're making a POST request to the endpoint. And that makes sense. The topic of "which HTTP method" - like GET, POST, PUT, etc - you're supposed to use for an API endpoint... can get complicated. But because our endpoint will eventually change something in the database, as a best-practice, we don't want to allow people to make a GET
request to it. Right now, we can make a GET request by just putting the URL in our browser. Hey! I just voted!
To tighten this up, in CommentController
, we can make our route smarter: we can tell it to only match if the method is POST. To do that add methods="POST"
.
... lines 1 - 8 | |
class CommentController extends AbstractController | |
{ | |
/** | |
* @Route("/comments/{id}/vote/{direction}", methods="POST") | |
*/ | |
public function commentVote($id, $direction) | |
{ | |
... lines 16 - 25 | |
} | |
} |
As soon as we do that, when we refresh... 404 not found! The route no longer matches.
Tip
Actually, it's a 405 response code! HTTP Method Not Allowed.
Another cool way to see this is at your terminal. Run: php bin/console router:match
. Then go copy the URL... and paste it.
php bin/console router:match /comments/10/vote/up
This fun command tells us which route matches a given URL. In this case, no routes match, but it tells us that it almost matched the app_comment_commentvote
route.
To see if a POST
request would match this route, pass --method=POST
:
php bin/console router:match /comments/10/vote/up --method=POST
And... boom! It shows us the route that matched and ALL its details, including the controller.
But there's something else that's not quite right with our route. We're expecting that the {direction}
part will either be up
or down
. But... technically, somebody could put banana
in the URL. In fact, let's try that: change the direction to banana
:
php bin/console router:match /comments/10/vote/banana --method=POST
Yes! We vote "banana" for this comment! This isn't the end of the world... if a bad user tried to hack our system and did this, it would just be a down vote. But we can make this better.
As you know, normally a wildcard matches anything. However, if you want, you can control that with a regular expression. Inside the {}
, but after the name, add <>
. Inside, say up|down
.
... lines 1 - 8 | |
class CommentController extends AbstractController | |
{ | |
/** | |
* @Route("/comments/{id}/vote/{direction<up|down>}", methods="POST") | |
*/ | |
public function commentVote($id, $direction) | |
{ | |
... lines 16 - 25 | |
} | |
} |
Now try the router:match
command:
php bin/console router:match /comments/10/vote/banana --method=POST
Yes! It does not match because banana
is not up or down. If we change this to up
, it works:
php bin/console router:match /comments/10/vote/up --method=POST
By the way, you might be tempted to also make the {id}
wildcard smarter. Assuming we're using auto-increment database ids, we know that id
should be an integer. To make this route only match if the id
part is a number, you can add <\d+>
, which means: match a "digit" of any length.
... lines 1 - 8 | |
class CommentController extends AbstractController | |
{ | |
/** | |
* @Route("/comments/{id<\d+>}/vote/{direction<up|down>}", methods="POST") | |
*/ | |
public function commentVote($id, $direction) | |
{ | |
... lines 16 - 25 | |
} | |
} |
But... I'm actually not going to put that here. Why? Eventually, we're going to use $id
to query the database. If somebody puts banana
here, who cares? The query won't find any comment with an id of banana
and we will add some code to return a 404 page. Even if somebody tries an SQL injection attack, as you'll learn later in our database tutorial, it will still be ok, because the database layer protects against this.
... lines 1 - 8 | |
class CommentController extends AbstractController | |
{ | |
/** | |
* @Route("/comments/{id}/vote/{direction<up|down>}", methods="POST") | |
*/ | |
public function commentVote($id, $direction) | |
{ | |
... lines 16 - 25 | |
} | |
} |
Let's make sure everything still works. I'll close one browser tab and refresh the show page. Yea! Voting still looks good.
Next, let's get a sneak peek into the most fundamental part of Symfony: services.
I have the same problem. Seems like the Git Bash console I'm using is interpeting "/" as git-bash.exe location folder. Not sure how make it stop adding the "C:/Users/hanen/Downloads/vendor/git-for-windows" in front of the route. Seems like a Git Bash console thing. Works fine in cmd.exe
Hey guys,
Try to wrap that path in quotes! Probably single quotes may not work in windows, I suppose you need to wrap it in double quotes. But just in case, it's a good idea to try both, some quotes should work for you I think. So, basically you need to run the next command:
$ bin/console router:match "/comments/10/vote/up" --method=POST
This should do the trick. And thanks JoxTheFix for some ideas about why it may happen, it's clearer for me where the problem might be.
I hope this helps!
Cheers!
Hi, I'm getting the same error with git bash (MINGW64) and single or doubles quotes didn't help. As with Jox, with windows prompt it works. Thanks.
Hey hanen
Let's double check a couple of things
1) Check that you have defined the route /comments/{id}/vote/up
. You can run bin/console debug:router
to see all your routes
2) Check that you have a comment in your database with ID 10
Let me know if you still have problems. Cheers!
The problem comes from my route where I specify that I only want to run it in POST so I add methods={"POST", "GET"}
/**
* @Route("/comments/{id}/vote/{direction<up|down>}", methods={"POST", "GET"})
*/
Did Victor comment answered to your problem? If not, could you please check if you are importing the right Route class? It should be this one Symfony\Component\Routing\Annotation\Route
Hi everyone , Thanks for your reply :))).. there Actually I'm using cmder software package on Windows but when I go to terminal from phpstorm run command adding double quotes: php bin/console router:match "/comments/10/vote/up" --method=POST
looks like it should work fine
[OK] Route "app_comment_commentvote" matches
+--------------+-------------------------------------------------------------+
| Property | Value |
+--------------+-------------------------------------------------------------+
| Route Name | app_comment_commentvote |
| Path | /comments/{id}/vote/{direction} |
| Path Regex | #^/comments/(?P<id>[^/]++)/vote/(?P<direction>up|down)$#sDu |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | POST |
| Requirements | direction: up|down |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\CommentController::commentVote |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | utf8: true |
+--------------+-------------------------------------------------------------+
// composer.json
{
"require": {
"php": "^7.3.0 || ^8.0.0",
"ext-ctype": "*",
"ext-iconv": "*",
"easycorp/easy-log-handler": "^1.0.7", // v1.0.9
"sensio/framework-extra-bundle": "^6.0", // v6.2.1
"symfony/asset": "5.0.*", // v5.0.11
"symfony/console": "5.0.*", // v5.0.11
"symfony/debug-bundle": "5.0.*", // v5.0.11
"symfony/dotenv": "5.0.*", // v5.0.11
"symfony/flex": "^1.3.1", // v1.17.5
"symfony/framework-bundle": "5.0.*", // v5.0.11
"symfony/monolog-bundle": "^3.0", // v3.5.0
"symfony/profiler-pack": "*", // v1.0.5
"symfony/routing": "5.1.*", // v5.1.11
"symfony/twig-pack": "^1.0", // v1.0.1
"symfony/var-dumper": "5.0.*", // v5.0.11
"symfony/webpack-encore-bundle": "^1.7", // v1.8.0
"symfony/yaml": "5.0.*" // v5.0.11
},
"require-dev": {
"symfony/profiler-pack": "^1.0" // v1.0.5
}
}
Hi, When I run bin/console router:match /comments/10/vote/up --method=POST
//dir Path: hanen@hanen-PC /d/symfony5/cauldron_overflow (master)
I got an error [ERROR] None of the routes match the path "C:/Users/hanen/Downloads/vendor/git-for-windows/comments/10/vote/up"
the issue is missing vendors libraries ?!!