Skip to content

Inconsistence between CachedResourcesProcessor#process_resources vs SimpleResourcesProcessor#process_resources #31

Open
@samnang

Description

@samnang

When I start implementing caching in my app, I noticed CachedResourcesProcessor#process_resources returns an array of strings, but SimpleResourcesProcessor#process_resources returns an array of hashes.

I assume the api should expect to return an array of hashes, so that when Rails' controllers calls render in jsonapi-rails, it converts that data hash into json correctly, but if it's a string, it will to_json again on string which I don't think we want that behaviour.

Option 1

Change CachedResourcesProcessor#process_resources to return array of hash:

def process_resources
  [@primary, @included].each do |resources|
    cache_hash = cache_key_map(resources)
    processed_resources = @cache.fetch_multi(*cache_hash.keys) do |key|
      res, include, fields = cache_hash[key]
      json = res.as_jsonapi(include: include, fields: fields).to_json

      JSONString.new(json)
    end

    values = processed_resources.values.map { |json| JSON.parse(json) }
    resources.replace(values)
  end
end

Pros: Consistency API.
Cons: It's a bit slow if we do with big data because it has to convert json data back and forth.

Option 2

Change jsonapi-rails to not calling to_json again if it's already in string.

::ActionController::Renderers.add(name) do |resources, options|
  # Renderer proc is evaluated in the controller context.
  self.content_type ||= Mime[:jsonapi]

  ActiveSupport::Notifications.instrument('render.jsonapi-rails',
                                           resources: resources,
                                           options: options) do
    data = renderer.render(resources, options, self)
    data.is_a?(String) ? data : data.to_json
  end
end

Pros: It's fast because we don't need to do double works on converting json data.
Cons: Inconsistency API between CachedResourcesProcessor#process_resources vs SimpleResourcesProcessor#process_resources.

Edit: Option 2 is not working because renderer.render(resources, options, self) return jsonapi respone data hash not just data attribute.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions