Skip to content
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

Multiple transformers for the same model #9

Closed
jjdrake opened this issue Aug 5, 2016 · 6 comments
Closed

Multiple transformers for the same model #9

jjdrake opened this issue Aug 5, 2016 · 6 comments

Comments

@jjdrake
Copy link

jjdrake commented Aug 5, 2016

I've been using the spatie/laravel-fractal package but appreciate the built-in error formatting this package provides. I need to be able to provide one of various transformers for the same model though. Is there any reason this package appears to lock you down to a single transformer class per entity/model?

@flugg
Copy link
Owner

flugg commented Aug 5, 2016

In my own projects I usually have a one to one mapping with models and transformers, and if I want to expose different fields based on different criterias I would add some conditionals to the transform() method in the transformer. So that's basically the reasoning. However, I appreciate that others might have a need for this and will look into an elegant way of handling it.

Do you have a concrete example of where it would make sense to have multiple transformers for one model?

@jjdrake
Copy link
Author

jjdrake commented Aug 6, 2016

It may be a bit of personal preference but I've taken the approach of only sending attributes which are immediately necessary through my JSON responses and consequentially my use cases are quite varied. More concretely, I may want to respond with users' id's and usernames in one case where in another location, (or for a more privileged end-user), I may want to also send first name, last name, and email attributes.

@flugg
Copy link
Owner

flugg commented Aug 6, 2016

Yeah, that makes sense. I'm experimenting with a few options now. What do you think of being able to return an associative array in the transformer() method on the models. So for instance a User model could have 3 different transformers:

public static function transformer()
    {
        return [
            'admin' => AdminUserTransformer::class,
            'moderator' => ModeratorUserTransformer::class,
            'regular' => RegularUserTransformer::class
        ];
    }

Then I haven't decided for a good API to choose which transformer to use. Since there are already quite a lot of (optional) parameters on the success() method, I'm considering the ability to be able to chain a transformer() method on the responder:

Responder::transformer('admin')->success($users, 200);

In that case an exception would be thrown if you don't specify the transformer type. Not completely satisfied with it, I'll think about it some more over the weekend.

If you have a better suggestion, please let me know :)

@flugg
Copy link
Owner

flugg commented Aug 6, 2016

I've been experimenting some more, and decided to allow an alternative syntax to build your success responses. A bit more similar to how the spatie/laravel-fractal package works, the above example would look like this:

Responder::transform($users, 'admin')->respond(200);

You can then also be explicit and instantiate a transformer directly:

Responder::transform($users, new UserTransformer)->respond();

The success() method is also getting refactored to call on these methods behind the scene, and will basically work as a shorthand.

This alternative syntax will also allow for some control:

Responder::transform($users, 'admin')->serialize(new DataArraySerializer)->respond();
Responder::transform($users, 'admin')->respond(201, [ 'meta' => 'data' ]);
Responder::transform($users, 'admin')->toArray();
Responder::transform($users, 'admin')->toResource();

Implementing this means a bit reworking of a few core pieces of the package, but hopefully shouldn't take too long. I'll keep you posted.

@flugg
Copy link
Owner

flugg commented Aug 18, 2016

Thought I'd let you know the status of the issue. Got my hands quite full with work related stuff at the moment, but working on a major rewrite of the package to allow a more flexible way of building responses. Quite similar to the code examples above.

I'm guessing it should be done by the end of the week, perhaps a few days longer.

@flugg
Copy link
Owner

flugg commented Aug 30, 2016

Hey! Sorry for the delay, ended up being a bit more work than expected. A few parts of the package has been completely rewritten from scratch, for the better anyway. I've also gone through the documentation word for word and simplified it quite a bit. You can update to the latest version (v1.2.0+) using composer update.

You can read about the new API for explicitly transforming models here: https://github.com/flugger/laravel-responder#transformers.

Would love to hear what you think and wether or not it solves all your needs :)

@flugg flugg closed this as completed Aug 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants