rmosolgo/graphql-ruby

Question: Finding Unused Fields

Closed this issue · 2 comments

We've recently migrated to persisted queries, so we have a set list of queries that can be ran. It seems like we could loop through these queries to pull out the referenced fields then cross reference this with the fields defined in the schema to look for fields that are never used. It seems like this could be a fairly valuable process to run periodically to lens out potentially dead code. I was wondering if something like this already exists or if you had any high level guidance before I embark on a journey of discovery.

Yes, if you're sure that you only need to support traffic via GraphQL::Pro::OperationStore, you could use its "index" feature to identify unused fields. For example:

# Gather all the named schema members from the OperationStore index:
all_index_entry_names = [] 
page = 1 
per_page = 100 
while (results = MySchema.operation_store.all_index_entries(per_page: per_page, page: page).items).any? 
  all_index_entry_names.concat(results.map(&:name)
  page += 1 
end 

# Check each field against the index: 
unused_fields = [] 
MySchema.types.each do |type_name, type_defn| 
  # Only check Object and Interface types, and skip introspection types:
  if type_defn.kind.fields? && !type_defn.introspection?
    type_defn.fields.each do |field_name, field_defn| 
      field_path = field_defn.path # eg "SomeObject.someField" 
      if !all_index_entry_names.include?(field_path) 
        unused_fields << field_path 
      end 
    end 
  end 
end 

if unused_fields.any? 
  raise "Some fields are unused: #{unused_fields}" 
end 

The index also includes input types, return types, and enum values, so you could do a similar inspection on those. Want to give that a try?

Thanks! This is pure gold. The all_index_entries is exactly the ticket I was missing. I very much doubt I'll get time to get to this today, and will likely get something up and running next week. Going to consider this question answered. Thank you so much for your time.