API Reference - Query / Subscription

query / subscription syntax

query|subscription [<op-name>] {
  object [([argument])]{
    object-fields
  }
}
Key Required Schema Description
op-name false Value Name query/subscription for observability
object true Object Name of the table/object
argument false Argument One or more of filter criteria, instructions for sort order or pagination

Example: Query

query {
  author(where: {articles: {rating: {_gte: 4}}} order_by: {name: asc}) {
    id
    name
  }
}

Example: Subscription

subscription {
  author(where: {articles: rating: {_gte: 4}}} order_by: {name: asc}) {
    id
    name
  }
}

Note

For more examples and details of usage, please see this.

query_by_pk / subscription_by_pk syntax

query|subscription [<op-name>] {
  <query-field-name> (
    column1: value1
    column2: value2
  )
  <object-fields>
}
Key Required Schema Description
op-name false Value Name query/subscription for observability
query-field-name true Value Name of the auto-generated query field, e.g. article_by_pk

Example: Query by PK

query {
  article_by_pk(id: 1) {
    id
    title
  }
}

Example: Subscription by PK

subscription {
  article_by_pk(id: 1) {
    id
    title
  }
}

Syntax definitions

Object

SimpleObject | AggregateObject

Simple object

object-name {
  field1
  field2
  json_field[(path: String)]
  ..
  nested object1
  nested object2
  aggregate nested object1
  ..
}
Key Required Schema Description
path false Value path argument of json/jsonb follows simple JSONPath specification. However, prefix symbol $. is optional.

Example

author {
   id  # scalar integer field

   name  # scalar text field

   address(path: "$.city") # scalar JSON field -> property
   address(path: "$.city.altitude") # scalar JSON field -> property -> property
   address(path: "city") # scalar JSON field -> property; '$.' prefix is optional
   contacts(path: "[0]") # scalar JSON field -> array_item
   contacts(path: "[0].phone") # scalar JSON field -> array_item_property
   contacts(path: "['Hello world!']") # scalar JSON field -> property; used for special characters key
   contacts(path: "[\"Hello world!\"]") # same as above; the syntax is ugly, but still works

   article {  # nested object
     title
   }

   article_aggregate {  # aggregate nested object
     aggregate {
       count
     }
     nodes {
       title
     }
   }
}

Aggregate object

object-name_aggregate {
  aggregate {
    count
    sum {
      field
      ..
    }
    avg {
      field
      ..
    }
    stddev {
      field
      ..
    }
    stddev_samp {
      field
      ..
    }
    stddev_pop {
      field
      ..
    }
    variance {
      field
      ..
    }
    var_samp {
      field
      ..
    }
    var_pop {
      field
      ..
    }
    max {
      field
      ..
    }
    min {
      field
      ..
    }
  nodes {
    field1
    field2
    ..
    nested object1
    nested object2
    aggregate nested object1
    ..
  }
}

(For more details on aggregate functions, refer to the Postgres docs).

Example

author_aggregate {
  aggregate {
    count  # total count
    sum {
      id  # sum aggregate on id
    }
    avg {
      id  # avg aggregate on id
    }
    stddev {
      id  # stddev aggregate on id
    }
    stddev_samp {
      id  # stddev_samp aggregate on id
    }
    stddev_pop {
      id  # stddev_pop aggregate on id
    }
    variance {
      id  # variance aggregate on id
    }
    var_samp {
      id  # var_samp aggregate on id
    }
    var_pop {
      id  # var_pop aggregate on id
    }
    max {
      id  # max aggregate on id
    }
    min {
      id  # min aggregate on id
    }
  }

  nodes {  # objects
    id  # scalar field
    name  # scalar field

    article {  # nested object
      title
    }

    article_aggregate {  # aggregate nested object
      aggregate {
        count
      }
      nodes {
        title
      }
    }
  }
}

Argument

DistinctOnExp | WhereExp | OrderByExp | PaginationExp

DistinctOnExp

distinct_on: [ TableSelectColumnEnum ]

Example

query {
  article(distinct_on: title) {
    title
    content
  }
}
TableSelectColumnEnum
#example table_select_column enum for "article" table
enum article_select_column {
  id
  title
  content
  author_id
  is_published
}

WhereExp

where: BoolExp

Example

query {
  author(where: {rating: {_gt: 4}}) {
    name
    articles {
      title
    }
  }
}
BoolExp
AndExp | OrExp | NotExp | TrueExp | ColumnExp
AndExp
{
  _and: [BoolExp]
}

Example

query {
  article(where: {_and: [{rating: {_gt: 4}}, {published_on: {_gt: "2018-01-01"}}]}) {
    title
    content
  }
}

Syntactic sugar

You can simplify an _and expression by passing the sub-expressions separated by a ,.

First example: _and expression with different fields

{
  _and: [
    { rating: { _gte: 4 } },
    { published_on: { _gte: "2018-01-01" } }
  ]
}

# can be simplified to:

{
  rating: { _gte: 4 },
  published_on: { _gte: "2018-01-01" }
}

Second example: _and expression with same field

_and: [
  {
    rating: {
      _gt: 1
    }
  },
  {
    rating: {
      _lt: 5
    }
  }
]

# can be simplified to:

rating: {
  _gt: 1,
  _lt: 5
}
OrExp
{
  _or: [BoolExp]
}

Example

query {
  article(where: {_or: [{rating: {_gt: 4}}, {is_published: {_eq: true}}]}) {
    title
    content
  }
}

Note

The _or operator expects an array of expressions as input. Passing an object to it will result in the behaviour of the _and operator due to the way GraphQL list input coercion behaves.

Example:

{
  _or: {
   rating: { _gte: 4 },
   published_on: { _gte: "2018-01-01" }
  }
}

# will be coerced to:

{
  _or: [
    {
      rating: { _gte: 4 },
      published_on: { _gte: "2018-01-01" }
    }
  ]
}

# which is equivalent to:

{
  _or: [
    _and: [
      { rating: { _gte: 4 } },
      { published_on: { _gte: "2018-01-01" } }
    ]
  ]
}
NotExp
{
  _not: BoolExp
}

Example

query {
  article(where: {_not: {title: {_eq: ""}}} ) {
    title
    content
  }
}
TrueExp
{}

Example

query {
  author(where: {articles: {}}) {
    name
  }
}

Note

{} evaluates to true whenever an object exists (even if it’s null).

ColumnExp
{
  field-name : {Operator: Value }
}

Example

query {
  article(where: {title: {_eq: "GraphQL Tutorial"}}) {
    title
    content
  }
}
Operator

Generic operators (all column types except json, jsonb):

Operator PostgreSQL equivalent
_eq =
_neq <>
_gt >
_lt <
_gte >=
_lte <=
_in IN
_nin NOT IN

(For more details, refer to the Postgres docs for comparison operators and list based search operators.)

Text related operators:

Operator PostgreSQL equivalent
_like LIKE
_nlike NOT LIKE
_ilike ILIKE
_nilike NOT ILIKE
_similar SIMILAR TO
_nsimilar NOT SIMILAR TO
_regex ~
_iregex ~*
_nregex !~
_niregex !~*

(For more details on text related operators, refer to the Postgres docs.)

Checking for NULL values:

Operator PostgreSQL equivalent
_is_null (takes true/false as values) IS NULL

(For more details on the IS NULL expression, refer to the Postgres docs.)

Type casting:

Operator PostgreSQL equivalent
_cast (takes a CastExp as a value) ::

(For more details on type casting, refer to the Postgres docs.)

JSONB operators:

Operator PostgreSQL equivalent
_contains @>
_contained_in <@
_has_key ?
_has_keys_any ?!
_has_keys_all ?&

(For more details on JSONB operators, refer to the Postgres docs.)

PostGIS related operators on GEOMETRY columns:

Operator PostGIS equivalent
_st_contains ST_Contains(column, input)
_st_crosses ST_Crosses(column, input)
_st_equals ST_Equals(column, input)
_st_intersects ST_Intersects(column, input)
_st_overlaps ST_Overlaps(column, input)
_st_touches ST_Touches(column, input)
_st_within ST_Within(column, input)
_st_d_within ST_DWithin(column, input)

(For more details on spatial relationship operators, refer to the PostGIS docs.)

Note

  • All operators take a JSON representation of geometry/geography values as input value.

  • The input value for _st_d_within operator is an object:

    {
      field-name : {_st_d_within: {distance: Float, from: Value} }
    }
    

Intersect Operators on RASTER columns:

Operator PostgreSQL equivalent Input object
_st_intersects_rast ST_Intersects(column, value) { _st_intersects_rast: raster }
_st_intersects_nband_geom ST_Intersects(column, nband, geommin) { _st_intersects_nband_geom: {nband: Integer! geommin: geometry!}
_st_intersects_geom_nband ST_Intersects(column, geommin, nband) { _st_intersects_geom_nband: {geommin: geometry! nband: Integer }

(For more details on intersect operators on raster columns refer to the PostGIS docs.)

ltree operators:

Operator PostgreSQL equivalent
_ancestor @>
_ancestor_any @>
_descendant <@
_descendant_any <@
_matches ~
_matches_any ?
_matches_fulltext @

(For more details on operators on ltree columns refer to the Postgres docs.)

CastExp
{type-name: {Operator: Value}}

Example

query MyQuery($coordinate: geography!) {
  postgis_test_table(
    where: {
      geometry_column: {
        _cast: {
          geography: { _st_d_within: { distance: 1000000, from: $coordinate } }
        }
      }
    }
  ) {
    id
  }
}

Variables:
{
  "coordinate": {
    "type": "Point",
    "coordinates": [ 2.5559, 49.0083 ]
  }
}

Note

Currently, only casting between geometry and geography types is allowed.

OrderByExp

order_by: (TableOrderBy | [ TableOrderBy ])

Example 1

query {
  author(order_by: {rating: desc}) {
    name
    rating
  }
}

Example 2

query {
  article(order_by: [{id: desc}, {author: {id: asc}}]) {
    title
    rating
  }
}

Example 3

query {
  article(order_by: [{id: desc}, {author: {id: asc}}]) {
    title
    rating
  }
}
TableOrderBy

For columns

{column: OrderByEnum}

Example

query {
  article(order_by: {rating: asc}) {
    title
    content
  }
}

For object relations

{relation-name: TableOrderBy}

Example

query {
  article(order_by: {author: {rating: desc}}) {
    title
    content
  }
}

For array relations aggregate

{relation-name_aggregate: AggregateOrderBy}

Example

query {
  author(order_by: {articles_aggregate: {max: {rating: asc}}}) {
    name
  }
}

For computed fields

Returning scalar values:

{computed-field-name: OrderByEnum}

Returning set of table rows:

{computed-field-name: TableOrderBy}
{computed-field-name_aggregate: AggregateOrderBy}

Order by type for article table:

input article_order_by {
  id: order_by
  title: order_by
  content: order_by
  author_id: order_by
  #order by using "author" object relationship columns
  author: author_order_by
  #order by using "likes" array relationship aggregates
  likes_aggregate: likes_aggregate_order_by
}

For computed fields returning scalar type

{computed-field-name: OrderByEnum}

Example

Consider a table student contains integer columns for course subjects to store marks. A computed field with the name total_marks defined to calculate sum of all subject marks. We need to fetch student rows sorted by total_marks.

query {
  student(order_by: {total_marks: desc}){
    id
    name
    total_marks
  }
}

For computed fields returning table row type

Computed fields returning set of table rows can be used to sort the query by their aggregate fields.

{computed-field-name_aggregate: AggregateOrderBy}

Example

A computed field get_articles is defined on the author table which returns set of article table rows. Fetch authors sorted by the count of their articles.

query {
  author(order_by: {get_articles_aggregate: {count: desc}}){
    id
    name
    get_articles{
      id
      title
      content
    }
  }
}
OrderByEnum
#the order_by enum type
enum order_by {
  #in the ascending order, nulls last
  asc
  #in the ascending order, nulls last
  asc_nulls_last
  #in the ascending order, nulls first
  asc_nulls_first
  #in the descending order, nulls first
  desc
  #in the descending order, nulls first
  desc_nulls_first
  #in the descending order, nulls last
  desc_nulls_last
}
AggregateOrderBy

Count aggregate

{count: OrderByEnum}

Example

query {
  author(order_by: {articles_aggregate: {count: desc}}) {
    name
  }
}

Operation aggregate

{op_name: TableAggOpOrderBy}

Example

query {
  author (order_by: {articles_aggregate: {sum: {id: desc}}}) {
    id
  }
}

Available operations are sum, avg, max, min, stddev, stddev_samp, stddev_pop, variance, var_samp and var_pop.

TableAggOpOrderBy
{column: OrderByEnum}

PaginationExp

limit: Integer
[offset: Integer]

Example

query {
  article(limit: 6, offset: 2) {
    title
    content
  }
}