Class: Graphlient::Query::Serializer
- Inherits:
-
Object
- Object
- Graphlient::Query::Serializer
- Includes:
- Arguments, Directives, Evaluator, Fragments, Scalars
- Defined in:
- lib/graphlient/query/serializer.rb,
lib/graphlient/query/serializer/scalars.rb,
lib/graphlient/query/serializer/arguments.rb,
lib/graphlient/query/serializer/evaluator.rb,
lib/graphlient/query/serializer/fragments.rb,
lib/graphlient/query/serializer/directives.rb
Overview
Builds a GraphQL query string from a DSL block. Composed from focused concern modules; Query is a thin public wrapper.
Defined Under Namespace
Modules: Arguments, Directives, Evaluator, Fragments, Scalars
Constant Summary collapse
- ROOT_NODES =
%w[query mutation subscription].freeze
- SPREAD_REQUIRES_NAME_OR_ON =
Raised when
spreadis called with neither a fragment name noron:. 'spread requires a fragment name (`spread :InvoiceFields`) or an inline ' \ 'type condition (`spread on: :PaidInvoice { ... }`).'.freeze
- SPREAD_NAME_TAKES_NO_BLOCK =
Raised when a named spread is given a block (a named spread has no selection set).
'a named fragment spread takes no block; for an inline fragment use ' \ '`spread on: :Type { ... }`.'.freeze
Constants included from Directives
Constants included from Fragments
Fragments::FRAGMENT_DEFINITION
Constants included from Scalars
Scalars::BUILT_IN_SCALAR_TYPES
Instance Attribute Summary collapse
-
#query_str ⇒ Object
Returns the value of attribute query_str.
Instance Method Summary collapse
-
#fragment(name, on:, &block) ⇒ Object
Inline fragment definition -- collected and appended after the main query.
-
#initialize(&block) ⇒ Serializer
constructor
A new instance of Serializer.
- #method_missing(method_name, *args, &block) ⇒ Object
- #respond_to_missing?(method_name, include_private = false) ⇒ Boolean
-
#spread(*args, on: nil, &block) ⇒ Object
Fragment spread OR inline fragment -- one consistent entry point.
-
#to_s ⇒ Object
Full output: main query string + any inline fragment definitions.
Methods included from Scalars
Constructor Details
#initialize(&block) ⇒ Serializer
Returns a new instance of Serializer.
31 32 33 34 35 36 37 |
# File 'lib/graphlient/query/serializer.rb', line 31 def initialize(&block) @indents = 0 @query_str = '' @variables = {} @fragments = {} evaluate(&block) if block end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
86 87 88 89 90 91 92 93 94 |
# File 'lib/graphlient/query/serializer.rb', line 86 def method_missing(method_name, *args, &block) if fragment?(method_name) append_node("...#{resolve_fragment_constant(method_name)}".to_sym, args, &block) elsif directive?(method_name) Directive.new(method_name, args.first || {}) else append_node(method_name, args, &block) end end |
Instance Attribute Details
#query_str ⇒ Object
Returns the value of attribute query_str.
29 30 31 |
# File 'lib/graphlient/query/serializer.rb', line 29 def query_str @query_str end |
Instance Method Details
#fragment(name, on:, &block) ⇒ Object
Inline fragment definition -- collected and appended after the main query. fragment(:InvoiceFields, on: :Invoice) { id; fee_in_cents }
81 82 83 84 |
# File 'lib/graphlient/query/serializer.rb', line 81 def fragment(name, on:, &block) body = self.class.new(&block).query_str.strip @fragments[name] = "fragment #{name} on #{on} {\n#{body}\n}" end |
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
96 97 98 |
# File 'lib/graphlient/query/serializer.rb', line 96 def respond_to_missing?(method_name, include_private = false) super end |
#spread(*args, on: nil, &block) ⇒ Object
Fragment spread OR inline fragment -- one consistent entry point.
Named fragment spread: ...FragmentName [@directive ...] spread :InvoiceFields spread :InvoiceFields, _skip(if: :x) # -> ...InvoiceFields @skip(if: $x)
Inline fragment / type condition: ... on Type [@directive ...] { fields } spread on: :PaidInvoice { amount_paid } # -> ... on PaidInvoice { amountPaid } spread on: :DraftInvoice, _skip(if: :skip) { draft_id } spread on: :Invoice # bare type condition, no block
A single verb covers both GraphQL forms; on: is the same keyword used by
fragment(name, on:), keeping the DSL consistent (and leaving room for a future
spread(:X).skip(...) chaining form without a breaking change).
69 70 71 72 73 74 75 76 77 |
# File 'lib/graphlient/query/serializer.rb', line 69 def spread(*args, on: nil, &block) directives = args.select { |a| a.is_a?(Directive) } if on append_inline_fragment(on, directives, &block) else append_named_spread(args, directives, &block) end @query_str << "\n#{indent}" end |
#to_s ⇒ Object
Full output: main query string + any inline fragment definitions.
40 41 42 43 44 |
# File 'lib/graphlient/query/serializer.rb', line 40 def to_s parts = [query_str.strip] parts.concat(@fragments.values) unless @fragments.empty? parts.join("\n\n") end |