Skip to content

Commit

Permalink
Correctly specify extra_fields params, attributes (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-illi authored Mar 14, 2024
1 parent d9cd4a6 commit be60453
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
1 change: 1 addition & 0 deletions app/models/graphiti/open_api/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def parameters
parameters << {'$ref': "#/components/parameters/#{type}_include"} if resource.relationships?
parameters << {'$ref': "#/components/parameters/#{type}_sort"}
parameters << {'$ref': "#/components/parameters/#{type}_fields"}
parameters << {'$ref': "#/components/parameters/#{type}_extra_fields"}
resource.query_filter_parameters.each do |parameter|
filter_name = "#{type}_#{parameter[:name]}".gsub('[', "_").gsub(']', "")
parameters << {'$ref': "#/components/parameters/#{filter_name}"}
Expand Down
18 changes: 17 additions & 1 deletion app/models/graphiti/open_api/extra_attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,27 @@ def type
schema.types[__attributes__[:type].to_sym]
end

def description
attr_desc = self[:description]&.strip
attr_desc += '.' unless attr_desc.nil? || attr_desc.end_with?('.')

extra_field_info =
<<~DESC
This *extra field* will only be present if requested explicitely with the `extra_fields[#{resource.type}]` parameter.
See [Graphiti Resource Extra fields](https://www.graphiti.dev/guides/concepts/resources#extra-fields) for more information.
DESC

[
attr_desc,
extra_field_info
].join(' ')
end

def to_property
return {} unless readable || writable

definition = type.to_schema
definition[:description] = description if description
definition[:description] = description
definition[:readOnly] = true
{name => definition}
end
Expand Down
23 changes: 22 additions & 1 deletion app/models/graphiti/open_api/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def resource_attributes
end

def readable_attributes
all_attributes.values.select(&:readable)
attributes.values.select(&:readable)
end

def sortable_attributes
Expand All @@ -75,6 +75,7 @@ def query_parameters
[].tap do |result|
result << query_include_parameter
result << query_fields_parameter
result << query_extra_fields_parameter
end + query_filter_parameters
end

Expand All @@ -92,6 +93,20 @@ def query_fields_parameter
explode: false)
end

def query_extra_fields_parameter
schema = {
description: "#{human} extra attributes list",
type: :array,
items: {'$ref': "#/components/schemas/#{type}_extra_attribute"},
uniqueItems: true,
}

query_parameter("extra_fields[#{type}]",
desc: "[Include specified extra fields of #{human} in response](https://jsonapi.org/format/#fetching-sparse-fieldsets)",
schema: schema,
explode: false)
end

def query_filter_parameter_schema(filter_spec)
type = filter_spec[:type].to_sym
if filter_spec[:single]
Expand Down Expand Up @@ -149,6 +164,7 @@ def to_parameters
"#{type}_id": path_parameter(:id, schema: {type: :string}, desc: "ID of the resource"),
"#{type}_include": query_include_parameter,
"#{type}_fields": query_fields_parameter,
"#{type}_extra_fields": query_extra_fields_parameter,
"#{type}_sort": query_sort_parameter,
}.keep_if { |name, value| value }.merge(filter_params)
end
Expand Down Expand Up @@ -281,6 +297,11 @@ def attribute_schemas
},
uniqueItems: true,
},
"#{type}_extra_attribute" => {
description: "#{human} extra attributes",
type: :string,
enum: extra_attributes.keys,
},
"#{type}_related" => {
description: "#{human} relationships available for inclusion",
type: :array,
Expand Down
21 changes: 21 additions & 0 deletions spec/models/graphiti/open_api/resource_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,25 @@
subject(:instance) { Graphiti::OpenApi::Generator.new(schema: graphiti_schema).resources.by_model("Entity") }

it { is_expected.to be_a described_class }

its(:extra_attributes) { is_expected.to include(:computational_expensive_attribute) }

context "#to_schema" do
subject(:schema) { instance.to_schema }

context "extra attribute" do
it 'property is present' do
expect(schema.dig("entities", :properties)).to be_key(:computational_expensive_attribute)
end

it 'property has "extra field" notice in description' do
description = schema.dig("entities", :properties, :computational_expensive_attribute, :description)
expect(description).to match(/will only be present if requested explicitely with the `extra_fields\[entities\]`/)
end

it 'is listed in "entities_extra_attribute" enum' do
expect(schema.dig("entities_extra_attribute", :enum)).to include(:computational_expensive_attribute)
end
end
end
end

0 comments on commit be60453

Please sign in to comment.