This PR rewrites the indexer service's GraphQL query resolution layer.
The following breaking changes have been made:
If annotated with the @queryable directive, each entity type has two queries generated for it which are the entry points for querying the indexer service:
-- a query returning a singular object record, which take at most one argument that matches to a field in the entity. The chosen field must be annotated with the @search and @unique directives.
-- a query returning a Connection for the entity as described in the GraphQL Cursor Connections specification.
Input objects are now programmatically per type; this means that there is no longer general filtering and sorting behavior.
-- A connection query will allow for the use of a sort input object as long as at least one of its entity's fields is sortable.
-- A connection query will allow for the use of a filter input object as long as at least one of its entity's fields is marked with the @filter directive.
Query responses are now spec-compliant with regards to the Response Format section of the GraphQL specification.
Offset-based pagination has been retired in favor of cursor-based pagination.
-- Paginated queries require a limit (by using the first keyword) and a sort order (by using the order keyword). Requesting the next or previous "page" can be done by passing a value from a cursor field from the response as a value for either the after or before keywords, respectively.
In addition to the above, the following non-breaking changes and fixes have been made:
Adds support for connection types; these are automatically generated for an entity.
Adds a @filter directive for fields to denote which fields should be used for filtering connection queries.
Adds support for executing multiple operations in one request.
Adds proper introspection data generation for logical operators with filter input objects.
Adjusts query string generation to use Display traits.
-- Queries are modeled through types and then converted to strings at the end.
Adjusts hello-world example to be a simple explorer of blocks with lists of transactions.
Cleans up organization of fuel-indexer-graphql module.
Fixes querying for list type fields on an object.
Fixes issue with database joins not being in correct sorted order.
Moves introspection type generation from dynamic.rs to the GraphQL schema parsing step.
Reduces use of format!() calls in query generation.
Testing steps
First, build the Fuel explorer example; you can use bash scripts/utils/build_modules.bash to build all examples. Then, start the Fuel explorer example with the service (be sure to adjust the Postgres details if they differ from the following command):
Yes, this PR is quite large. However, given that the block explorer will be served by an indexer backend, we needed to support as much GraphQL functionality as we possibly can; we do not have the luxury of enshrining certain types and queries as part of our code so we need to be able to support anything that a user may feasibly create.
Description
This PR rewrites the indexer service's GraphQL query resolution layer.
The following breaking changes have been made:
@queryable
directive, each entity type has two queries generated for it which are the entry points for querying the indexer service: -- a query returning a singular object record, which take at most one argument that matches to a field in the entity. The chosen field must be annotated with the@search
and@unique
directives. -- a query returning aConnection
for the entity as described in the GraphQL Cursor Connections specification.@filter
directive.first
keyword) and a sort order (by using theorder
keyword). Requesting the next or previous "page" can be done by passing a value from acursor
field from the response as a value for either theafter
orbefore
keywords, respectively.In addition to the above, the following non-breaking changes and fixes have been made:
@skip
and@include
directives as required by the relevant section of the GraphQL specification.@filter
directive for fields to denote which fields should be used for filtering connection queries.Display
traits. -- Queries are modeled through types and then converted to strings at the end.hello-world
example to be a simple explorer of blocks with lists of transactions.fuel-indexer-graphql
module.dynamic.rs
to the GraphQL schema parsing step.format!()
calls in query generation.Testing steps
First, build the Fuel explorer example; you can use
bash scripts/utils/build_modules.bash
to build all examples. Then, start the Fuel explorer example with the service (be sure to adjust the Postgres details if they differ from the following command):Examples coming soon...
Notes
Yes, this PR is quite large. However, given that the block explorer will be served by an indexer backend, we needed to support as much GraphQL functionality as we possibly can; we do not have the luxury of enshrining certain types and queries as part of our code so we need to be able to support anything that a user may feasibly create.