User Profile
Sanctum middleware
To make sure you can get your profile just right, you should add the auth:sanctum
middleware to the restify middleware config:
// config/restify.php
'middleware' => [
'api',
'auth:sanctum',
\Binaryk\LaravelRestify\Http\Middleware\DispatchRestifyStartingEvent::class,
\Binaryk\LaravelRestify\Http\Middleware\AuthorizeRestify::class,
]
Get profile
When retrieving the user's profile, it is serialized by using the UserRepository
.
GET: /api/restify/profile
This is what we have for a basic profile:
{
"id": "7",
"type": "users",
"attributes": {
"name": "Eduard",
"email": "interstelar@me.com"
},
"meta": {
"authorizedToShow": true,
"authorizedToStore": true,
"authorizedToUpdate": true,
"authorizedToDelete": true
}
}
You can add more fields
in your UserRepository
if you want to display them.
public function fields(RestifyRequest $request): array
{
return [
field('name')->rules('required'),
field('email')->rules('required')->storingRules('unique:users'),
field('age')
];
}
Since the profile is nicely set on by using the UserRepository, you can now benefit from the power of the related entities. For example, if you want to return user roles:
//UserRepository
public static array $related = [
'roles',
];
Also, make sure that the User
model has this method that returns a relationship from another table. You can do that or you can simply
return an array:
//User.php
public function roles(): array
{
// In a real project, here you will get this information from the database.
return [
'owner',
'admin'
];
}
Now, let's get the profile by using the roles
relationship:
GET: /api/restify/profile?include=roles
The result will look like this:
{
"id": "7",
"type": "users",
"attributes": {
"name": "Eduard",
"email": "interstelar@me.com"
},
"relationships": {
"roles": [
"owner",
"admin"
]
},
"meta": {
"authorizedToShow": true,
"authorizedToStore": true,
"authorizedToUpdate": true,
"authorizedToDelete": true
}
}
Without repository
In some cases, you might choose not to use the repository for the profile serialization. Afterwards, you should add the
trait Binaryk\LaravelRestify\Repositories\UserProfile
into your UserRepository
:
// UserProfile
use Binaryk\LaravelRestify\Repositories\UserProfile;
class UserRepository extends Repository
{
use UserProfile;
public static $model = 'App\\Models\\User';
//...
}
The profile will return the model directly:
Relations
Note that when you're not using the repository, the ?include
will not work anymore.
/api/restify/profile
You will get:
{
"data": {
"id": 7,
"name": "Eduard",
"email": "interstelar@me.com",
"email_verified_at": null,
"created_at": "2020-12-24T08:49:30.000000Z",
"updated_at": "2020-12-24T08:52:37.000000Z"
}
}
Conditionally use repository
In rare cases you may want to utilize the repository only for non admin users. Make sure to serialize specific fields for the users:
use Binaryk\LaravelRestify\Fields\Field;
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\Repositories\UserProfile;
use Illuminate\Http\Request;
class UserRepository extends Repository
{
use UserProfile;
public static $model = 'App\\Models\\User';
public static function canUseForProfile(Request $request)
{
return $request->user()->isAdmin();
}
public function fields(RestifyRequest $request)
{
return [
field('name')->rules('required'),
field('email')->rules('required')
->storingRules('unique:users')->messages([
'required' => 'This field is required.',
]),
];
}
}
Thus, you instruct Restify to only use the repository for users who are admins of your application.
Update Profile using repository
By default, Restify will validate and fill only the fields presented in your UserRepository
for updating the user's
profile. Let's get as an example the following repository fields:
// UserRepository
public function fields(RestifyRequest $request)
{
return [
field('name')->rules('required'),
field('email')->storingRules('required', 'unique:users')->messages([
'required' => 'This field is required.',
]),
];
}
If we will try to call the PUT
method to update the profile without data:
{}
We will get back a 4xx
validation:
Accept header if you test it via Postman (or other HTTP client) and make sure you always pass the Accept
header application/json
. This will instruct Laravel to return you back the json formatted data:
{
"message": "The given data was invalid.",
"errors": {
"name": [
"The name field is required."
]
}
}
Let's say we have to populate the user name
in the payload:
{
"name": "Eduard Lupacescu"
}
Since the payload is valid now, Restify will update the user's profile (a name, in our case):
{
"id": "7",
"type": "users",
"attributes": {
"name": "Eduard Lupacescu",
"email": "interstelar@me.com"
},
"meta": {
"authorizedToShow": true,
"authorizedToStore": true,
"authorizedToUpdate": true,
"authorizedToDelete": true
}
}
Update without repository
If you don't use the repository for the user's profile, Restify will only
update the fillable
user attributes that are present in the request payload: $request->only($user->getFillable())
.
PUT: /api/restify/profile
Payload:
{
"name": "Eduard Lupacescu"
}
The response will be the updated user:
{
"data": {
"id": 7,
"name": "Eduard",
"email": "interstelar@me.com",
"email_verified_at": null,
"created_at": "2020-12-24T08:49:30.000000Z",
"updated_at": "2020-12-24T09:34:48.000000Z"
}
}
User avatar
To prepare your users for avatars, you can add the avatar
column in your users' table:
// Migration
public function up()
{
Schema::table('users', function( Blueprint $t) {
$t->string('avatar')->nullable();
});
}
Now, you should specify in the user repository that the user has an avatar file:
use Binaryk\LaravelRestify\Fields\Image;
public function fields(RestifyRequest $request)
{
return [
field('name')->rules('required'),
field('avatar')->image()->storeAs('avatar.jpg')
];
}
You can use the Restify's profile update and give the avatar as an image.
Post request
You cannot upload a file by using PUT or PATCH verbs, so we should use a POST request instead.
POST: /api/restify/profile
The payload should be a form-data, with an image under the avatar
key:
{
"avatar": "binary image in form data request"
}
If you have to customize the path or disk of the storage file, check the image field