Skip to content

Commit 59387b9

Browse files
committed
Document filters
1 parent 73862fb commit 59387b9

File tree

1 file changed

+218
-22
lines changed

1 file changed

+218
-22
lines changed

README.md

Lines changed: 218 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,46 @@ npm install -g json-graphql-server
9696
Based on your data, json-graphql-server will generate a schema with one type per entity, as well as 3 query types and 3 mutation types. For instance for the `Post` entity:
9797

9898
```graphql
99-
type Post {
100-
id: ID!
101-
title: String!
102-
views: Int
103-
user_id: ID
104-
User: User
105-
Comments: [Comment]
106-
}
10799
type Query {
108100
Post(id: ID!): Post
109-
allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: String): [Customer]
110-
_allPostsMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: String): ListMetadata
101+
allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
102+
_allPostsMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): ListMetadata
111103
}
112104
type Mutation {
113105
createPost(data: String): Post
114106
updatePost(data: String): Post
115107
removePost(id: ID!): Boolean
116108
}
109+
type Post {
110+
id: ID!
111+
title: String!
112+
views: Int!
113+
user_id: ID!
114+
User: User
115+
Comments: [Comment]
116+
}
117+
type PostFilter {
118+
q: String
119+
id: ID
120+
title: String
121+
views: Int
122+
views_lt: Int
123+
views_lte: Int
124+
views_gt: Int
125+
views_gte: Int
126+
user_id: ID
127+
}
117128
type ListMetadata {
118129
count: Int!
119130
}
120131
```
121132

133+
By convention, json-graphql-server expects all entities to have an `id` field that is unique for their type - it's the entity primary key. The type of every field is inferred from the values, so for instance, `Post.title` is a `String!`, and `Post.views` is an `Int!`. When all entities have a value for a field, json-graphql-server makes the field type non nullable (that's why `Post.views` type is `Int!` and not `Int`).
134+
135+
For every field named `*_id`, json-graphql-server creates a two-way relationship, to let you fetch related entities from both sides. For instance, the presence of the `user_id` field in the `posts` entity leads to the ability to fetch the related `User` for a `Post` - and the related `Posts` for a `User`.
136+
137+
The `all*` queries accept parameters to let you sort, paginate, and filter the list of results. You can filter by any field, not just the primary key. For instance, you can get the posts written by user `123`. Json-graphql-server also adds a full-text query field named `q`, and created range filter fields for numeric fields. The detail of all available filters can be seen in the generated `*Filter` type.
138+
122139
## GraphQL Usage
123140

