Next iteration of serializers
Description
I recently though that our serializers (app/serializers
) might need a next iteration with some minor refactoring.
This is how pipelines and environments serializers look like at the moment:
We have more serializers, but these are most complicated ones at the moment.
It appears that using serializers to set some constraints / extensions to ActiveRecord::Relation
objects which are passed to Serializer#represent(resource)
is a convenient thing to do.
How we use PipelinesSerializer
now:
pipelines: PipelineSerializer
.new(project: @project, user: @current_user)
.with_pagination(request, response)
.represent(@pipelines),
This represents paginated resource, but in other places of GitLab we still do not paginate pipelines, so we don't call with_pagination
on the serializer object.
The problem with this approach is that we pass @resource
after we set pagination, which means that we have to somehow memoize the pagination request, and apply pagination after this is done.
In the new environments serializer we want to sometimes group some environments into folders, it looks quite similar. But code like this:
def represent(resource, opts = {})
resource = paginate(resource) if paginated?
if itemized?
itemize(resource).map do |item|
# ...
end
else
super(resource, opts)
end
end
does not scale very well, because we have to add itemized?
, paginated?
for each condition. Would it be better to add pagination to the ActiveRecord::Relation
object once we call with_pagination
? Changing the resource
object when someone calls with_folders
might be a good solution as well.
This would mean that we should refine serializers and pass the ActiveRecord::Relation
object to the initializer and set RequestAwareEntity
parameters with method like .with_request(user: @current_user, project: @project)
.
Proposal
Refine serializers to support code like:
PipelineSerializer.new(@pipelines)
.with_request(user: @user, project: @project)
.with_pagination
.with_something_else
.represent!
Fluent interface like this may simplify the underlying implementation.
I remember @DouweM didn't like this solution when we introduced serializers in the first place, but I wonder what do you and @rymai think about it since we know a little more about serializers now, once we have few implemented already.