Support for Relay Connection spec

Is it possible to support relay connection spec via GraphQL ?
https://relay.dev/graphql/connections.htm

For my schema I have a slight variation of the same to support a hybrid connection definition as supported by GitHub GraphQL APIs. Also I want to able to map Relation properties to each ThingEdge properties

 # A connection to a list of Things.
type ThingConnection {
  # Information to aid in pagination.
  pageInfo: PageInfo # this is built based on what is returned

  # A list of Things.
  nodes: [Thing] # if clients do not want to access the edge properties they will use this

  # A list of Thing edges.
  edges: [ThingEdge] # each edge will have a Thing Node and a cursor to itself

  # Count of filtered result set without considering pagination arguments.
  totalCount: Int! # mapped to cypher that fetches the totalCount
}

type ThingEdge {
   # The node that is connected to this edge/relationship
   node: Thing
   # cursor information about this node
   cursor: String
   # Some props of the edge
   created: Date
   # Some props of the edge
   createdBy: UserId
   # Some props of the edge
  # sequence: Int
}
# Information about the current page of results fetched via a connection.
type PageInfo {
    # When paginating backwards, are there more items?
    hasPreviousPage: Boolean!
    # When paginating forwards, are there more items?
    hasNextPage: Boolean!
    # When paginating backwards, the cursor to continue
    startCursor: String
    # When paginating forwards, the cursor to continue
    endCursor: String
}

Hi @soneymathew,

We do support pagination in GraphQL but our spec differs from Relay’s GraphQL Cursor Connections Specification. The current way we support pagination is similar to how pagination is done in Graphql±.
For example, fetching names of first 5 friends in sorted order of name with some offset (next page)

query {
...

    friend (order: {desc: name@.},  first: 5, offset: 5) {
      name
    }
...

We would love your feedback on this to make our spec more developer friendly.

1 Like

I was wondering if it is possible to achieve the same outcome using
Custom resolvers? https://graphql.dgraph.io/doc/custom/

It may be possible. But what’s the use case you want to serve by writing your own custom resolver? Pagination is already supported for edges at any level.

Is there some use case for which the current pagination in Dgraph’s graphql doesn’t suffice?

Also, please mark this resolved if my previous answer suffices.

When building pagination experiences there are a few nuances I have encountered. I am evaluating Dgraph for the three patterns I need, The schema definition defined above enables me to cater to all my needs, I am trying to determine if the same schema can be achieved via DGraph GraphQL API.
It’s unclear to me how I can achieve parity with the schema needs detailed above.

Pagination patterns I am interested in

Pagination with offsets

image

  • How do I determine if there is a next/prev page? (To enable/Disable the Prev/Next) control
  • How do I get the totalCount of the edges to be able to show Page 1 of 20

Load more

  • Looks like I can use after param to achieve this (is my understanding correct that this acts as a cursor?)

Infinite scrolling

  • This is just load more pattern in steroids but needs totalCount to be able to determine the scroll height/limits

Is it possible to use GraphQL± techniques to be able to satisfy the above schema definition?

{
  total (func:  anyofterms(name@., "Michael Catalina"))  {
    count(uid) # perhaps this is the way to get totalCount? How to map this to GraphQL?
  }
  everyone(func: anyofterms(name@., "Michael Catalina"), offset: 10, first: 10, after: 0) { 
    name
    friend {
      name@ru:ko:en
    }
  }
}

I see GraphQL± is able to go far with being able to get totalCount but I would really love to enable the other good practices that are part of the the relay spec into my schema it also enables me to use the relay client directly.

The below image explains the pagination algorithm used to determine the edges per connection spec when fetching the 2nd page from a collection of 100 edges with page size 10. Really keen to learn if this can be achieved :pray:

1 Like

All of this can be achieved if we just had the total count with graphql. Maybe with a @count directive. :wink:

Keep UI track of offset and first. In my UI I have also added UI tracking of a page variables.

# I am using React...
const [offset, setOffset] = useState(0)
const [limit, setLimit] = useState(25)
const page = offset+first/first

I then create a setPage function that takes a page number:

const setPage(page) => {
  setOffset(page*first - first)
}

Then use these function in the UI and send the first/offset to the query.

1 Like

@Rahul please can you share your thoughts on this requirement?

Hello @gja / @akashjain971 ,

Is there a possibility to use dgraph-lambda
to support the Hybrid Connection discussed in this topic? :pray:

Thanks,
Soney

@soneymathew you could get something to work with a similar syntax, but it wouldn’t be a true cursor. Since this post, we now support counts in graphql (Release Notes v20.11.0 - Tenacious T'Challa), so you may not need to use lambdas.

1 Like