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, graphql_only: false, singular: nil, groupable: !!singular,, filterable: nil, aggregatable: nil, highlightable: 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: nil, indexing_only: false) {|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:, indexing_only: false) {|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
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 is needed, 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.
437 438 439 440 441 442 443 444 445 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 437 def deleted_field(field_name) schema_def_state.register_deleted_field( name, field_name, defined_at: caller_locations(2, 1).to_a.first, # : ::Thread::Backtrace::Location defined_via: %(type.deleted_field "#{field_name}") ) nil 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 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 an ingestion validation extension to require a non-null indexed value.
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.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 201 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 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.
115 116 117 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 115 def name type_ref.name end |
#paginated_collection_field(name, element_type, name_in_index: name, graphql_only: false, singular: nil, groupable: !!singular,, filterable: nil, aggregatable: nil, highlightable: 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.
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 267 def paginated_collection_field( name, element_type, name_in_index: name, graphql_only: false, singular: nil, groupable: !!singular, filterable: nil, aggregatable: nil, highlightable: 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 unless graphql_only field(name, "[#{element_type}!]!", indexing_only: true, name_in_index: name_in_index, &block) end field( name, element_type_ref.as_connection.name, name_in_index: name_in_index, type_for_derived_types: "[#{element_type}]", graphql_only: true, singular: singular, groupable: groupable, filterable: filterable, aggregatable: aggregatable, highlightable: highlightable, sortable: false ) do |f| f.define_relay_pagination_arguments! block&.call(f) end end |
#relates_to_many(field_name, type, via:, dir:, singular: nil, indexing_only: false) {|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.
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 383 def relates_to_many(field_name, type, via:, dir:, singular: nil, indexing_only: false) foreign_key_type = (dir == :out) ? "[ID!]!" : "ID" if singular.nil? && !indexing_only raise Errors::SchemaError, "`relates_to_many` requires a `singular:` argument (used to name the aggregations field)." end 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, indexing_only: indexing_only) 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 unless indexing_only 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 end |
#relates_to_one(field_name, type, via:, dir:, indexing_only: false) {|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.
339 340 341 342 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 339 def relates_to_one(field_name, type, via:, dir:, indexing_only: false, &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, indexing_only: indexing_only, &block) end |
#renamed_from(old_name) ⇒ void
In situations where this API is needed, 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.
462 463 464 465 466 467 468 469 470 |
# File 'elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/type_with_subfields.rb', line 462 def renamed_from(old_name) schema_def_state.register_renamed_type( name, from: old_name, defined_at: caller_locations(2, 1).to_a.first, # : ::Thread::Backtrace::Location defined_via: %(type.renamed_from "#{old_name}") ) nil end |