Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Public Endpoint /travels with Feature Tests

Premium
16:32

Time for us to build the first API endpoint. The description from the client looks like this:

A public (no auth) endpoint to get a list of paginated travels. It must return only public travels

So let's transform it into a plan of action for this lesson:

  1. New API Controller and Route
  2. Return all Travels with Pagination and API Resource
  3. Write automated Tests for it with Factories

Controller and Route with Prefix

First, let's generate the Controller:

php artisan make:controller Api/V1/TravelController

As you can see, I immediately add two subfolders:

  • /Api, which means we will store all API controllers in there - maybe in the future, there will be separate /Web Controllers
  • /V1 is an immediate preparation for versioning: it's a personal habit to create API as v1 right away, with the idea that there may be v2 in the future, which would then land in the /Api/V2 subfolder

For now, we need only one method in the Controller, so we have a choice to make it an Invokable, but I have a feeling that there may be more methods like show() in the future, so let's stick to a typical Route::resource() naming and create an index() method:

app/Http/Controllers/Api/V1/TravelController.php:

namespace App\Http\Controllers\Api\V1;
 
use App\Http\Controllers\Controller;
use App\Models\Travel;
 
class TravelController extends Controller
{
public function index()
{
return Travel::where('is_public', true)->get();
}
}

We also need the Route for that Controller:

routes/api.php:

use App\Http\Controllers\Api\V1\TravelController;
 
// ...
 
Route::get('travels', [TravelController::class, 'index']);

At this point, the endpoint URL would be /api/travels. But I want to use the versioning in the Routes, the same as with namespaces above, to have /api/v1/travels.

We could add this prefix in three different places...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (31 h 16 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

M
Mrzalais ✓ Link copied!

One useful thing I've found is when you use laravel ide-helper to generate docblocks for every model, you can then write a comment in Resources, for example, TravelResource above the returned array specifying /** @var Travel $this */ then it is easier to see the attributes of the model as the IDE can show which are available.

  • ide-helper is in general very useful in the scope of the whole project
  • not sure about this 100% but if you were to use PHPStan some time in the future it would probably show errors like Property accessed via magic method, but the added comments would resolve that (note: I haven't used Larastan yet so not sure how different they are in this sense)
PK
Povilas Korop ✓ Link copied!

Thanks for the valuable comment, we'll see what Larastan will say, at the end of this course, and we may make changes accordingly :)