Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

oliverbusk's avatar

Laravel RESTful api - best practice for query params

I have a simple website running Laravel Jetstream with Teams enabled. On this website, you can create different "to-do tasks", which are owned by a team. I have a model called Task.

I am trying to create a public facing API, so my users can query their tasks from their own applications. In my routes/api.php file, I have added this:

Route::middleware('auth:sanctum')->group(function(){
    Route::apiResources([
        'tasks' => \App\Http\Controllers\API\TaskController::class,
    ]);
});

And then in the TaskController, I have only begun coding the index method:

/**
 * Display a listing of the resource.
 * @queryParam team int The team to pull tasks for.
 * @return \Illuminate\Http\Response
*/
public function index()
{

   if(request()->team){
        $tasks = Task::where('team_id', request()->team)->get();
        return TaskResource::collection($tasks);
   }

   return response([
        'status' => 'error',
        'description' => "Missing required parameter `team`."
   ], 422);
      
}

Now this works fine. I can make a GET request to https://example.org/api/tasks?team=1 and successfully get all the tasks related to team.id = 1.

However, what if I want to include multiple query parameters - some required, others only optional. For example, if I want to let users access all tasks with a given status:

https://example.org/api/tasks?team=1&status=0

What is the best practices around this? As I can see where things are going now, I will end up with a lot of if/else statement just to check for valid parameters and given a correct error response code if something is missing.

0 likes
3 replies
tykus's avatar

This Laracasts lesson describes a technique for filtering based on query string, which I have utilised in several projects. It allows you to define on a Filter class which parameters you will accept, and how you will handle those values.

Source Code is on Github: https://github.com/laracasts/Dedicated-Query-String-Filtering

Personally, I would consider nested resources over query params where relevant, so my preferred URI would look like:

https://example.org/api/teams/1/tasks?status=0

Since you are returning a 4xx status whenever the team is not provided, then this format would work for you also.

Aside, be aware that the code you shared does not prevent a non-team member querying tasks for a team!

2 likes
martinbean's avatar

@oliverbusk If you need to query tasks belonging to a team, then instead of requiring the team ID to be passed a query string parameter I‘d consider making the team as part of the URI itself and creating a nested resource:

https://example.com/api/teams/{team}/tasks

This would list all of the tasks for the team on the request.

1 like

Please or to participate in this conversation.