124141
Here is how you can use the queries and mutations generated for your data, using `Post` as an example:
@@ -131,6 +148,94 @@ Here is how you can use the queries and mutations generated for your data, using
131148
<tr>
132149
<td>
133150
<pre>
151+
// get a single entity, by id
152+
{
153+
Post(id: 1) {
154+
id
155+
title
156+
views
157+
user_id
158+
}
159+
}
160+
</pre>
161+
</td>
162+
<td>
163+
<pre>
164+
{
165+
"data": {
166+
"Post": {
167+
"id": 1,
168+
"title": "Lorem Ipsum",
169+
"views": 254,
170+
"user_id": 123
171+
}
172+
}
173+
}
174+
</pre>
175+
</td>
176+
</tr>
177+
<tr>
178+
<td>
179+
<pre>
180+
// include many-to-one relationships
181+
{
182+
Post(id: 1) {
183+
title
184+
User {
185+
name
186+
}
187+
}
188+
}
189+
</pre>
190+
</td>
191+
<td>
192+
<pre>
193+
{
194+
"data": {
195+
"Post": {
196+
"title": "Lorem Ipsum",
197+
"User": {
198+
"name": "John Doe"
199+
}
200+
}
201+
}
202+
}
203+
</pre>
204+
</td>
205+
</tr>
206+
<tr>
207+
<td>
208+
<pre>
209+
// include one-to-many relationships
210+
{
211+
Post(id: 1) {
212+
title
213+
Comments {
214+
body
215+
}
216+
}
217+
}
218+
</pre>
219+
</td>
220+
<td>
221+
<pre>
222+
{
223+
"data": {
224+
"Post": {
225+
"title": "Lorem Ipsum",
226+
"Comments": [
227+
{ "body": "Consectetur adipiscing elit" },
228+
{ "body": "Nam molestie pellentesque dui" },
229+
]
230+
}
231+
}
232+
}
233+
</pre>
234+
</td>
235+
</tr>
236+
<tr>
237+
<td>
238+
<pre>
134239
// get a list of entities for a type
135240
{
136241
allPosts {
@@ -156,13 +261,11 @@ Here is how you can use the queries and mutations generated for your data, using
156261
<tr>
157262
<td>
158263
<pre>
159-
// get a single entity, by id
264+
// paginate the results
160265
{
161-
Post(id: 1) {
162-
id
266+
allPosts(page: 0, perPage: 1) {
163267
title
164268
views
165-
user_id
166269
}
167270
}
168271
</pre>
@@ -171,20 +274,114 @@ Here is how you can use the queries and mutations generated for your data, using
171274
<pre>
172275
{
173276
"data": {
174-
"Post": {
175-
"id": 1,
176-
"title": "Lorem Ipsum",
177-
"views": 254,
178-
"user_id": 123
179-
}
277+
"allPosts": [
278+
{ "title": "Lorem Ipsum", views: 254 },
279+
]
280+
}
281+
}
282+
</pre>
283+
</td>
284+
</tr>
285+
<tr>
286+
<td>
287+
<pre>
288+
// sort the results by field
289+
{
290+
allPosts(sortField: "title", sortOrder: "desc") {
291+
title
292+
views
293+
}
294+
}
295+
</pre>
296+
</td>
297+
<td>
298+
<pre>
299+
{
300+
"data": {
301+
"allPosts": [
302+
{ "title": "Sic Dolor amet", views: 65 }
303+
{ "title": "Lorem Ipsum", views: 254 },
304+
]
305+
}
306+
}
307+
</pre>
308+
</td>
309+
</tr>
310+
<tr>
311+
<td>
312+
<pre>
313+
// filter the results using the full-text filter
314+
{
315+
allPosts({ filter: { q: "lorem" }}) {
316+
title
317+
views
318+
}
319+
}
320+
</pre>
321+
</td>
322+
<td>
323+
<pre>
324+
{
325+
"data": {
326+
"allPosts": [
327+
{ "title": "Lorem Ipsum", views: 254 },
328+
]
329+
}
330+
}
331+
</pre>
332+
</td>
333+
</tr>
334+
<tr>
335+
<td>
336+
<pre>
337+
// filter the result using any of the entity fields
338+
{
339+
allPosts(views: 254) {
340+
title
341+
views
342+
}
343+
}
344+
</pre>
345+
</td>
346+
<td>
347+
<pre>
348+
{
349+
"data": {
350+
"allPosts": [
351+
{ "title": "Lorem Ipsum", views: 254 },
352+
]
353+
}
354+
}
355+
</pre>
356+
</td>
357+
</tr>
358+
<tr>
359+
<td>
360+
<pre>
361+
// number fields get range filters
362+
// -lt, _lte, -gt, and _gte
363+
{
364+
allPosts(views_gte: 200) {
365+
title
366+
views
367+
}
368+
}
369+
</pre>
370+
</td>
371+
<td>
372+
<pre>
373+
{
374+
"data": {
375+
"allPosts": [
376+
{ "title": "Lorem Ipsum", views: 254 },
377+
]
180378
}
181379
}
182380
</pre>
183381
</td>
184382
</tr>
185383
</table>
186384

187-
188385
## Usage with Node
189386

190387
Install the module locally
@@ -234,7 +431,6 @@ Deploy with Heroku or Next.js.
234431

235432
## Roadmap
236433

237-
* Filtering in the `all*` queries
238434
* Client-side mocking (à la [FakeRest](https://github.com/marmelab/FakeRest))
239435
* CLI options (port, https, watch, delay, custom schema)
240436

0 commit comments

Comments
 (0)