Class: ElasticGraph::SchemaDefinition::SchemaElements::TypeWithSubfields Abstract
- Inherits:
-
Struct
- Object
- Struct
- ElasticGraph::SchemaDefinition::SchemaElements::TypeWithSubfields
- Includes:
- Mixins::CanBeGraphQLOnly, Mixins::HasDerivedGraphQLTypeCustomizations, Mixins::HasDirectives, Mixins::HasDocumentation, Mixins::HasTypeInfo, Mixins::VerifiesGraphQLName
- Defined in:
- elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb
Overview
Defines common functionality for all GraphQL types that have subfields:
- InputType
- InterfaceType
- ObjectType
Direct Known Subclasses
Constant Summary
Constants included from Mixins::HasTypeInfo
Mixins::HasTypeInfo::CUSTOMIZABLE_DATASTORE_PARAMS
Instance Attribute Summary
Attributes included from Mixins::HasDocumentation
Instance Method Summary collapse
-
#deleted_field(field_name) ⇒ void
Registers the name of a field that existed in a prior version of the schema but has been deleted.
-
#field(name, type, graphql_only: false, indexing_only: false, **options) {|Field| ... } ⇒ void
Defines a GraphQL field on this type.
-
#name ⇒ String
The name of this GraphQL type.
-
#paginated_collection_field(name, element_type, name_in_index: name, singular: nil) {|Field| ... } ⇒ void
An alternative to #field for when you have a list field that you want exposed as a paginated Relay connection rather than as a simple list.
-
#relates_to_many(field_name, type, via:, dir:, singular:) {|Relationship| ... } ⇒ void
Defines a “has many” relationship between the current indexed type and another indexed type by defining a pair of fields clients can use to navigate across indexed types in a single GraphQL query.
-
#relates_to_one(field_name, type, via:, dir:) {|Relationship| ... } ⇒ void
Defines a “has one” relationship between the current indexed type and another indexed type by defining a field clients can use to navigate across indexed types in a single GraphQL query.
-
#renamed_from(old_name) ⇒ void
Registers an old name that this type used to have in a prior version of the schema.
Methods included from Mixins::HasTypeInfo
#json_schema, #json_schema_options, #mapping, #mapping_options
Methods included from Mixins::HasDerivedGraphQLTypeCustomizations
#customize_derived_type_fields, #customize_derived_types
Methods included from Mixins::HasDirectives
#directive, #directives, #directives_sdl
Methods included from Mixins::HasDocumentation
#append_to_documentation, #derived_documentation, #documentation, #formatted_documentation
Methods included from Mixins::CanBeGraphQLOnly
Methods included from Mixins::VerifiesGraphQLName
Instance Method Details
#deleted_field(field_name) ⇒ void
In situations where this API applies, ElasticGraph will give you an error message indicating that you need to use this API or Field#renamed_from. Likewise, when ElasticGraph no longer needs to know about this, it’ll give you a warning indicating the call to this method can be removed.
This method returns an undefined value.
Registers the name of a field that existed in a prior version of the schema but has been deleted.
238 239 240 241 242 243 244 245 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 238 def deleted_field(field_name) schema_def_state.register_deleted_field( name, field_name, defined_at: caller_locations(2, 1).first, # : ::Thread::Backtrace::Location defined_via: %(type.deleted_field "#{field_name}") ) end |
#field(name, type, graphql_only: false, indexing_only: false, **options) {|Field| ... } ⇒ void
Be careful about defining non-nullable fields. Changing a field’s type from non-nullable (e.g. Int!
) to nullable (e.g.
Int
) is a breaking change for clients. Making a field non-nullable may also prevent you from applying permissioning to a field
via an AuthZ layer (as such a layer would have no way to force a field value to null
when for a client denied field access).
Therefore, we recommend limiting your use of !
to only a few situations such as defining a type’s primary key (e.g.
t.field "id", "ID!"
) or defining a list field (e.g. t.field "authors", "[String!]!"
) since empty lists already provide a
“no data” representation. You can still configure the ElasticGraph indexer to require a non-null value for a field using
f.json_schema nullable: false
.
ElasticGraph’s understanding of datastore capabilities may override your configured
aggregatable
/filterable
/groupable
/sortable
options. For example, a field indexed as text
for full text search will
not be sortable or groupable even if you pass sortable: true, groupable: true
when defining the field, because text fields
cannot be efficiently sorted by or grouped on.
This method returns an undefined value.
Defines a GraphQL field on this type.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 192 def field(name, type, graphql_only: false, indexing_only: false, **) if reserved_field_names.include?(name) raise Errors::SchemaError, "Invalid field name: `#{self.name}.#{name}`. `#{name}` is reserved for use by " \ "ElasticGraph as a filtering operator. To use it for a field name, add " \ "the `schema_element_name_overrides` option (on `ElasticGraph::SchemaDefinition::RakeTasks.new`) to " \ "configure an alternate name for the `#{name}` operator." end = {name_in_index: nil}.merge() if graphql_only field_factory.call( name: name, type: type, graphql_only: graphql_only, parent_type: wrapping_type, ** ) do |field| yield field if block_given? unless indexing_only register_field(field.name, field, graphql_fields_by_name, "GraphQL", :indexing_only) end unless graphql_only register_field(field.name_in_index, field, indexing_fields_by_name_in_index, "indexing", :graphql_only) do |f| f.to_indexing_field_reference end end end end |
#name ⇒ String
Returns the name of this GraphQL type.
110 111 112 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 110 def name type_ref.name end |
#paginated_collection_field(name, element_type, name_in_index: name, singular: nil) {|Field| ... } ⇒ void
Bear in mind that pagination does not have much efficiency benefit in this case: all elements of the collection will be retrieved when fetching this field from the datastore. The pagination implementation will just trim down the collection before returning it.
This method returns an undefined value.
An alternative to #field for when you have a list field that you want exposed as a paginated Relay connection rather than as a simple list.
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 300 def paginated_collection_field(name, element_type, name_in_index: name, singular: nil, &block) element_type_ref = schema_def_state.type_ref(element_type).to_final_form element_type = element_type_ref.name schema_def_state.paginated_collection_element_types << element_type backing_indexing_field = field(name, "[#{element_type}!]!", indexing_only: true, name_in_index: name_in_index, &block) field( name, element_type_ref.as_connection.name, name_in_index: name_in_index, type_for_derived_types: "[#{element_type}]", groupable: !!singular, sortable: false, graphql_only: true, singular: singular, backing_indexing_field: backing_indexing_field ) do |f| f.define_relay_pagination_arguments! block&.call(f) end end |
#relates_to_many(field_name, type, via:, dir:, singular:) {|Relationship| ... } ⇒ void
This method returns an undefined value.
Defines a “has many” relationship between the current indexed type and another indexed type by defining a pair of fields clients can use to navigate across indexed types in a single GraphQL query. The pair of generated fields will be Relay Connection types allowing you to filter, sort, paginate, and aggregated the related data.
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 397 def relates_to_many(field_name, type, via:, dir:, singular:) foreign_key_type = (dir == :out) ? "[ID!]!" : "ID" type_ref = schema_def_state.type_ref(type).to_final_form relates_to(field_name, type_ref.as_connection.name, via: via, dir: dir, foreign_key_type: foreign_key_type, cardinality: :many, related_type: type) do |f| f.argument schema_def_state.schema_elements.filter, type_ref.as_filter_input.name do |a| a.documentation "Used to filter the returned `#{field_name}` based on the provided criteria." end f.argument schema_def_state.schema_elements.order_by, "[#{type_ref.as_sort_order.name}!]" do |a| a.documentation "Used to specify how the returned `#{field_name}` should be sorted." end f.define_relay_pagination_arguments! yield f if block_given? end aggregations_name = schema_def_state.schema_elements.normalize_case("#{singular}_aggregations") relates_to(aggregations_name, type_ref.as_aggregation.as_connection.name, via: via, dir: dir, foreign_key_type: foreign_key_type, cardinality: :many, related_type: type) do |f| f.argument schema_def_state.schema_elements.filter, type_ref.as_filter_input.name do |a| a.documentation "Used to filter the `#{type}` documents that get aggregated over based on the provided criteria." end f.define_relay_pagination_arguments! yield f if block_given? f.documentation f.derived_documentation("Aggregations over the `#{field_name}` data") end end |
#relates_to_one(field_name, type, via:, dir:) {|Relationship| ... } ⇒ void
This method returns an undefined value.
Defines a “has one” relationship between the current indexed type and another indexed type by defining a field clients can use to navigate across indexed types in a single GraphQL query.
355 356 357 358 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 355 def relates_to_one(field_name, type, via:, dir:, &block) foreign_key_type = schema_def_state.type_ref(type).non_null? ? "ID!" : "ID" relates_to(field_name, type, via: via, dir: dir, foreign_key_type: foreign_key_type, cardinality: :one, related_type: type, &block) end |
#renamed_from(old_name) ⇒ void
In situations where this API applies, ElasticGraph will give you an error message indicating that you need to use this API or API#deleted_type. Likewise, when ElasticGraph no longer needs to know about this, it’ll give you a warning indicating the call to this method can be removed.
This method returns an undefined value.
Registers an old name that this type used to have in a prior version of the schema.
262 263 264 265 266 267 268 269 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 262 def renamed_from(old_name) schema_def_state.register_renamed_type( name, from: old_name, defined_at: caller_locations(2, 1).first, # : ::Thread::Backtrace::Location defined_via: %(type.renamed_from "#{old_name}") ) end |