Skip to content

Commit 1d7c8eb

Browse files
committed
Add possibility to include and exclude arguments from generated cache key
1 parent ff48de5 commit 1d7c8eb

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

lib/graphql/fragment_cache/cache_key_builder.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,16 +130,22 @@ def path_cache_key
130130

131131
next lookahead.field.name if lookahead.arguments.empty?
132132

133-
args = lookahead.arguments.map { "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
133+
args = lookahead.arguments.select { include_argument?(_1) }.map { "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")
134134
"#{lookahead.field.name}(#{args})"
135135
}.join("/")
136136
end
137137
end
138138

139+
def include_argument?(argument_name)
140+
return false if @options[:exclude_arguments]&.include?(argument_name)
141+
return false if @options[:include_arguments] && !@options[:include_arguments].include?(argument_name)
142+
true
143+
end
144+
139145
def traverse_argument(argument)
140146
return argument unless argument.is_a?(GraphQL::Schema::InputObject)
141147

142-
"{#{argument.map { "#{_1}:#{traverse_argument(_2)}" }.sort.join(",")}}"
148+
"{#{argument.map { include_argument?(_1) ? "#{_1}:#{traverse_argument(_2)}" : nil }.compact.sort.join(",")}}"
143149
end
144150

145151
def object_cache_key

spec/graphql/fragment_cache/cache_key_builder_spec.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@
6666
end
6767

6868
specify { is_expected.to eq "graphql/cachedPost/schema_key-cachedPost(id:#{id})[id.title.author[id.name]]" }
69+
70+
context "when excluding arguments" do
71+
let(:options) { {exclude_arguments: [:id]} }
72+
73+
specify { is_expected.to eq "graphql/cachedPost/schema_key-cachedPost()[id.title.author[id.name]]" }
74+
end
75+
76+
context "when including arguments" do
77+
let(:options) { {include_arguments: [:id]} }
78+
79+
specify { is_expected.to eq "graphql/cachedPost/schema_key-cachedPost(id:#{id})[id.title.author[id.name]]" }
80+
end
6981
end
7082

7183
context "when cached field has aliased selections" do
@@ -109,7 +121,7 @@
109121

110122
specify { is_expected.to eq "graphql/cachedPostByInput/schema_key-cachedPostByInput(input_with_id:{id:#{id},int_arg:42})[id.title.author[id.name]]" }
111123

112-
context "when argument is complext input" do
124+
context "when argument is complex input" do
113125
let(:query) do
114126
<<~GQL
115127
query GetPostByComplexInput($complexPostInput: ComplexPostInput!) {
@@ -130,6 +142,18 @@
130142
let(:variables) { {complexPostInput: {stringArg: "woo", inputWithId: {id: id, intArg: 42}}} }
131143

132144
specify { is_expected.to eq "graphql/cachedPostByComplexInput/schema_key-cachedPostByComplexInput(complex_post_input:{input_with_id:{id:#{id},int_arg:42},string_arg:woo})[id.title.author[id.name]]" }
145+
146+
context "when excluding arguments" do
147+
let(:options) { {exclude_arguments: [:int_arg]} }
148+
149+
specify { is_expected.to eq "graphql/cachedPostByComplexInput/schema_key-cachedPostByComplexInput(complex_post_input:{input_with_id:{id:#{id}},string_arg:woo})[id.title.author[id.name]]" }
150+
end
151+
152+
context "when including arguments" do
153+
let(:options) { {include_arguments: [:complex_post_input, :input_with_id, :int_arg]} }
154+
155+
specify { is_expected.to eq "graphql/cachedPostByComplexInput/schema_key-cachedPostByComplexInput(complex_post_input:{input_with_id:{int_arg:42}})[id.title.author[id.name]]" }
156+
end
133157
end
134158
end
135159

spec/graphql/fragment_cache/cacher_spec.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,30 @@ def write_multi(hash, options)
118118

119119
expect(args).to eq([{query_cache_key: "1"}, {query_cache_key: "2"}])
120120
end
121+
122+
context "when different options exist, but should be excluded" do
123+
let(:schema) do
124+
build_schema do
125+
query(
126+
Class.new(Types::Query) {
127+
field :post, Types::Post, null: true do
128+
argument :id, GraphQL::Types::ID, required: true
129+
argument :cache_key, GraphQL::Types::String, required: true
130+
end
131+
132+
define_method(:post) { |id:, cache_key:|
133+
cache_fragment(cache_key: {exclude_arguments: [:cache_key]}) { Post.find(id) }
134+
}
135+
}
136+
)
137+
end
138+
end
139+
140+
it "uses #write_multi ony one time time" do
141+
execute_query
142+
expect(GraphQL::FragmentCache.cache_store).to have_received(:write_multi).once
143+
end
144+
end
121145
end
122146
end
123147

0 commit comments

Comments
 (0)