Question

I have just started tinkering with Laravel (PHP newbie alert) and I have a doubt on how to implement my REST JSON APIs on this framework.

The desired URL path should be:

http://api.mysite.com/APIKEY/FUNCTION/(ARGUMENTS)*

But what is the best way to do it?

I did not find any enough explanatory guide, because it is assumed that each feature (authentication, search, and so on) are on different routes.

At the moment I managed to create migrations and models for the needed data and I also set a route this way:

Route::get('/{apikey}/{function}/{arg1}/{arg2}/{arg3?}', 
//The first two arguments are mandatory, the 3rd optional
function($apikey,$function,$arg1,$arg2)
{
        return Response::json(array(
        'status'=>'200'),
        200);
})
->where(array('function'=>'[A-Za-z]+')); 

This should be the correct action flow, but I have some doubts.

  1. Check that apikey is valid, if not return a 404 json response. How do I call such function, where do I define it?
  2. If key check is successful, understand which function is needed (should I use a switch construct or is there a better way to implement this, like a route group? In all examples with Route::group there is a static prefix, but here the prefix is apikey, a variable)
  3. Return data - if available - getting it from the database. I suppose that for each function i should code a specific controller that gets data from the database using the Models.
Was it helpful?

Solution

@1. I think I'd probably use a route filter for this, like so:

Route::filter('apikey', function(){
    if (Shared\API::checkIfKeyIsValid(Input::get('key') != true){
        return Shared\Errors::handleError("bad-api-key");
    }
});

You can see this filter checks to make sure some session variables are set and match, and if it returns ANYTHING, that's failing, and it won't send the user where the route normally goes. You'd call it in the route like so:

Route::get('play/{id}', array('before' => 'loggedin', 'uses' => 'ThingController@doThing'));

@2. I think a route group is how I'd structure this (if I understand what you're asking).
Edit: You've changed the question since I answered, regarding the prefix being a variable. I'd reorder your arguments so the API key is at the end, or you could take a look at this, which might do what you want: https://github.com/jasonlewis/enhanced-router

Route::group(array('prefix' => 'api'), function()
{
    //the routes for all API calls
    Route::group(array('prefix' => '/v1'), function()
    {
        //for version 1
        Route::group(array('prefix' => '/thing', 'before' => 'loggedin'), function()
        {
            //for things only
            Route::get('/getThing/{id}', 'APIController@getThing');
            Route::get('/getDifferentThing/{id}/{aux}/{optional?}', 'APIController@getDifferentThing');
        });
    });
});

@3. The returning of the data should be done via your controller with the data coming from the model. Either return it as a view, or just return it as JSON like so:

return Response::json($data);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top