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

verism's avatar

How do create a database query to use on both web and api?

Hi,

I've been working on integrating Vue into a Laravel installation, and under a specific API route (that displays a list of actors) I arrived at the following to achieve what I need:

// routes/api.php

Route::get('/actors', function(Request $request) {
    // Select all user with actor role, with their attributes and gender
    $actors = User::whereHas('roles', function ($query) {
        $query->where('slug', '=', 'actor');
    })->with(['actorAttributes', 'gender']);

    // Limit by gender
    if ($request->has('gender')) {
        $actors->whereHas('gender', function ($query) use ($request) {
            $query->where('name', $request->gender);
        });
    }

    // Limit by minimum age
    if ($request->has('min_age')) {
        $actors->whereHas('actorAttributes', function ($query) use ($request) {
            $query->where('age_minimum', '>=', $request->min_age);
        });
    }

    // ...several other conditionals here...

    // Get the results and return them
    return $actors->paginate(24);
});

Of course I know this isn't the best place for the logic, but it works exactly as it should. However I now want to recreate the same functionality for my web route (to provide server-rendered fallback for URLs that include queries), but i'm having trouble replicating it.

In my web routes there is:

// routes/web.php

Route::get('/actors', 'ActorController@index')->name('actors');

And my Actor Controller started out like so:

public function index(Request $request)
{
    $actors = User::whereHas('roles', function ($query) {
        $query->where('slug', '=', 'actor');
    })->with(['roles', 'actorAttributes'])->paginate(24);

    return view('actors', compact('actors'));
}

But now I need to expand on it to deal with URL queries. Ideally all of the logic in routes/api.php would be extracted out entirely so it could be used by both web and api, but at the moment I'm having difficulty even recreating my api logic in my Actor Controller.

Any advice would be great.

0 likes
4 replies
verism's avatar

@martinbean Well that's annoying - I meant to like your reply, not mark it as a solution...

Either way, thanks for your input. I've actually managed make it work now, although I'll definitely catch up on the lesson you linked.

One other thing, could you expand on / link to something helpful regarding "repository methods"? I'm only an intermediate PHP dev at best...

martinbean's avatar

@verism You could move the query to a method on a class, and then use that method in both your API and web controllers:

class ActorRepository
{
    public function paginate($perPage = 24)
    {
        return User::whereHas('roles', function ($query) {
            $query->where('slug', '=', 'actor');
        })->with(['roles', 'actorAttributes'])->paginate($perPage)
    }
}

You can then inject the repository and use its method in your controllers:

class ActorController extends Controller
{
    private $actors;

    public function __construct(ActorRepository $actors)
    {
        $this->actors = $actors;
    }

    public function index()
    {
        $actors = $this->actors->paginate();

        return view('actor.index', compact('actors'));
    }
}
1 like

Please or to participate in this conversation.