Custom API call handling - robinmarechal/laravel-rest-api GitHub Wiki
Custom API calls handling
It is sometime necessary to write specific API calls handling.
There are two possibilities:
- Override a method to add or change the API behavior
- Add custom relationships
Override handling
Here is an example.
By default, the result of a DELETE
request is the deleted model (except if you specify ?all=true
in the url parameters).
But It's possible to change that, for example to always return a list.
To do that, all you have to do is to override the delete()
method of your controller, like this:
class UsersController extends Controller
{
/**
* Delete a user
* @param $id The user's id
* @return RestResponse /!\ Mandatory !
*/
public function delete($id): RestResponse
{
parent::delete($id);
$users = User::all();
return RestResponse::make($users);
}
}
Custom relationship
As always, an example is worth a thousand words, so there is one:
Imagine you have two tables: users
and posts
and the following models:
class User extends Model
{
public function posts(){
return $this->hasMany('App\Post');
}
}
class Post extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
}
The API automatically allows you to request the posts of one user (.../api/users/2/posts
), or the author of one post (.../api/posts/3/user
)
But if you want the latest post published by a certain user, you have to do it yourself, but not from the beggining.
When requesting an url like .../api/user/2/posts
, the library will call the method getPosts()
of your controller App\Controllers\Rest\UsersController
. This method is handled by the magic method __call()
since getPosts()
doesn't exist.
However, it's possible to define this method in your controller. The method will therefore be called instead of the __call()
one.
Now imagine you want to request the latest post published by a user, with the following URL:
.../api/users/2/lastPost
By default, the API will call the method getLastPost()
, therefore the __call()
one since it doesn't exist.
Then, it would throw an error saying that the relation lastPost
does not exist in User
model.
All you have to do is to define the method getLastPost()
in your UsersController
:
use App\Http\Controllers\Controller;
use App\Post;
use RobinMarechal\RestApi\Rest\RestResponse;
class UsersController extends Controller
{
/**
* Find the last post published by a user
* @param $id the user's id
* @return RestResponse /!\ Mandatory !
*/
public function getLastPost($id): RestResponse
{
$post = Post::where('user_id', $id)->orderBy('published_at', 'DESC')->first();
return RestResponse::make($post);
}
}
As simple as that.
I personnally use this a lot when I need to provide the inverse of a hasManyThrough
relationship.