简体   繁体   中英

Transformer usage on laravel/dingo API

I am creating a set of REST APIs to be exposed to my mobile apps using laravel repository pattern.I am using dingo as the REST framework.I am confused on how the response for the APIs should be done using a transformer.

I have the below controller function

if(!$user) { 
    //Authenticate with Twitter and authenticate
    //Register user and issue jwt
    $user = Sentinel::register($device_details);
    $user_data = json_decode($user,true);
    $device_details['users_id'] = $user['users_id'] = $user_data['id'];
    $this->device_details->create($device_details);             
}
$token = JWTAuth::fromUser($user);
$user_array = $user->toArray();
$user_array['token'] = $token;   //An array containing user details and token
return $this->response->item($user_array, new UserTransformer)->setStatusCode(200);   //I can only pass an object (eloquent) as the #1 parameter

My Tranformer class

namespace App\Api\V1\Transformers;

use App\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract {

    public function transform(User $user)
    {
        return [
            'users_id'     => (int) $user->users_id,
            'AUTH-TOKEN'   => $user->token // Doesnt comes from database,
...
        ];
    }
}

Now my question is,

  1. I can only use eloquent objects with a tranformer?
  2. Here in this case, the token is generated by jwt library and I binded it with the array as a single user array. Now how will be able to pass this array to a presenter.
  3. The documention for fractal transformer doesn't say about passing array to the presenter.My data might not always comes from an eloquent object.
  4. How do I handle this case?
  5. Why are presenters used? I would either use a presenter or a tranformer right?

You're mixing up a couple concepts here I guess. A presenter is tied to the repository pattern, I don't see anything regarding that in your sample code but I'm assuming you're using it.

A presenter/transformer is nothing more than a layer that casts data from one structure into the other. A transformer layer is useful when you want to make sure your API always returns the same structure regardless if the underlying data object changes.

So, for clarity if you really want to follow the repository pattern the correct way to go is for the presenter to return a transformer. But don't over complicate things.

You can use whatever you want to transform, you can also transform an array into another array but then you have to make sure the parameter accepts that. For example this:

public function transform(Array $user){
    return [
        'user_id'     => (int) $user['id'],
        'auth_token'  => $user['token']
    ];
}

I see you're using Dingo and using it in Laravel 5. So try to modify your dingo response to be:

return $this->response->item($user, new UserTransformer);

Also make sure that JWTAuth::fromUser($user); can read the $user object/array that Sentinel returns.

I have check your code, Please check below code that might work for you. You have to pass $user without converting to array :

if(!$user) { 
             //Authenticate with Twitter and authenticate
            //Register user and issue jwt
            $user = Sentinel::register($device_details);
            $user_data = json_decode($user,true);
            $device_details['users_id'] = $user['users_id'] = $user_data['id'];
            $this->device_details->create($device_details);             
           }
   $token = JWTAuth::fromUser($user);
   $user_array = $user->toArray();
   $user_array['token'] = $token;   //An array containing user details and token
    $user->token = $token;
   return $this->response->item(UserTransformer::transform($user))->setStatusCode(200);   //I can only pass an object (eloquent) as the #1 parameter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM