docs: add single object mutations docs (close #4622) (#4625)

This commit is contained in:
Rakesh Emmadi 2020-05-18 16:43:57 +05:30 committed by GitHub
parent 6b5a61cff6
commit 6069cc95e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 446 additions and 66 deletions

View File

@ -65,6 +65,7 @@ Read more about the session argument for computed fields in the [docs](https://h
- cli: list all available commands in root command help (fix #4623) - cli: list all available commands in root command help (fix #4623)
- docs: add section on actions vs. remote schemas to actions documentation (#4284) - docs: add section on actions vs. remote schemas to actions documentation (#4284)
- docs: fix wrong info about excluding scheme in CORS config (#4685) - docs: fix wrong info about excluding scheme in CORS config (#4685)
- docs: add single object mutations docs (close #4622) (#4625)
- docs: add docs page on query performance (close #2316) (#3693) - docs: add docs page on query performance (close #2316) (#3693)
- docs: add a sample Caddyfile for Caddy 2 in enable-https section (#4710) - docs: add a sample Caddyfile for Caddy 2 in enable-https section (#4710)

View File

@ -14,8 +14,8 @@ API Reference - Mutation
.. _insert_upsert_syntax: .. _insert_upsert_syntax:
Insert / upsert syntax **insert** (upsert) syntax
---------------------- --------------------------
.. code-block:: none .. code-block:: none
@ -99,8 +99,8 @@ Insert / upsert syntax
.. _insert_upsert_one_syntax: .. _insert_upsert_one_syntax:
Insert / upsert one syntax **insert_one** syntax
-------------------------- ---------------------
.. code-block:: none .. code-block:: none
@ -157,11 +157,89 @@ Insert / upsert one syntax
} }
} }
.. _update_by_pk_syntax:
**update_by_pk** syntax
-----------------------
.. code-block:: none
mutation [<mutation-name>] {
<mutation-field-name> (
[pk-columns-argument!],
[set-argument!]
)
<object-fields>
}
.. list-table::
:header-rows: 1
* - Key
- Required
- Schema
- Description
* - mutation-name
- false
- Value
- Name of mutation for observability
* - mutation-field-name
- true
- Value
- Name of the auto-generated update mutation field, e.g. *update_author_by_pk*
* - pk-columns-argument
- true
- pkColumnsArgExp_
- Primary key(s) for row(s) to be updated
* - set-argument
- false
- setArgExp_
- Data to be updated in the table
* - inc-argument
- false
- incArgExp_
- Integer value to be incremented to Int columns in the table
* - append-argument
- false
- appendArgExp_
- JSON value to be appended to JSONB columns in the table
* - prepend-argument
- false
- prependArgExp_
- JSON value to be prepended to JSONB columns in the table
* - delete-key-argument
- false
- deleteKeyArgExp_
- Key to be deleted in the value of JSONB columns in the table
* - delete-elem-argument
- false
- deleteElemArgExp_
- Array element to be deleted in the value of JSONB columns in the table
* - delete-at-path-argument
- false
- deleteAtPathArgExp_
- Element at path to be deleted in the value of JSONB columns in the table
**E.g. UPDATE BY PK**:
.. code-block:: graphql
mutation update_articles {
update_article_by_pk (
pk_columns: {
id: 1
}
_set: { is_published: true }
) {
id
title
}
}
.. _update_syntax: .. _update_syntax:
Update syntax **update** syntax
------------- -----------------
.. code-block:: none .. code-block:: none
@ -238,10 +316,54 @@ Update syntax
} }
} }
.. _delete_by_pk_syntax:
**delete_by_pk** syntax
-----------------------
.. code-block:: none
mutation [<mutation-name>] {
<mutation-field-name> (
column1: value1
column2: value2
)
<object-fields>
}
.. list-table::
:header-rows: 1
* - Key
- Required
- Schema
- Description
* - mutation-name
- false
- Value
- Name of mutation for observability
* - mutation-field-name
- true
- Value
- Name of the auto-generated delete mutation field, e.g. *delete_author_by_pk*
**E.g. DELETE BY PK**:
.. code-block:: graphql
mutation delete_articles {
delete_article_by_pk (
id: 1
) {
id
title
}
}
.. _delete_syntax: .. _delete_syntax:
Delete syntax **delete** syntax
------------- -----------------
.. code-block:: none .. code-block:: none
@ -431,6 +553,29 @@ E.g.:
where: {id: {_lt: 1}} where: {id: {_lt: 1}}
} }
.. _pkColumnsArgExp:
**pk_columns** argument
^^^^^^^^^^^^^^^^^^^^^^^
The ``pk_columns`` argument is used to identify an object by its primary key columns in *update* mutations.
.. code-block:: none
pk_columns: {
column-1: value-1
column-2: value-2
}
E.g.:
.. code-block:: graphql
pk_columns: {
id: 1
name: "Harry"
}
.. _whereArgExp: .. _whereArgExp:
**where** argument **where** argument

View File

@ -12,8 +12,8 @@ API Reference - Query / Subscription
:depth: 3 :depth: 3
:local: :local:
Query / subscription syntax **query** / **subscription** syntax
--------------------------- -----------------------------------
.. code-block:: none .. code-block:: none
@ -69,6 +69,57 @@ Query / subscription syntax
For more examples and details of usage, please see :ref:`this <queries>`. For more examples and details of usage, please see :ref:`this <queries>`.
**query_by_pk** / **subscription_by_pk** syntax
-----------------------------------------------
.. code-block:: none
query|subscription [<op-name>] {
<query-field-name> (
column1: value1
column2: value2
)
<object-fields>
}
.. list-table::
:header-rows: 1
* - 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*
**E.g. QUERY BY PK**:
.. code-block:: graphql
query {
article_by_pk(id: 1) {
id
title
}
}
**E.g. SUBSCRIPTION BY PK**:
.. code-block:: graphql
subscription {
article_by_pk(id: 1) {
id
title
}
}
Syntax definitions Syntax definitions
------------------ ------------------

View File

@ -133,8 +133,11 @@ Add a table/view ``author``:
"select_by_pk": "Author", "select_by_pk": "Author",
"select_aggregate": "AuthorAggregate", "select_aggregate": "AuthorAggregate",
"insert": "AddAuthors", "insert": "AddAuthors",
"insert_one":"AddAuthor",
"update": "UpdateAuthors", "update": "UpdateAuthors",
"delete": "DeleteAuthors" "update_by_pk": "UpdateAuthor",
"delete": "DeleteAuthors",
"delete_by_pk": "DeleteAuthor"
}, },
"custom_column_names": { "custom_column_names": {
"id": "authorId" "id": "authorId"
@ -199,28 +202,40 @@ Custom Root Fields
- Description - Description
* - select * - select
- false - false
- `String` - ``String``
- Customise the ``<table-name>`` root field - Customise the ``<table-name>`` root field
* - select_by_pk * - select_by_pk
- false - false
- `String` - ``String``
- Customise the ``<table-name>_by_pk`` root field - Customise the ``<table-name>_by_pk`` root field
* - select_aggregate * - select_aggregate
- false - false
- `String` - ``String``
- Customise the ``<table-name>_aggregete`` root field - Customise the ``<table-name>_aggregete`` root field
* - insert * - insert
- false - false
- `String` - ``String``
- Customise the ``insert_<table-name>`` root field - Customise the ``insert_<table-name>`` root field
* - insert_one
- false
- ``String``
- Customise the ``insert_<table-name>_one`` root field
* - update * - update
- false - false
- `String` - ``String``
- Customise the ``update_<table-name>`` root field - Customise the ``update_<table-name>`` root field
* - update_by_pk
- false
- ``String``
- Customise the ``update_<table-name>_by_pk`` root field
* - delete * - delete
- false - false
- `String` - ``String``
- Customise the ``delete_<table-name>`` root field - Customise the ``delete_<table-name>`` root field
* - delete_by_pk
- false
- ``String``
- Customise the ``delete_<table-name>_by_pk`` root field
.. _set_table_custom_fields: .. _set_table_custom_fields:
@ -249,8 +264,11 @@ Set custom fields for table/view ``author``:
"select_by_pk": "Author", "select_by_pk": "Author",
"select_aggregate": "AuthorAggregate", "select_aggregate": "AuthorAggregate",
"insert": "AddAuthors", "insert": "AddAuthors",
"insert_one":"AddAuthor",
"update": "UpdateAuthors", "update": "UpdateAuthors",
"delete": "DeleteAuthors" "update_by_pk": "UpdateAuthor",
"delete": "DeleteAuthors",
"delete_by_pk": "DeleteAuthor"
}, },
"custom_column_names": { "custom_column_names": {
"id": "authorId" "id": "authorId"

View File

@ -27,10 +27,16 @@ Auto-generated delete mutation schema
type article_mutation_response { type article_mutation_response {
# number of affected rows by the mutation # number of affected rows by the mutation
affected_rows: Int! affected_rows: Int!
#data of the affected rows by the mutation # data of the affected rows by the mutation
returning: [article!]! returning: [article!]!
} }
# single object delete (supported from v1.2.0)
delete_article_by_pk (
# all primary key columns args
id: Int
): article
As you can see from the schema: As you can see from the schema:
- The ``where`` argument is compulsory to filter rows to be deleted. See :ref:`Filter queries <filter_queries>` - The ``where`` argument is compulsory to filter rows to be deleted. See :ref:`Filter queries <filter_queries>`
@ -45,8 +51,68 @@ See the :ref:`delete mutation API reference <delete_syntax>` for the full specif
If a table is not in the ``public`` Postgres schema, the delete mutation field will be of the format If a table is not in the ``public`` Postgres schema, the delete mutation field will be of the format
``delete_<schema_name>_<table_name>``. ``delete_<schema_name>_<table_name>``.
Delete based on an object's fields Delete an object by its primary key
---------------------------------- -----------------------------------
You can delete a single object in a table using the primary key.
The output type is the nullable table object. The mutation returns the deleted
row object or ``null`` if the row does not exist.
**Example:** Delete an article where ``id`` is ``1``:
.. graphiql::
:view_only:
:query:
mutation delete_an_object {
delete_article_by_pk (
id: 1
) {
id
title
user_id
}
}
:response:
{
"data": {
"delete_article_by_pk": {
"id": 1,
"title": "Article 1",
"user_id": 1
}
}
}
**Example:** Delete a non-existent article:
.. graphiql::
:view_only:
:query:
mutation delete_an_object {
delete_article_by_pk (
id: 100
) {
id
title
user_id
}
}
:response:
{
"data": {
"delete_article_by_pk": null
}
}
.. admonition:: Supported from
The ``delete_<table>_by_pk`` mutation is supported in versions ``v1.2.0``
and above.
Delete objects based on an their fields
---------------------------------------
**Example:** Delete all articles rated less than 3: **Example:** Delete all articles rated less than 3:
.. graphiql:: .. graphiql::
@ -69,8 +135,8 @@ Delete based on an object's fields
} }
Delete based on a nested object's fields Delete objects based on nested objects' fields
---------------------------------------- ----------------------------------------------
**Example:** Delete all articles written by a particular author: **Example:** Delete all articles written by a particular author:
.. graphiql:: .. graphiql::

