Symfomy2 manual route definitions with FOSRestBund

2019-09-06 04:38发布

问题:

I am now using the FOSRestBundle in order to build a REST API within my Symfony application. The idea for now is to list some locations(hotels, restaurants...), I managed to configure the automatic routes with FOSRestBundle like:

/api/locations , /api/locations/{id} , /api/locations/{name}/detail

with this controller:

class LocationController extends FOSRestController implements ClassResourceInterface
{

/**
 * GET /locations 
 *
 * @return Array
 *
 */
public function cgetAction()
{
    $locations = $this->getDoctrine()
              ->getManager()
              ->getRepository('VisitBILocationsBundle:Location')
              ->findAll(); 

    if (!$locations) {
        return array(
            'locations' => $locations,
            'status' => 1
        );
    }

    return array(
            'locations' => $locations,
            'status' => 0
        );
}

/**
 * GET /locations/{locationId} 
 *
 * @return Array
 *
 */
public function getAction($id)
{
    $location = $this->getDoctrine()
              ->getManager()
              ->getRepository('VisitBILocationsBundle:Location')
              ->findBy(array('id' => $id));

    if (!$location) {
        return array(
            'location' => $location,
            'status' => 1
        );
    }

    return array(
            'location' => $location,
            'status' => 0
    );       
}

/**
 * GET /locations/{name}/detail 
 *
 * @return Array
 */
public function getDetailAction($name)
{

    $detail = $this->getDoctrine()
             ->getManager()
             ->getRepository('VisitBILocationsBundle:LocationDetail')
             ->findBy(array('name' => $name));

    if (!$detail) {
        return array(
            'locationDetail' => $detail,
            'status' => 1
        );
    }

    return array(
            'locationDetail' => $detail,
            'status' => 0
    );      
}


}

I've been struggling with this, but would anyone know how should I proceed to generate one custom url like this:

/api/locations/nearby/{latitude}/{longitude}

The idea is that I would provide my own latitude and longitude, and the backend will calculate and provide the locations which are the closest to me.

Of course I've looked at the documentation of FOSRestBundle for manual route configuration, but since I spent some time trying to do it, I come here to ask for some help :)

回答1:

If you want to manually define a route, it should just be as simple as adding the route to the existing routing configuration. How exactly you do it depends on how you're handling the routing configuration: annotation, yaml, or xml.

Option 1: YAML

In the routing.yml file (ex: src/Vendor/MyBundle/Resources/config/routing.yml) add something like:

location_nearby:
    pattern:  /api/locations/nearby/{latitude}/{longitude}
    defaults: { _controller: "MyBundle:Location:nearby" }
    requirements:
        _method: GET

which would correspond to this method in LocationController:

public function nearbyAction($latitude, $longitude) { ... }

Option 2: Annotations

Add this use statement to the Controller file:

use FOS\RestBundle\Controller\Annotations\Get;

and then define the route above the controller method:

/**
 * Return a nearby location
 * @Get("/api/locations/nearby/{latitude}/{longitude}")
 */
public function nearbyAction($latitude, $longitude) { ... }


回答2:

OK here is how to proceed, works fine for me:

I use the annotation system to route /locations/nearby/{latitude}/{longitude}

/**
 * Return a nearby location
 * @Get("/locations/nearby/{latitude}/{longitude}", requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"})
 */
public function nearbyAction($latitude, $longitude) {...}

Then I have to specify float numbers with: requirements={"latitude" = "[-+]?(\d*[.])?\d+", "longitude" = "[-+]?(\d*[.])?\d+"}

Those will still be interpreted as string by the controller: "64.1333", I just have to use this in the controller:

floatval($latitude)

to get url parameters as float and then do my calculations!