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

claytoningmire's avatar

Laravel 8 API - show() method help

I have some controllers and resources for different models like users and blog posts. Every endpoint for my user model is working properly. I modeled my blog post model, controller, and resources similarly but the blog post model does not work when requesting specific posts. Blog post methods like index() and store() are working properly however.

api.php

Route::prefix('v1')->group(function (){
    Route::apiResource('/blog', 'App\Http\Controllers\API\v1\BlogPostController');
}

BlogPostController.php

/**
 * @param BlogPost $blog_post
 * @return BlogPostResource
 */
public function show(BlogPost $blog_post) : BlogPostResource
{
    return new BlogPostResource($blog_post);
}

/**
 * @return BlogPostResourceCollection
 */
public function index() : BlogPostResourceCollection
{
    return new BlogPostResourceCollection(BlogPost::paginate());
}

The BlogPostResource() is a default resource created with artisan. The BlogPostResourceCollection() is a resource created with artisan and the --collection flag applied.

I am targeting .../v1/blog/2 which is an existing blog post id.

Using the index() method endpoint proves our blog post with id of 2 exists

    {
        "id": 2,
        "created_at": "2021-01-21T01:29:36.000000Z",
        "updated_at": "2021-01-21T01:29:36.000000Z",
        "user_id": 52,
        "title": "quae porro laborum incidunt vel",
        "body": "Molestiae eius debitis..."
    },

When I dd() on $blog_post in show() I get this as one of the returned fields +exists: false.

I must be missing something.

It may be worth noting that my user model has this method:

public function blogPosts() {
    return $this->hasMany(BlogPost::class);
}

...and my blog post model has this method:

public function author() {
    $this->belongsTo(User::class);
}

The user_id field in a blog post is a foreign key referencing user.id.

The only methods that don't work are those that accept a BlogPost as an argument.

I changed the api.php file to contain only this route:

Route::get('/v1/blog/{blog_post}', function(BlogPost $blog_post){return $blog_post;});

...which was successful but I want this to work in the other route.

Response from php artisan route:list

| api.rest-api.test | GET|HEAD  | v1/blog        | blog.index   | App\Http\Controllers\API\v1\BlogPostController@index   | api        |
| api.rest-api.test | POST      | v1/blog        | blog.store   | App\Http\Controllers\API\v1\BlogPostController@store   | api        |
| api.rest-api.test | GET|HEAD  | v1/blog/{blog} | blog.show    | App\Http\Controllers\API\v1\BlogPostController@show    | api        |
| api.rest-api.test | PUT|PATCH | v1/blog/{blog} | blog.update  | App\Http\Controllers\API\v1\BlogPostController@update  | api        |
| api.rest-api.test | DELETE    | v1/blog/{blog} | blog.destroy | App\Http\Controllers\API\v1\BlogPostController@destroy | api        |
0 likes
2 replies
claytoningmire's avatar

I now know it was because my route was looking for blog not blog_post so I modified my controller. I see I could also alter my rout to look point to /blog_post

Tippin's avatar

@claytoningmire When you use Route::apiResource, it defaults to using the route name as the parameter, meaning it is looking for $blog, not $blog_post:

Route::get('/v1/blog/{blog}', function(BlogPost $blog){return $blog;});

Just edit controller method:

/**
 * @param BlogPost $blog
 * @return BlogPostResource
 */
public function show(BlogPost $blog) : BlogPostResource
{
    return new BlogPostResource($blog);
}

Please or to participate in this conversation.