Skip to content

Commit f5b8585

Browse files
committed
add dbquery filter example
1 parent 7f99aec commit f5b8585

File tree

5 files changed

+172
-28
lines changed

5 files changed

+172
-28
lines changed

dbquery/pagination/README.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ To run these examples,
1414

1515
This example uses a demo database filled with mock data, you can inspect the `config.yaml` file to find the credentials for this database.
1616

17-
1817
## GraphQL pagination
1918

2019
StepZen supports pagination through the standard [GraphQL Cursor Connection Specification](https://relay.dev/graphql/connections.htm).
@@ -63,4 +62,51 @@ Fetch the next five, the value of `after` is taken from the `endCursor` field of
6362
stepzen request -f operations.graphql --operation-name=Customers --var first=5 --var after="eyJjIjoiTDpRdWVyeTpjdXN0b21lcnMiLCJvIjo0fQ=="
6463
```
6564

65+
## GraphQL filtering
66+
67+
Filtering using a "MongoDB" inspired style for GraphQL is supported with `@dbquery` and is typically
68+
used with pagination, though it can be used alone. [Reference](https://www.ibm.com/docs/en/api-connect-graphql/saas?topic=directives-directive-dbquery#filtering__title__1)
69+
70+
The field `Query.lookup` in [`filter.graphql`](./filter.graphql) is similar to `Query.customers` but adds a `filter` argument.
71+
72+
This filter value would return all names that start with "S":
73+
74+
```json
75+
{ "name": { "like": "S%" } }
76+
```
77+
78+
This returns two customers using an OR clause:
79+
80+
```json
81+
{
82+
"or": {
83+
"name": { "eq": "John Doe" },
84+
"email": { "eq": "[email protected]" }
85+
}
86+
}
87+
```
88+
89+
### Examples
90+
91+
With no filter all customers are returned (subject to pagination)
92+
93+
```
94+
stepzen request -f operations.graphql --operation-name=Lookup
95+
```
96+
97+
With a filter then only matching customers are returned.
98+
99+
```
100+
stepzen request -f operations.graphql --operation-name=Lookup --var 'f={ "name": { "like": "S%" } }'
101+
```
102+
103+
```
104+
stepzen request -f operations.graphql --operation-name=Lookup --var first=5 --var 'f={
105+
"or": {
106+
"name": { "eq": "John Doe" },
107+
"email": { "eq": "[email protected]" }
108+
}
109+
}'
110+
```
66111

112+
Also note that `totalEdges` returns the number of customers (edges) in the connection subject to the filter.

dbquery/pagination/filter.graphql

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This shows how filtering is supported with @dbquery
2+
3+
input CustomerFilter {
4+
id: ID
5+
name: StringFilter
6+
email: StringFilter
7+
or: CustomerFilter
8+
}
9+
10+
input StringFilter {
11+
eq: String
12+
ne: String
13+
like: String
14+
ilike: String
15+
gt: String
16+
le: String
17+
}
18+
19+
extend type Query {
20+
"""
21+
`lookup` pages through mock `Customer` objects in a demo PostgreSQL database.
22+
The data is exposed using standard GraphQL pagination using the connection model.
23+
The filter argument provides a standard approach to filtering regardless of
24+
the backend and in this case is dynamically translated to SQL predicates in the `WHERE` clause.
25+
"""
26+
lookup(
27+
first: Int! = 10
28+
after: String! = ""
29+
filter: CustomerFilter
30+
): CustomerConnection
31+
@dbquery(
32+
type: "postgresql"
33+
table: "customer"
34+
schema: "public"
35+
configuration: "postgresql_config"
36+
)
37+
}

dbquery/pagination/index.graphql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
schema @sdl(files: ["api.graphql"]) {
1+
schema @sdl(files: ["api.graphql", "filter.graphql"]) {
22
query: Query
33
}
4+
5+
# this validates that the executable document is valid for the schema.
6+
# If the schema and document become out of sync then deployment will fail.
7+
extend schema @sdl(executables: { document: "operations.graphql" })

dbquery/pagination/operations.graphql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,21 @@ query Customers($first: Int!, $after: String = "") {
1414
totalEdges
1515
}
1616
}
17+
18+
# Lookup customers with filtering.
19+
query Lookup($first: Int, $after: String = "", $f: CustomerFilter) {
20+
lookup(first: $first, after: $after, filter: $f) {
21+
edges {
22+
node {
23+
id
24+
name
25+
email
26+
}
27+
}
28+
pageInfo {
29+
endCursor
30+
hasNextPage
31+
}
32+
totalEdges
33+
}
34+
}

dbquery/pagination/tests/Test.js

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,38 @@ const requestsFile = path.join(path.dirname(__dirname), "operations.graphql");
1212
const requests = fs.readFileSync(requestsFile, "utf8").toString();
1313

1414
describe(testDescription, function () {
15-
const CURSOR = "eyJjIjoiTDpRdWVyeTpjdXN0b21lcnMiLCJvIjoxfQ=="
15+
const CURSOR = "eyJjIjoiTDpRdWVyeTpjdXN0b21lcnMiLCJvIjoxfQ==";
1616

1717
const tests = [
1818
{
1919
label: "first set of results",
2020
query: requests,
2121
operationName: "Customers",
22-
variables: {
23-
first: 2
22+
variables: {
23+
first: 2,
2424
},
2525
expected: {
2626
customers: {
2727
edges: [
28-
{
29-
node: {
30-
id: "1",
31-
name: "Lucas Bill "
32-
}
28+
{
29+
node: {
30+
id: "1",
31+
name: "Lucas Bill ",
32+
},
33+
},
34+
{
35+
node: {
36+
id: "2",
37+
name: "Mandy Jones ",
38+
},
3339
},
34-
{
35-
node: {
36-
id: "2",
37-
name: "Mandy Jones "
38-
}
39-
}
4040
],
4141
pageInfo: {
4242
hasNextPage: true,
43-
endCursor: CURSOR
43+
endCursor: CURSOR,
4444
},
45-
totalEdges: 10
46-
}
45+
totalEdges: 10,
46+
},
4747
},
4848
},
4949
{
@@ -52,30 +52,69 @@ describe(testDescription, function () {
5252
operationName: "Customers",
5353
variables: {
5454
first: 2,
55-
after: CURSOR
55+
after: CURSOR,
5656
},
5757
expected: {
5858
customers: {
5959
edges: [
6060
{
6161
node: {
6262
id: "3",
63-
name: "Salim Ali "
64-
}
63+
name: "Salim Ali ",
64+
},
6565
},
6666
{
6767
node: {
6868
id: "4",
69-
name: "Jane Xiu "
70-
}
71-
}
69+
name: "Jane Xiu ",
70+
},
71+
},
7272
],
7373
pageInfo: {
7474
endCursor: "eyJjIjoiTDpRdWVyeTpjdXN0b21lcnMiLCJvIjozfQ==",
75-
hasNextPage: true
75+
hasNextPage: true,
76+
},
77+
totalEdges: 10,
78+
},
79+
},
80+
},
81+
{
82+
label: "lookup-filter",
83+
query: requests,
84+
operationName: "Lookup",
85+
variables: {
86+
first: 2,
87+
f: {
88+
or: {
89+
name: { eq: "John Doe" },
90+
email: { eq: "[email protected]" },
91+
},
92+
},
93+
},
94+
expected: {
95+
customers: {
96+
edges: [
97+
{
98+
node: {
99+
id: "5",
100+
name: "John Doe ",
101+
email: "[email protected] ",
102+
},
103+
},
104+
{
105+
node: {
106+
id: "6",
107+
name: "Jane Smith ",
108+
email: "[email protected] ",
109+
},
110+
},
111+
],
112+
pageInfo: {
113+
hasNextPage: true,
114+
endCursor: "eyJjIjoiTDpRdWVyeTpsb29rdXAiLCJvIjoxfQ==",
76115
},
77-
totalEdges: 10
78-
}
116+
totalEdges: 2,
117+
},
79118
},
80119
},
81120
];

0 commit comments

Comments
 (0)