I have and api endpoint which should return a user based on his id : user/{id}
.
In my controller i have the following code:
/**
* @Api\Get("user/{id}")
* @SWG\Parameter(name="id", type="string", in="path", required=true)
*/
public function getUser(Request $request, string $id) {
$user = $this->getDoctrine()->getManager()->getRepository('App\Entity\User')->findUser($id);
return $this->view($user);
}
In my repository i have the following code:
public function findUser(string $id) {
$qb = $this->createQueryBuilder('a');
$qb->andWhere($qb->expr()->eq('a.id',':id'))->setParameter('id',$id);
return $qb->getQuery()->getOneOrNullResult();
}
it is working fine when getting user/4
, but it is also working when getting user/4ruqbu
.
I just want to get the user on user/4
and no result on user/4ruqbu
. It should return the exact match. I think the problem is that the id parameter is a string. if i change it to int it is working, but i get an error instead of no result if i try user/4eiugq
.
Is there a way to handle that?
CodePudding user response:
Your route accepts any string for your id
parameter which means that any value will make its way to your repository method. Then if you try to use a string which starts with a numeric value as an integer, you will get that integer.
Try for yourself on 3v4l.org:
var_dump((int)'4ruqbu'); // output: int(4)
You could make use of parameters validation using a Regex:
/**
* @Api\Get("user/{id<\d >}")
*/
public function getUser(Request $request, int $id) {
// ...
}
This should now fail for URIs such as /user/4ruqbu as it does not meet the route requirements.
Some improvements:
If you installed sensio/framework-extra-bundle you can benefit of the ParamConverter and replace string $id
with a user:
public function getUser(User $user, Request $request)
{
// ...
}
Avoid fetching services related to Doctrine with $this->getDoctrine()
etc. Use autowiring instead.
If you need the Entity Manager to save/update/remove entities, add a Doctrine\ORM\EntityManagerInterface
argument to your controller method. If you need to query for entities using a repository, add an argument typed with its class like App\Repository\UserRepository
in your case:
// Example of controller method fetching services by autowiring:
public function myAction(EntityManagerInterface $em, UserRepository $userRepo)
{
// ...
}