graphql-genie
Version:
201 lines (176 loc) • 4.98 kB
Markdown
- [Connections](#connections)
- [Connection output type](#connection-output-type)
- [Examples](#examples)
# Connections
If you would rather learn by playing with a demo checkout the [client demo](https://genie-team.github.io/graphql-genie-client/). Note you can set the Data Mode to Mock in settings to have queries return demo data
If `generateConnections` is true in the generatorOptions (defaults to true) connection queries will be created for every type in the model. The name of the query will be the plural version of the type name followed by Connection.
Every query will have optional arguments `where`, `first`, `last`, `skip`, `before`, `after`. As well as identifying root fields for scalar types. These root fields are the same as doing {where: match:{}}. They are a convenience and allow some more advanced caching with [Relay](https://facebook.github.io/relay/).
For the following typedefs `citiesConnection` and `usersConnection` queries will be created.
```typescript
const typeDefs = `
type City {
id: ID! @unique
name: String!
neighborhoods: [String]
user: User
founded: Date
population: Int
}
type User {
id: ID! @unique
displayname: String @unique
email: String! @unique
address: City
}
`
const genie = new GraphQLGenie({
typeDefs,
generatorOptions: {
generateGetAll: true,
}
});
```
See the [Type Queries](https://github.com/genie-team/graphql-genie/blob/master/docs/queries.md) documentation for more on the arguments.
The main difference with connection queries is that they return a Connection rather than the type. Connections allow easier and cacheable pagination.
**Note:** You can use the @connection directive to have a field return a Connection rather than just the node. See the [SDL docs](https://github.com/genie-team/graphql-genie/blob/master/docs/sdl.md) for more info.
The Connection type follows the [Relay Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm). Reading this will give comprehensive documentation on how it works.
## Connection output type
Lets look at a the CityConnection returned by `citiesConnection` query
```graphql
"""
A connection to a list of items.
"""
type CityConnection {
"""
A list of edges.
"""
edges: [CityEdge]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo
"""
Meta information
"""
aggregate: CityAggregate
}
type CityEdge {
node: City!
cursor: String!
}
"""
Information about pagination in a connection.
"""
type PageInfo {
"""
When paginating forwards, are there more items?
"""
hasNextPage: Boolean!
"""
When paginating backwards, are there more items?
"""
hasPreviousPage: Boolean!
"""
When paginating backwards, the cursor to continue.
"""
startCursor: String
"""
When paginating forwards, the cursor to continue.
"""
endCursor: String
}
type CityAggregate {
"""
The total number that match the where clause
"""
count: Int!
}
```
## Examples
**Note: You can see a lot of examples by looking at the [tests](https://github.com/genie-team/graphql-genie/tree/master/src/tests).**
See the [setupTests](https://github.com/genie-team/graphql-genie/blob/master/src/tests/setupTests.ts) file to see the schema and then see the files in the [__tests__](https://github.com/genie-team/graphql-genie/tree/master/src/tests/__tests__) folder for many different examples.
If you wanted to query cities founded before 1990 two at a time you would do a query like this
```graphql
query filteredCities {
citiesConnection(where:
{range: {founded: [null, "1990-01-01"]}},
orderBy: {founded: ASCENDING},
first: 2) {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
name
population
founded
}
cursor
}
aggregate {
count
}
}
}
```
Which would return something like
```graphql
{
"data": {
"citiesConnection": {
"pageInfo": {
"hasNextPage": true,
"endCursor": "ID2"
},
"edges": [
{
"node": {
"name": "NY",
"population": 500000,
"founded": "1800-02-23"
},
"cursor": "ID1"
},
{
"node": {
"name": "LA",
"population": -500000,
"founded": "1988-02-23"
},
"cursor": "ID2"
}
],
"aggregate": {
"count": 12
}
}
}
}
```
Then you would check if hasNextPage is true, if so you take the endCursor and pass it as the after arugment in the next call. Like so
```graphql
query filteredCities {
citiesConnection(where:
{range: {founded: [null, "1990-01-01"]}},
orderBy: {founded: ASCENDING},
first: 2,
after: "ID2") {
pageInfo {
hasNextPage
endCursor
}
edges {
node {
name
population
founded
}
cursor
}
aggregate {
count
}
}
}
```