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

Refactor JsonApi adapter in order to avoid recomputation of hashes fo… #1300

Closed
wants to merge 2 commits into from

Conversation

beauby
Copy link
Contributor

@beauby beauby commented Oct 26, 2015

…r included resources.
Ref: #1239

Plus make the method names closer to the JSON API terminology.

Main changes:

  • introduced the attributes_for method (for symmetry with relationships_for)
  • renamed relationship_value_for into linkage_for
  • computation of all hashes at once, with an annotation on each one saying whether it is a primary or included resource, so that no hash is ever computed twice, and there is not need for the serializable_hash_for_single_resource / serializable_hash_for_collection distinction. The adapter no longer calls itself recursively.
  • introduced process_resource which does the job of add_included_resources_for, included_for, primary_data_for, serializable_hash_for_single_resource, serializable_hash_for_collection (and removed those)

@bf4
Copy link
Member

bf4 commented Oct 26, 2015

Benchmark :trollface: ?

@beauby
Copy link
Contributor Author

beauby commented Oct 26, 2015

@bf4 Would love to provide one, do not have time to build the required infrastructure though. I think @joaomdmoura started to work on something though. Moreover, I think this PR is beneficial for code clarity and simplicity as well (code is now shorter and more streamlined).

end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block could also be rewritten in the following shorter form:

primary_data, included = resources.partition { |_, r| r[:is_primary] }.map { |s| s.map { |_, r| r.except(:is_primary) } }  

which I am sure @bf4 would love haha

@beauby beauby force-pushed the refactor-jsonapi branch 7 times, most recently from 6facf88 to 97b7f7e Compare October 26, 2015 08:27
@@ -44,21 +44,36 @@ def object
def initialize(serializer, options = {})
super
@include_tree = IncludeTree.from_include_args(options[:include])
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields))
@fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options[:fields])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we officially support the fieldset option? (that is, providing an instance of Fieldset, rather than a Hash of Arrays of Symbols)
It seems it was introduced only to handle the recursive call to the adapter for collections of resources (here).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @bf4

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

offhand I don't know. It's not part of the codebase I've looked much

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I'm up to remove it in a subsequent PR, as keeping it around would force us to keep the FieldSet interface constant, which we may not necessarily want.


attr_reader :fieldset
# Build the requested resource objects.
# @return [Array] [primary, included] Pair of arrays containing primary and included
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect!

@NullVoxPopuli
Copy link
Contributor

I'm unsure why the travis run is being reported as a failure. all green here: https://travis-ci.org/rails-api/active_model_serializers/builds/87493621

I'm ok to merge this.

Any objections?

@@ -39,26 +39,93 @@ def object
object
end
end

ResourceIdentifier = Struct.new(:id, :type) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be in a different file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure it can, but I wanted to see whether we liked it first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool.

so what is a ResourceIdentifier what does it represent?
(I think your answer to this should be coupled with inline comments as class header comments)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It representes a resource identifier object. But yeah, agreed, should be in the class header.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool. this link is helpful (esp since I'm new to json api)

@NullVoxPopuli
Copy link
Contributor

needs rebase, and then I'll merge

@beauby
Copy link
Contributor Author

beauby commented Nov 5, 2015

Painful rebase over.

@NullVoxPopuli
Copy link
Contributor

looks good. could you squash? :-)

@beauby
Copy link
Contributor Author

beauby commented Nov 7, 2015

@bf4 Should we put Relationship, Resource, ResourceIdentifier etc. inside ApiObjects or should we get rid of ApiObjects?

@NullVoxPopuli
Copy link
Contributor

@beauby I think it makes sense to have everything that makes up an api response document under its own namespace. ApiObjects is kind of ambiguous, though (unsure, by looking at just the ApiObjects namespace, if we are even on the server side)

What are your thoughts on ApiResponseDocument?

@bf4
Copy link
Member

bf4 commented Nov 8, 2015

I think it's a good idea to group them together

And to make clear they corresponds to object definitions inthe jsonschema

Beyond that, i'm less picky. ApiObjects describes what the are is the only argument for it

B mobile phone

On Nov 7, 2015, at 5:58 PM, L. Preston Sego III [email protected] wrote:

@beauby I think it makes sense to have everything that makes up an api response document under its own namespace. ApiObjects is kind of ambiguous, though (unsure, by looking at just the ApiObjects namespace, if we are even on the server side)

What are your thoughts on ApiResponseDocument?


Reply to this email directly or view it on GitHub.

@beauby
Copy link
Contributor Author

beauby commented Nov 8, 2015

Done.


ApiObjects::JsonApi.add!(hash)
ApiObjects::JsonApiObject.add!(hash)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I suppose that even under the ApiObjects namespace JsonApi doesn't signal it's a json object strongly enough :)

@bf4
Copy link
Member

bf4 commented Nov 9, 2015

I've only skimmed the implementation details but I really like the big picture of it!

Dunno if it's worth referencing any details in https://github.com/rails-api/active_model_serializers/pull/1301/files but the PR is relevant

@NullVoxPopuli
Copy link
Contributor

@beauby can you address @bf4's questions - I'd like to start getting all the JSON API stuff done, cause I'm running in to issues with not full compatibility on my side project.

@beauby
Copy link
Contributor Author

beauby commented Jan 19, 2016

Closing in favor of #1447.

@beauby beauby closed this Jan 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants