- Stable connections: Fix using startCursor / endCursor without nodes #3752
- Stable Connections: Properly handle cursors containing invalid JSON #3735
- Operation Store sync: ActiveRecord backend performance improvements: when syncing operations, only validate newly-added operations, reduce allocations when normalizing incoming query strings
- Operation Store sync: fix when operations are re-synced with new aliases
- Operation Store: Use Rails
insert_all
for better performance when adding new operations
- Pundit and CanCan integrations: Add
ResolverIntegration
modules for plain resolvers #3392
- OperationStore Redis backend: pipeline updates to last_used_at values #3672
- OperationStore: fix a stack overflow error on GraphQL 1.9 #3653
- Dashboard: add a component for GraphQL-Enterprise rate limiters
- Stable cursors: raise an error on unrecognized orderings instead of ignoring them #3605
- Stable cursors: Handle
Arel::Attributes::Attribute
andArel::SqlLiteral
#3605
- Stable connections: nicely handle incoming cursors with too many sort values #3581
- Stable connections: improve handling of
SELECT
withCASE
#3558 - Defer: fix to support runtime wrapper objects in graphql-ruby 1.12.13
- Ably subscriptions: send
quickAck: true
for a faster response from Ably
- Defer: support dataloader inside deferred blocks
- Defer: support
label:
argument which is returned in the patch for that deferral #3454
- Dashboard: fix stack error when OperationStore isn't configured on a class-based schema
- Stable Connections: When using aliases and GROUP BY, replace the alias when building a HAVING condition.
- Pundit integration: Add a
use_owner_role(true)
configuration option
- Stable Connections: Re-select aliased fields that are referenced by ORDER BY. #3421
- Pundit integration: properly halt when
unauthorized_by_pundit
returns errors-as-data after a mutation argument fails authorization #3384
- Pundit, CanCan integrations: properly call configured auth hooks for arguments that are lists and input objects
- Fix OperationStore assignment on GraphQL-Ruby 1.9
- Subscriptions: change the default
cleanup_delay_s:
to 5 seconds (usecleanup_delay_s: 0
to get the old behavior)
- Subscriptions: Handle unsubscribe race condition #3357
- CanCan integration: support
can_can_subject:
config for overriding the use ofobject
as the CanCan subject #3350
- Subscriptions: Support
Redis::Namespace
without deprecation warnings forscript load
#3347
- Stable connections: implement
range_add_edge
to leverage GraphQL-Ruby 1.12.5's improved RangeAdd #2184
- Defer: Update to work with Dataloader
- Subscriptions: Use
MULTI
instead of Lua for some operations - Subscriptions: Use
EVAL_SHA
for duplicate scripts to reduce network overhead #3285 - Subscriptions: Don't use
redis.call
, which is unsupported in theredis-namespace
gem #3322
- Stable Relation Connection: Don't emit
OR ... IS NULL
for columns that are known to benull: false
(this improves index utilization)
- Pusher subscriptions:
context[:compress_pusher_payload] = true
will cause the payload to be gzipped before being sent to Pusher
- Subscriptions: don't generate keys inside Lua scripts (for redis-namespace compatibility, and probably better support for Redis cluster) #3307
- OperationStore: add
OperationStore::AddOperationBatch.call
for adding data directly - Subscriptions: use Lua scripts for more efficient Redis access
- Updates for 1.12.0 compatibility
- OperationStore: improve performance by batching reads and writes during updates
- Subscriptions: Add
stale_ttl_s:
andcleanup_delay_s:
to customize persistence in Redis #3252
- Fix duplicate calls to
Argument#authorized?
in CanCan and Pundit integrations #3242
- Ably Subscriptions:
cipher_base:
sets up end-to-end encryption
- Encoder: fix Ruby 2.7 warning #3161
- Stable connections: Handle
ARRAY[...]
selections and cursors on Postgres #3166 - Pundit: properly lookup policies for list inputs #3146
- Stable Connections: Use method access to get
.cursor_#{idx}
values instead of.attributes[:cursor_#{idx}]
, fixes #3149
- Stable Connections: use
.to_sql
to handle orderings that use complex Arel expressions (#3109)
- Pundit: add
pundit_policy_class_for(object, context)
andpundit_role_for(object, context)
for custom runtime lookups
- Subscriptions: don't send empty updates when subscriptions return
:no_update
- OperationStore: improve handling of archived operations in index views
(Oops, bad release!)
-
OperationStore: Store & display
last_used_at
for operation store clients and operations. To upgrade, add the column to your ActiveRecord table:add_column :graphql_client_operations, :last_used_at, :datetime
(It works out-of-the-box with the Redis backend.)
You can opt out of this feature by adding
use GraphQL::Pro::OperationStore, ... default_touch_last_used_at: false
to your schema setup. -
OperationStore: Add archive/unarchive workflow for operations. To upgrade, add the column to your table:
add_column :graphql_client_operations, :is_archived, :boolean, index: true
(It works out-of-the-box with the Redis backend.)
-
OperationStore: Fix indexing of enum values
- CanCan: Accept
can_can_attribute:
configuration, which is passed as the third input to.can?(...)
- Add PubnubSubscriptions
- Update subscription implementations to support
broadcast: true
when available
- More Ruby 2.7 warning fixes
- Return the proper
pageInfo
values when it's requested beforeedges
ornodes
(#2972)
- Fix some warnings on Ruby 2.7
- StableRelationConnection: properly return
hasNextPage: true
whenbefore
andmax_page_size
are used.
GraphQL::Pro::OperationStore::Migration
can be used to copy persisted operations from one backend to another (eg, ActiveRecord to Redis). See the source file,lib/graphql/pro/operation_store/migration.rb
for docs.
GraphQL::Pro::Subscriptions
is deprecated; useGraphQL::Pro::PusherSubscriptions
instead which works the same, but better (see below). This new name avoids confusion with the later-addedAblySubscriptions
.
GraphQL::Pro::PusherSubscriptions
replacesGraphQL::Pro::Subscriptions
and adds orphaned record cleanup. (No more dangling records in Redis.)
- Use
nonce: true
when working with cursors in new stable connections
- OperationStore supports a
redis:
backend - OperationStore supports an arbitrary
backend_class:
for persistence operations
- Use a loop when clearing Redis subscription state to avoid large stack traces #2701
- Handle empty subscription keys when publishing updates #2061
- Improve backwards compat with OperationStore (Improve adding
.tracer
, use.graphql_name
when indexing)
- Fix OperationStore on class-based schemas with query instrumenters that use the query string
GraphQL::Pro::Monitoring
is deprecated; see Tracing for a replacement: https://graphql-ruby.org/queries/tracing.htmlGraphQL::Pro::Repository
is deprecated; see OperationStore for a replacement: https://graphql-ruby.org/operation_store/overview.html
- New stable connection support based on GraphQL-Ruby 1.10's new pagination implementation. New classes provide better handling of
NULL
values in order-by columns and they can be applied on a field-by-field basis(GraphQL::Pro::SqliteStableRelationConnection
,GraphQL::Pro::MySQLStableRelationConnection
,GraphQL::Pro::PostgresStableRelationConnection
).
- Add the Access query analyzer to class-based schemas
- Forwards-compatibility for graphql 1.10.0
- Support 1.10.0.pre1's input object argument
loads:
authorization
- Continue authorizing input object arguments
- Use millisecond-aware string format for datetimes in cursors
- Support multiple subscriptions in one document
- Support custom
#can_can_ability
methods on query context for CanCanIntegration - Support custom
#pundit_user
method on query context for PunditIntegration
- Fix off-by-one error when paginating backwards from the last item in a stable relation connection
- Include expected HMAC digest in OperationStore debug output
- Include content-length and content-type headers in OperationStore JSON responses
- Support stable connections ordered by Arel SQL literals
- Support stable connections on realized views (which don't have primary keys)
- Pundit integration: support
pundit_policy_class
String names when scoping connections
- Add
GraphQL::Pro::Defer
, implementing@defer
for streaming responses
- Pundit integration: correctly authorize fields when Query root is nil
- Pundit integration: use overriden
pundit_policy_class
for scoping and mutation authorization
- Pundit integration: Fields use the owner's configured
pundit_policy_class
if there is one - Pundit integration: avoid conflicts with
#initialize
for schema classes that don't need it
- Support inheritance with
pundit_policy_class(...)
- Support
pundit_policy_class(...)
andpundit_policy_class:
to manually specify a class or class name.
- Inject
context
into policy lookup hooks instead of just the user
- Extract
pundit_policy
andscope_by_pundit_policy
hooks for user override
- Properly render subscription context in dashboard
- Don't pass arrays to Pundit scopes (fixes rmosolgo#2008)
- Prepare for future compat with graphql-ruby 1.9
- Include table name when adding a default order-by-id to ActiveRecord Relations
- Raise if a required cursor attribute is missing
- Improve
rake routes
output for operation store endpoint - Support already-parsed queries in subscription RedisStorage
- Derp, remove the dummy app's
.log
files from the gem bundle - Fix ordering bug when a SQL function call doesn't have an explicit order
- Fix Pusher reference in AblySubscriptions
- Add
GraphQL::Pro::AblySubscriptions
for GraphQL subscriptions over Ably.io transport
- Support
NULLS LAST
in stable cursors
- Improve operation store models to work when
config.active_record.primary_key_prefix_type
is set
- Support Rails 3.2 with OperationStore
- Use
.select
to filter items in CanCanIntegration
- Properly send an ability and the configured
can_can_action
to.accessible_by
- Use a string (not integer) for
Content-Length
header in the dashboard
-
PunditIntegration
: instead of raisingMutationAuthorizationFailed
when an argument fails authorization, it will send aGraphQL::UnauthorizedError
to yourSchema.unauthorized_object
hook. (This is what all other authorization failures do.) To retain the previous behavior, in your base mutation, add:def unauthorized_by_pundit(owner, value) # Raise a runtime error to halt query execution raise "#{value} failed #{owner}'s auth check" end
Otherwise, customize the handling of this behavior with
Schema.unauthorized_object
.
- Auth: mutation arguments which have authorization constraints but don't load an object from the database will have mutation instance passed to the auth check, not the input value.
- Add
GraphQL::Pro::CanCanIntegration
which leverages GraphQL-Ruby's built-in auth
PunditIntegration
: Don't try to authorize loaded objects when they'renil
- Update
PunditIntegration
for arguments, unions, interfaces and mutations
- Add a new
PunditIntegration
which leverages the built-in authorization methods
- Authorization: fix scoping lists of abstract type when there's no
#scope
method on the strategy
- Fix ordering of authorization field instrumenter (put it at the end, not the beginning of the list)
- Authorization: Add
view
/access
/authorize
methods toGraphQL::Schema::Mutation
- Authorization: when a
fallback:
configuration is given, apply it to each field which doesn't have a configuration of its own or from its return type. Don't apply that configuration at schema level (it's applied to each otherwise uncovered field instead).
- Support Mongoid::Criteria in authorization scoping
- Fix authorization code for when
ActiveRecord
is not defined
- Use a more permissive regexp (
/^\s*((?:[a-z._]+)\(.*\))\s*(asc|desc)?\s*$/im
) to parse SQL functions
- Fix route helpers to support class-based schemas
- Support
1.8-pre
versions of GraphQL-Ruby
- Fix OperationStore when other query instrumenters need
.query_string
- Support
LEAST(...)
in stable cursors
- Support
CASE ... END
in stable cursors
- Support
FIELD(...)
in stable cursors
- Improve detection of
OperationStore
for the dashboard - Serve
Content-Type
andContent-Length
headers with dashboard pages - Better
Dashboard#inspect
for Rails routes output - Use a string to apply order-by-primary-key for better Rails 3 support
- Support
composite_primary_keys
gem
GraphQL::Pro::UI
renamed toGraphQL::Pro::Dashboard
- Routing method
.ui
was renamed to.dashboard
- Added
GraphQL::Pro::Subscriptions
- Added subscriptions component to Dashboard
- Don't crash when scoping lists of abstract types with Pundit
- Use
authorize(:pundit, namespace: )
to lookup policies in a namespace instead of the global namespace.
- Introspection data is allowed through
fallback:
authorize:
andaccess:
filters. (It can be hidden with aview:
filter.)
- Properly return
nil
when a list of authorized objects returnsnil
- Add
authorization(..., operation_store:)
option for authorizing operation store requests
- Support
ConnectionType.bidrectional_pagination?
in stable RelationConnection
- Fix load issue when Rails is not present
-
Fix OperationStore views on PostgresQL
-
Fix stable cursors when joined tables have the same column names
Note: This is implemented by adding extra fields to the
SELECT
clause with aliases likecursor_#{idx}
, so you'll notice this in your SQL logs.
- Bump
graphql
dependency to1.6
- Routing extensions moved to
using GraphQL::Pro::Routes
- Deprecate
using GraphQL::Pro
, move extensions toGraphQL::Pro::Routes
- Add
GraphQL::Pro::OperationStore
for persisted queries with Rails
- Update
authorization
to use type-levelresolve_type
hooks
- Update authorization instrumentation for
graphql >= 1.6.5
- Fix typo in RelationConnection source
- Correctly fall back to offset-based cursors with
before:
argument
- Add
Schema#unauthorized_object(obj, ctx)
hook for failed runtime checks
- Prevent usage of
parent_role:
withview:
oraccess:
(since parent role requires a runtime check) - Fix versioned, encrypted cursors with 16-byte legacy cursors
OrderedRelationConnection
supports ordering by joined fields
- Update auth plugin for new Relay instrumenters
Pro::Encoder
supportsencoder(...)
as documented
- Fix compatibility of
RelationConnection
andRangeAdd
helper
- Add
:datadog
monitoring
ActiveRecord::Relation
s can be scoped by PunditScope
s, CanCanaccessible_by
, or custom strategy's#scope(gate, relation)
methods- Default authorization configuration can be provided with
authorization(..., fallback: { ... })
- Authorization's
:current_user
key can be customized withauthorization(..., current_user: ...)
- Serve static, persisted queries with
GraphQL::Pro::Repository
- Fix compatibility of
RelationConnection
andRangeAdd
helper
- Raise
GraphQL::Pro::RelationConnection::InvalidRelationError
when a grouped, unordered relation is returned from a field. (This relation can't be stably paginated.)
- Formally support ActiveRecord
>= 4.1.0
- Support grouped relations in
GraphQL::Pro::RelationConnection
-
Authorize fields based on their parent object, for example:
AccountType = GraphQL::ObjectType.define do name "Account" # This field is visible to all users: field :name, types.String # This is only visible when the current user is an `:owner` # of this account field :account_balance, types.Int, authorize: { parent_role: :owner } end
- Fix monitoring when
Query#selected_operation
is nil
- Add AppSignal monitoring platform
- Add type- and field-level opting in and opting out of monitoring
- Add
monitor_scalars: false
to skip monitoring on scalars
- Fix
OrderedRelationConnection
when neitherfirst
norlast
are provided (usemax_page_size
or don't limit)
OrderedRelationConnection
exposes more metadata methods:parent
,field
,arguments
,max_page_size
,first
,after
,last
,before
- When an authorization check fails on a non-null field, propagate the null and add a response to the errors key (as if the field had returned null). It previously leaked the internal symbol
__graphql_pro_access_not_allowed__
. - Apply a custom Pundit policy even when the value isn't
nil
. (It previously fell back toPundit.policy
, skipping apundit_policy_name
configuration.)
OrderedRelationConnection
exposes the underlying relation as#nodes
(likeRelationConnection
does), supporting custom connection fields.
-
CanCan integration now supports a custom
Ability
class with theability_class:
option:authorize :cancan, ability_class: CustomAbility
GraphQL::Pro
released