View File

@ -28,7 +28,7 @@ Auto-generated insert mutation schema
type article_mutation_response { type article_mutation_response {
# number of affected rows by the mutation # number of affected rows by the mutation
affected_rows: Int! affected_rows: Int!
#data of the affected rows by the mutation # data of the affected rows by the mutation
returning: [article!]! returning: [article!]!
} }

View File

@ -29,10 +29,18 @@ Auto-generated update mutation schema
type article_mutation_response { type article_mutation_response {
# number of affected rows by the mutation # number of affected rows by the mutation
affected_rows: Int! affected_rows: Int!
#data of the affected rows by the mutation # data of the affected rows by the mutation
returning: [article!]! returning: [article!]!
} }
# single object update (supported from v1.2.0)
update_article_by_pk (
_inc: article_inc_input
_set: article_set_input
# primary key columns arg
pk_columns: article_pk_columns_input!
): article
As you can see from the schema: As you can see from the schema:
- The ``where`` argument is compulsory to filter rows to be updated. See :ref:`Filter queries <filter_queries>` - The ``where`` argument is compulsory to filter rows to be updated. See :ref:`Filter queries <filter_queries>`
@ -50,20 +58,77 @@ See the :ref:`update mutation API reference <update_syntax>` for the full specif
- If a table is not in the ``public`` Postgres schema, the update mutation field will be of the format - If a table is not in the ``public`` Postgres schema, the update mutation field will be of the format
``update_<schema_name>_<table_name>``. ``update_<schema_name>_<table_name>``.
Update based on an object's fields Update an object by its primary key
---------------------------------- -----------------------------------
**Example:** Update the ``title``, ``content`` and ``rating`` of the article with a given ``id``:
You can update a single object in a table using the primary key.
The output type is the nullable table object. The mutation returns the updated
row object or ``null`` if the row does not exist.
**Example:** Update an article where ``id`` is ``1``:
.. graphiql::
:view_only:
:query:
mutation update_an_article {
update_article_by_pk (
pk_columns: {id: 1}
_set: { is_published: true }
) {
id
is_published
}
}
:response:
{
"data": {
"update_article_by_pk": {
"id": 1,
"is_published": true
}
}
}
**Example:** Update a non-existent article:
.. graphiql::
:view_only:
:query:
mutation update_an_article {
update_article_by_pk (
pk_columns: {id: 100}
_set: { is_published: true }
) {
id
is_published
}
}
:response:
{
"data": {
"update_article_by_pk": null
}
}
.. admonition:: Supported from
The ``update_<table>_by_pk`` mutation is supported in versions ``v1.2.0``
and above.
Update objects based on their fields
------------------------------------
**Example:** Update the ``rating`` and ``is_published`` of articles with a low ``rating``:
.. graphiql:: .. graphiql::
:view_only: :view_only:
:query: :query:
mutation update_article { mutation update_article {
update_article( update_article(
where: {id: {_eq: 3}}, where: {rating: {_lte: 2}},
_set: { _set: {
title: "lorem ipsum", rating: 1,
content: "dolor sit amet", is_published: false
rating: 2
} }
) { ) {
affected_rows affected_rows
@ -72,6 +137,7 @@ Update based on an object's fields
title title
content content
rating rating
is_published
} }
} }
} }
@ -79,13 +145,21 @@ Update based on an object's fields
{ {
"data": { "data": {
"update_article": { "update_article": {
"affected_rows": 1, "affected_rows": 2,
"returning": [ "returning": [
{ {
"id": 3, "id": 3,
"title": "lorem ipsum", "title": "article 3",
"content": "dolor sit amet", "content": "lorem ipsum dolor sit amet",
"rating": 2 "rating": 1,
"is_published": false
},
{
"id": 6,
"title": "article 6",
"content": "lorem ipsum dolor sit amet",
"rating": 1,
"is_published": false
} }
] ]
} }
@ -97,9 +171,9 @@ Using variables:
.. graphiql:: .. graphiql::
:view_only: :view_only:
:query: :query:
mutation update_article($id: Int, $changes: article_set_input) { mutation update_article($rating: Int, $changes: article_set_input) {
update_article( update_article(
where: {id: {_eq: $id}}, where: {rating: {_lte: $rating}},
_set: $changes _set: $changes
) { ) {
affected_rows affected_rows
@ -108,6 +182,7 @@ Using variables:
title title
content content
rating rating
is_published
} }
} }
} }
@ -115,13 +190,21 @@ Using variables:
{ {
"data": { "data": {
"update_article": { "update_article": {
"affected_rows": 1, "affected_rows": 2,
"returning": [ "returning": [
{ {
"id": 3, "id": 3,
"title": "lorem ipsum", "title": "article 3",
"content": "dolor sit amet", "content": "lorem ipsum dolor sit amet",
"rating": 2 "rating": 1,
"is_published": false
},
{
"id": 6,
"title": "article 6",
"content": "lorem ipsum dolor sit amet",
"rating": 1,
"is_published": false
} }
] ]
} }
@ -129,11 +212,10 @@ Using variables:
} }
:variables: :variables:
{ {
"id": 3, "rating": 2,
"changes": { "changes": {
"title": "lorem ipsum", "rating": 1,
"content": "dolor sit amet", "is_published": false,
"rating": 2
} }
} }
@ -142,13 +224,12 @@ OR
.. graphiql:: .. graphiql::
:view_only: :view_only:
:query: :query:
mutation update_article($id: Int, $title: String, $content: String, $rating: Int) { mutation update_article($ratingLimit: Int, $rating: Int, $isPublished: Boolean) {
update_article( update_article(
where: {id: {_eq: $id}}, where: {rating: {_lte: $ratingLimit}},
_set: { _set: {
title: $title, rating: $rating,
content: $content, is_published: $isPublished,
rating: $rating
} }
) { ) {
affected_rows affected_rows
@ -157,6 +238,7 @@ OR
title title
content content
rating rating
is_published
} }
} }
} }
@ -164,13 +246,21 @@ OR
{ {
"data": { "data": {
"update_article": { "update_article": {
"affected_rows": 1, "affected_rows": 2,
"returning": [ "returning": [
{ {
"id": 3, "id": 3,
"title": "lorem ipsum", "title": "article 3",
"content": "dolor sit amet", "content": "lorem ipsum dolor sit amet",
"rating": 2 "rating": 1,
"is_published": false
},
{
"id": 6,
"title": "article 6",
"content": "lorem ipsum dolor sit amet",
"rating": 1,
"is_published": false
} }
] ]
} }
@ -178,14 +268,13 @@ OR
} }
:variables: :variables:
{ {
"id": 3, "ratingLimit": 2,
"title": "lorem ipsum", "rating": 1,
"content": "dolor sit amet", "isPublished": false
"rating": 2
} }
Update based on a nested object's fields Update objects based on nested objects' fields
---------------------------------------- ----------------------------------------------
**Example:** Reset the ``rating`` of all articles authored by "Sidney": **Example:** Reset the ``rating`` of all articles authored by "Sidney":
.. graphiql:: .. graphiql::
@ -551,5 +640,3 @@ one to delete all the existing objects and one to add a list of new nested objec
{ {
"author_id": 21 "author_id": 21
} }

View File

@ -40,6 +40,12 @@ Auto-generated query field schema
order_by: [author_order_by!] order_by: [author_order_by!]
): [author] ): [author]
# single object select
author_by_pk (
# all primary key columns args
id: Int!
): author
See the :ref:`Query API reference <graphql_api_query>` for the full specifications See the :ref:`Query API reference <graphql_api_query>` for the full specifications
.. note:: .. note::

View File

@ -1727,7 +1727,13 @@ The TRUE expression ( **{ }** )
The expression ``{}`` evaluates to ``true`` for all objects. The expression ``{}`` evaluates to ``true`` for all objects.
**For example**, any query with the condition ``{ where: {} }`` will return all objects without applying any filter. **For example**:
- any query with the condition ``{ where: {} }`` will return all objects without
applying any filter.
- any query with the condition ``{ where: { nested_object: {} } }`` will return all
objects for which atleast one ``nested_object`` exists.
.. _null_value_evaluation: .. _null_value_evaluation: