Laravel 5.6 - 将附加参数传递给API资源?

Won*_*nka 8 laravel-5 laravel-5.6

Laravel API资源可以是单个资源,也可以是集合.在某些情况下,需要从控制器将其他参数传递给资源/集合.下面是一个简单的示例,演示了使用User单个/集合资源的问题,以及$apple要传递给资源以进行输出的自定义参数.这个问题可以在Output (Collection)下面的最后一个中看到,对于fruit值,我们得到banana第一个用户的错误值,而不是正确的apple值(所有其他用户得到的值).它适用于单个输出,而不是集合.见下文:

带UserResource的控制器(单个)

    $user = User::first();
    return new UserResource($user, $apple = true); // $apple param passed
Run Code Online (Sandbox Code Playgroud)

带UserResource的控制器(集合)

    $users = User::limit(3)->get();
    return UserResource::collection($users, $apple = true); // $apple param passed
Run Code Online (Sandbox Code Playgroud)

UserResource

    <?php

    namespace App\Http\Resources;
    use Illuminate\Http\Resources\Json\JsonResource;

    class UserResource extends JsonResource {
        private $apple;

        public function __construct($resource, $apple = false) {
            // Ensure we call the parent constructor
            parent::__construct($resource);
            $this->resource = $resource;
            $this->apple = $apple; // $apple param passed
        }

        public function toArray($request) {
            return [
                'id'     => (int) $this->id, 
                'name'   => $this->name,
                'fruit'  => $this->apple ? 'apple' : 'banana',
            ];
        }
    }
Run Code Online (Sandbox Code Playgroud)

输出(单个)

    {
        "data": {
            "id": 1,
            "name": "Peter",
            "fruit": "apple" // correct param!
        }
    }

Run Code Online (Sandbox Code Playgroud)

输出(收集)

    {
        "data": [
            {
                "id": 1,
                "name": "Peter",
                "fruit": "banana" // INCORRECT param!
            },
            {
                "id": 2,
                "name": "Lois",
                "fruit": "apple" // correct param!
            },
            {
                "id": 3,
                "name": "Brian",
                "fruit": "apple" // correct param!
            }
        ]
    }
Run Code Online (Sandbox Code Playgroud)

请注意,这只是一个示例,它可以是任意数量的随机参数(与User集合无关,但必须为输出逻辑传递),例如read_at来自我想要传递一次的不同表的单个值时间戳,并且在输出之前在资源集合中的一些逻辑(比如与用户时间戳的比较),或者为if/else在资源文件中执行的附加逻辑传递的其他参数通常用于操纵集合的输出.如何才能做到这一点?

小智 23

这就是我在 laravel 8 上的制作方法。



class PatientResource extends JsonResource
{

  private static $data;
  /**
   * Transform the resource into an array.
   *
   * @param \Illuminate\Http\Request $request
   * @return array
   */
  public function toArray($request)
  {
    //access $data
    //self::$data
    return [
      'id' => $this->id,
      'first_name' => $this->first_name,
      'middle_name' => $this->middle_name,
      'last_name' => $this->last_name,
      'contact_number' => $this->contact_number
    ];
  }

  //I made custom function that returns collection type
  public static function customCollection($resource, $data): \Illuminate\Http\Resources\Json\AnonymousResourceCollection
  {
   //you can add as many params as you want.
    self::$data = $data;
    return parent::collection($resource);
  }
}

Run Code Online (Sandbox Code Playgroud)

然后在我的控制器上我调用了该自定义函数。

$data = PatientResource::customCollection($query->get(),$medicines);
Run Code Online (Sandbox Code Playgroud)


Won*_*nka 17

以下方法对我有用:

UserResource

class UserResource extends Resource{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return [
            'id' => $this->id,
            'name' => $this->name,
            'foo' => $this->foo,
         ];
    }

    public static function collection($resource){
        return new UserResourceCollection($resource);
    }
}
Run Code Online (Sandbox Code Playgroud)

UserCollection

class UserResourceCollection extends ResourceCollection{

    protected $foo;

    public function foo($value){
        $this->foo = $value;
        return $this;
    }

    public function toArray($request){
        return $this->collection->map(function(UserResource $resource) use($request){
            return $resource->foo($this->foo)->toArray($request);
    })->all();

        // or use HigherOrderCollectionProxy
        // return $this->collection->each->foo($this->foo)->map->toArray($request)->all()

        // or simple
        // $this->collection->each->foo($this->foo);
        // return parent::toArray($request);
    }
}
Run Code Online (Sandbox Code Playgroud)

传递附加参数的不同方法

(new UserResource($user))->foo('bar');
(new UserResourceCollection($user))->foo('bar');

UserResource::make($user)->foo('bar');
UserResourceCollection::make($users)->foo('bar');
UserResource::collection($users)->foo('bar');
Run Code Online (Sandbox Code Playgroud)

  • 我试过这个`UserResource::collection($users)-&gt;foo('bar');`但得到错误`Method Illuminate\Support\Collection::foo does not exist.` (3认同)

Sna*_*hot 11

您可以将额外的参数作为调用 API 端点的一部分传递。然后,您可以使用 UserResource 中的 $request 对象(对于您的示例)访问参数。

例如,如果您从客户端(例如 Web 浏览器、axios 等)调用端点,请使用以下内容:

http://localhost:3000/api/users?apple=true
Run Code Online (Sandbox Code Playgroud)

这将使参数 apple 的值为 true 在控制器中可用。您无需执行任何其他操作,也可以在 UserResource 的 toArray($request) 中访问它。您可以通过类似以下方式访问它:

public function toArray($request) {
      $isApple = $request->apple;

        return [
            'id'     => (int) $this->id, 
            'name'   => $this->name,
            'fruit'  => $isApple ? 'apple' : 'banana',
        ];
    }
Run Code Online (Sandbox Code Playgroud)


zar*_*pio 7

这个简单的技巧在 Laravel 5.8 中对我有用:)

控制器

$user = User::find($user->id);
$user->access_token = $tokenResult->accessToken; // Add additional data
return new ProfileResource($user);
Run Code Online (Sandbox Code Playgroud)

资源

public function toArray($request)
{
    return [
        'id'            => $this->id,
        'picture'       => $this->picture,
        'first_name'    => $this->first_name,
        'last_name'     => $this->last_name,
        'active'        => $this->active,
        'access_token'  => isset($this->access_token) ? $this->access_token : '', // Additional data
    ];
}
Run Code Online (Sandbox Code Playgroud)

  • 收藏呢?我有几个数据,我根据“all()”获取它们,然后像​​“DataResource::collection($data);”一样返回 (2认同)