63 lines
1.7 KiB
Ruby
63 lines
1.7 KiB
Ruby
|
module GraphqlOperationLogConcern
|
||
|
extend ActiveSupport::Concern
|
||
|
|
||
|
# This method parses GraphQL query and creates a short description of the query. It is useful for logging.
|
||
|
def operation_log(query, operation_name, variables)
|
||
|
return "NoQuery" if query.nil?
|
||
|
|
||
|
operation = parse_graphql_query(query, operation_name)
|
||
|
|
||
|
return "InvalidQuery" if operation.nil?
|
||
|
return "IntrospectionQuery" if operation.name == "IntrospectionQuery"
|
||
|
|
||
|
message = "#{operation.operation_type}: "
|
||
|
message += if operation.name.present?
|
||
|
"#{operation.name} { "
|
||
|
else
|
||
|
"{ "
|
||
|
end
|
||
|
message += operation.selections.map(&:name).join(', ')
|
||
|
message += " } "
|
||
|
message += if variables.present?
|
||
|
variables.flat_map do |(name, value)|
|
||
|
format_graphql_variable(name, value)
|
||
|
end
|
||
|
else
|
||
|
operation.selections.flat_map(&:arguments).flat_map do |argument|
|
||
|
format_graphql_variable(argument.name, argument.value)
|
||
|
end
|
||
|
end.join(', ')
|
||
|
|
||
|
message.strip
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def parse_graphql_query(query, operation_name)
|
||
|
operations = GraphQL.parse(query).children.filter do |node|
|
||
|
node.is_a?(GraphQL::Language::Nodes::OperationDefinition)
|
||
|
end
|
||
|
if operations.size == 1
|
||
|
operations.first
|
||
|
else
|
||
|
operations.find { |node| node.name == operation_name }
|
||
|
end
|
||
|
rescue
|
||
|
nil
|
||
|
end
|
||
|
|
||
|
def format_graphql_variable(name, value)
|
||
|
if value.is_a?(Hash)
|
||
|
value.map do |(name, value)|
|
||
|
format_graphql_variable(name, value)
|
||
|
end
|
||
|
elsif value.is_a?(GraphQL::Language::Nodes::InputObject)
|
||
|
value.arguments.map do |argument|
|
||
|
format_graphql_variable(argument.name, argument.value)
|
||
|
end
|
||
|
else
|
||
|
"#{name}: \"#{value.to_s.truncate(10)}\""
|
||
|
end
|
||
|
end
|
||
|
end
|