New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What's the best way to go about hiding fields on the transformer domain? #226
Comments
Do you mean how can you be specific about what fields you return or is there a way to filter the results based on some passed query string parameter? The former of the two is available out of the box so I'm going to presume you meant the latter and offer this solution. public function transform(User $user)
{
return $this->filterFields([
'name' => (string) $user->name,
'email' => (string) $user->email,
'age' => (int) $user->age
]);
}
protected function filterFields(array $user)
{
$fields = isset($_GET['fields']) ? explode(',', $_GET['fields']) : array_keys($user);
return array_intersect_key($user, array_flip((array) $fields));
} If no I hope this helps. |
Hm after posting that I gave it some thought and if you'd like to filter included data this solution will need some modification. |
This works well, but the global var makes tests harder. Wondering if there is any solution to that. |
I would suggest doing something like so: use League\Fractal\TransformerAbstract;
class UserTransformer extends TransformerAbstract
{
public function __construct($fields = null)
{
$this->fields = $fields;
}
public function transform(User $user)
{
return $this->transformWithFieldFilter([
'name' => (string) $user->name,
'email' => (string) $user->email,
'age' => (int) $user->age
]);
}
protected function transformWithFieldFilter($data)
{
if (is_null($this->fields)) {
return $data;
}
return array_intersect_key($data, array_flip((array) $this->fields));
}
} Then, when you use your transformer, you pass through the fields to transform: use League\Fractal;
$fields = $request->get('fields');
$resource = new Fractal\Resource\Item($book, new UserTransformer($fields)); |
For anyone who finds this via a Google search or something in the future, if you want this to work so you can pass multiple fields to an endpoint like this: /endpoint?fields=id,created_at,whatever You can adjust the above code in the following way: protected function transformWithFieldFilter($data)
{
if (is_null($this->fields)) {
return $data;
}
$fields = explode(',', $this->fields);
return array_intersect_key($data, array_flip($fields));
} |
Specifically, this param takes effect after all other transformations are complete. In other words, it's not acting on the model attributes per se, but rather on the fields displayed in the API. See thephpleague/fractal#226
Hey @philsturgeon (or anyone else). I ended up buying your book, it was a good investment. Learned quite a bit on some REST theory, and other topics too. I learned about Fractal and had a quick question.
I'm looking to hide some fields on the presentation layer, i.e. in the transformer class:
$fieldsTohide
for example without blacklisting in my model class.is it currently possible to do so in Fractal? If not, do you mind suggesting how this can be achieved?
I have a list of nested relationships that I transformer with Fractal.
Great package btw, does a lot of the transform processing for me.
The text was updated successfully, but these errors were encountered: