We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Custom querystring for Rest API

Hi people,

I'm creating a rest api and I need configure a route with optional parameters on querystring.

The url should be looks like: https://192.168.1.133/base/generic/lista/ OR https://192.168.1.133/base/generic/lista?q=criteria OR https://192.168.1.133/base/generic/lista?q=some+criteria&sort=-priority OR https://192.168.1.133/base/generic/lista?q=some+criteria&sort=priority OR https://192.168.1.133/base/generic/lista?sort=-priority

I want to use a unique get route for this, is:

    $app->get('/generic/lista/[I DONT KNOW WHAt PUT HERE]', function([AND HERE]) {
        $controller->listar($q,$sort);
    });

$app is my MicroApp instance $controller is my Controller instance

And in my controller I want to validate if $q or $sort have value. I was trying with:

$app->get('/generic/lista/?{q:[a-z]*}&{sort:-?[a-z0-9]*}', function($q=null, $sort=null) {
    $controller->listar($q,$sort);
});

But I don't receive %q or $sort in controller

Any clue?

Thanks



145.0k
Accepted
answer
edited Nov '15

Actually to rerievie variables from question mark you have to use getQuery() from $app->request like this:

$app->request->getQuery('q') or $app->request->getQuery('sort').

If you have to use this in function you have to add use ($app) after function. Im not sure if it is bound to function closure like in di(so you can just use $this, well this behaviour of di is actually only in 2.1 beta phalcon).



1.0k

Hi Jurigag

About use "use ($app)", I don't need pass it because my controller has $app injected.

I have a doubt, my route are ok:

$app->get('/generic/lista/?{q:[a-z]*}&{sort:-?[a-z0-9]*}', function($q=null, $sort=null) {
    $controller->listar($q,$sort);
});

Or should be looks like:

$app->get('/generic/lista/?{q:[a-z]*}&{sort:-?[a-z0-9]*}', function() {
    $controller->listar();
});

Then in my controller can I use your suggestion:

$app->request->getQuery('q') or $app->request->getQuery('sort').

Thanks in advance

Actually to rerievie variables from question mark you have to use getQuery() from $app->request like this:

$app->request->getQuery('q') or $app->request->getQuery('sort').

If you have to use this in function you have to add use ($app) after function. Im not sure if it is bound to function closure like in di(so you can just use $this, well this behaviour of di is actually only in 2.1 beta phalcon).

It Doesn't even have to be in route definition



1.0k

Thanks, works perfect

Another question about these routes, I have defined:

    $this->app->get('/generics/', function() {
        $this->controller->listar();
    });

    $this->app->get("/generics/{id:[0-9a-z]+}",  function($id) {
        $this->controller->get($id);
    });

    $this->app->post('/generics/', function()  {
        $this->controller->nuevo();
    });

    $this->app->put('/generics/{id:[0-9a-z]+}', function($id) {
        $this->controller->modificar($id);
    });

    $this->app->delete('/generics/{id:[0-9a-z]+}', function($id) {
        $this->controller->eliminar($id);
    });

But no all of them works:

$this->app->get('/generics/', function() { // doesn't work, always is executed $this->app->get("/generics/{id:[0-9a-z]+}

$this->app->post('/generics/', function() { // doesn't work, the route is not found

put and delete works perfect

Before that, I was using specific names for each resource like app->get('/generics/lista/ or app->get('/generics/get/ or app->get('/generics/new/

But for client guidelines we need to use / with each different http method

Any suggestion?

It Doesn't even have to be in route definition

edited Nov '15

It should work. You are sure you are access /generics/ not /generics ? So if this second route with $id is executed what value of $id is then ?



1.0k

Yes, I'm sure about the access. I tryed with:

https://192.168.1.131/base/generics/ https://192.168.1.131/base/generics

("base" is my context path on apache)

But the route isn't found... is executed:

$app->notFound(function () {
            $this->app->response->setStatusCode(ICommons::HTTP_404, ICommons::HTTP_404_MSG);
            $this->app->response->setHeader(ICommons::HEADER_CONTENT_TYPE, ICommons::HEADER_CONTENT_JSON);
            $this->app->response->setJsonContent(array(ICommons::RESPONSE_RESULTADO => ICommons::HTTP_404_MSG, ICommons::RESPONSE_MENSAJE => ICommons::RESPONSE_RUTA_INEXISTENTE));
            $this->app->response->send();
        });

The second route works like:

https://192.168.1.131/base/generics/67890 With response like: { resultado: "OK", mensaje: { id: "67890", nombre: "generico de prueba 2", fecha: "2015-11-17 14:19:32.275854", tipo: 1, marca: "marca 2" } }

I don't see the error....

It should work. You are sure you are access /generics/ not /generics ? So if this second route with $id is executed what value of $id is then ?



1.0k

Solved!! Using Micro/Collection

use Phalcon\Mvc\Micro\Collection as MicroCollection;
.....

$mc = new MicroCollection();

    $mc->setHandler($this->controller);
    $mc->setPrefix('/generics');

    $mc->get('/', "listar");

    $mc->get('/{id:[0-9a-z]+}', "get");

    $mc->post('/', "nuevo");

    $mc->put('/{id:[0-9a-z]+}', "modificar");

    $mc->delete('/{id:[0-9a-z]+}', "eliminar");

    $this->app->mount($mc);