All Versions
252
Latest Version
Avg Release Cycle
21 days
Latest Release
1386 days ago

Changelog History
Page 19

  • v1.4.1 Changes

    January 16, 2017

    ๐Ÿ› Bug fixes

    • Absent variables aren't present in args #479
    • ๐Ÿ›  Fix grouped ActiveRecord relation with last only #476
    • 0๏ธโƒฃ Schema#default_mask & query only:/except: are combined, not overriden #485
    • Root types can be hidden with dynamic filters #480
  • v1.4.0 Changes

    January 08, 2017

    ๐Ÿ’ฅ Breaking changes

    ๐Ÿ—„ Deprecations

    • One-argument schema filters are deprecated. Schema filters are now called with two arguments, (member, ctx). #463 To update, add a second argument to your schema filter.
    • โšก๏ธ The arity of middleware #call methods has changed. Instead of next_middleware being the last argument, it is passed as a block. To update, call yield to continue the middleware chain or use &next_middleware to capture next_middleware into a local variable.
      # Previous:
      def call(*args, next_middleware)
        next_middleware.call
      end
    
      # Current
      def call(*args)
        yield
      end
      # Or
      def call(*args, &next_middleware)
        next_middleware.call
      end
    

    ๐Ÿ†• New features

    • You can add a nodes field directly to a connection. #451 That way you can say { friends { nodes } } instead of { freinds { edges { node } } }. Either pass nodes_field: true when defining a custom connection type, for example:
      FriendsConnectionType = FriendType.define_connection(nodes_field: true)
    

    Or, set GraphQL::Relay::ConnectionType.default_nodes_field = true before defining your schema, for example:

      GraphQL::Relay::ConnectionType.default_nodes_field = true
      MySchema = GraphQL::Schema.define { ... }
    
    • ๐ŸŽ Middleware performance was dramatically improved by reducing object allocations. #462 next_middleware is now passed as a block. In general, yield is faster than calling a captured block.
    • ๐Ÿ‘Œ Improve error messages for wrongly-typed variable values #423
    • Cache the value of resolve_type per object per query #462
    • Pass ctx to schema filters #463
    • Accept whitelist schema filters as only: #463
    • โž• Add Schema#to_definition which accepts only:/except: to filter the schema when printing #463
    • โž• Add Schema#default_mask as a default except: filter #463
    • โž• Add reflection methods to types #473
      • #introspection? marks built-in introspection types
      • #default_scalar? marks built-in scalars
      • #default_relay? marks built-in Relay types
      • #default_directive? marks built-in directives

    ๐Ÿ› Bug fixes

    • ๐Ÿ›  Fix ArrayConnection: gracefully handle out-of-bounds cursors #452
    • ๐Ÿ›  Fix ArrayConnection & RelationConnection: properly handle last without before #362
  • v1.3.0 Changes

    December 08, 2016

    ๐Ÿ—„ Deprecations

    • ๐Ÿ—„ As per the spec, __ prefix is reserved for built-in names only. This is currently deprecated and will be invalid in a future version. #427, #450

    ๐Ÿ†• New features

    • Schema#lazy_resolve allows you to define handlers for a second pass of resolution #386
    • Field#lazy_resolve can be instrumented to track lazy resolution #429
    • Schema#type_error allows you to handle InvalidNullErrors and UnresolvedTypeErrors in your own way #416
    • Schema#cursor_encoder can be specified for transforming cursors from built-in Connection implementations #345
    • Schema members #dup correctly: they shallowly copy their state into new instances #444
    • Query#provided_variables is now public #430

    ๐Ÿ› Bug fixes

    • Schemas created from JSON or strings with custom scalars can validate queries (although they still can't check if inputs are valid for those custom scalars) #445
    • ๐Ÿ‘ Always use quirks_mode: true when serializing values (to support non-stdlib JSONs) #449
    • Calling #redefine on a Schema member copies state outside of previous #define blocks (uses #dup) #444
  • v1.2.6 Changes

    December 01, 2016

    ๐Ÿ› Bug fixes

    • Preserve connection behaviors after redefine #421
    • Implement respond_to_missing? on DefinedObjectProxy (which is self inside .define { ... }) #414
  • v1.2.5 Changes

    November 22, 2016

    ๐Ÿ’ฅ Breaking changes

    • Visitor received some breaking changes, though these are largely-private APIs (#401):
      • Global visitor hooks (Visitor#enter and Visitor#leave) have been removed
      • Returning SKIP from a visitor hook no longer skips sibling nodes

    ๐Ÿ†• New features

    • Schema#instrument may be called outside of Schema.define #399
    • Validation: assert that directives on a node are unique #409
    • instrument(:query) hooks are executed even if the query raises an error #412

    ๐Ÿ› Bug fixes

    • Mutation#input_fields should trigger lazy definition #392
    • ObjectType#connection doesn't modify the provided GraphQL::Field #411
    • Mutation#resolve may return a GraphQL::ExecutionError #405
    • Arguments can handle nullable arguments passed as nil #410
  • v1.2.4 Changes

    November 14, 2016

    ๐Ÿ› Bug fixes

    • ๐Ÿ–จ For invalid enum values, print the enum name in the error message (not a Ruby object dump) #403
    • ๐Ÿ‘Œ Improve detection of invalid UTF-8 escapes #394
  • v1.2.3 Changes

    November 14, 2016

    ๐Ÿ› Bug fixes

    • Lexer previous token should be a local variable, not a method attribute #396
    • Arguments should wrap values according to their type, not their value #398
  • v1.2.2 Changes

    November 07, 2016

    ๐Ÿ†• New features

    • Schema.execute raises an error if variables: is a string

    ๐Ÿ› Bug fixes

    • Dynamic fields __schema, __type and __typename are properly validated #391
  • v1.2.1 Changes

    November 07, 2016

    ๐Ÿ› Bug fixes

    • ๐Ÿ‘ Implement Query::Context#strategy and FieldResolutionContext#strategy to support GraphQL::Batch #382
  • v1.2.0 Changes

    November 07, 2016

    ๐Ÿ’ฅ Breaking changes

    • A breaking change from 1.1.0 was reverted: two-character "\\u" is longer treated as the Unicode escape character #372

    • Due to the execution bug described below, the internal representation of a query has changed. Although Node responds to the same methods, tree is built differently and query analyzers visit it differently. #373, #379

    The difference is in cases like this:

      outer {
        ... on A { inner1 { inner2 } }
        ... on B { inner1 { inner3 } }
      }
    

    Previously, visits would be:

    • outer, which has one child:
      • inner1, which has two definitions (one on A, another on B), then visit its two children:
        • inner2 which has one definition (on the return type of inner1)
        • inner3 which has one definition (on the return type of inner1)

    This can be wrong for some cases. For example, if A and B are mutually exclusive (both object types, or union types with no shared members), then inner2 and inner3 will never be executed together.

    Now, the visit goes like this:

    • outer which has two entries in typed_children, one on A and another on B. Visit each typed_chidren branch:
      • inner1, then its one typed_children branch:
        • inner2
      • inner1, then its one typed_children branch:
        • inner3

    As you can see, we visit inner1 twice, once for each type condition. inner2 and inner3 are no longer visited as siblings. Instead they're visited as ... cousins? (They share a grandparent, not a parent.)

    Although Node#children is still present, it may not contain all children actually resolved at runtime, since multiple typed_children branches could apply to the same runtime type (eg, two branches on interface types can apply to the same object type). To track all children, you have to do some bookkeeping during visitation, see QueryComplexity for an example.

    You can see PR #373 for how built-in analyzers were changed to reflect this.

    ๐Ÿ—„ Deprecations

    • ๐Ÿ—„ InternalRepresentation::Node#children and InternalRepresentation::Node#definitions are deprecated due to the bug described below and the breaking change described above. Instead, use InternalRepresentation::Node#typed_children and InternalRepresentation::Node#defininition. #373

    ๐Ÿ†• New features

    • 0๏ธโƒฃ null support for the whole library: as a query literal, variable value, and argument default value. To check for the presence of a nullable, use Arguments#key? #369

    • GraphQL::Schema::UniqueWithinType.default_id_separator may be assigned to a custom value #381

    • Context#add_error(err) may be used to add a GraphQL::ExecutionError to the response's "errors" key (and the resolve function can still return a value) #367

    • The third argument of resolve is now a FieldResolutionContext, which behaves just like a Query::Context, except that it is not modified during query execution. This means you can capture a reference to that context and access some field-level details after the fact: #path, #ast_node, #irep_node. (Other methods are delegated to the underlying Query::Context) #379

    • TimeoutMiddleware's second argument is a proxied query object: it's #context method returns the FieldResolutionContext (see above) for the timed-out field. Other methods are delegated to the underlying Query #379

    ๐Ÿ› Bug fixes

    • ๐Ÿ›  Fix deep selection merging on divergently-typed fragments. #370, #373, #379 Previously, nested selections on different fragments were not distinguished. Consider a case like this:
      ... on A { inner1 { inner2 } }
      ... on B { inner1 { inner3 } }
    

    Previously, an object of type A would resolve inner1, then the result would receive both inner2 and inner3. The same was true for an object of type B.

    Now, those are properly distinguished. An object of type A resolves inner1, then its result receives inner2. An object of type B receives inner1, then inner3.