mobxjs/mst-gql

In mutations include only arguments which have a value set in variables

beepsoft opened this issue · 0 comments

In a Hasura generated schema I have this mutation:

# update data of the table: "task"
updateTasks(
  # append existing jsonb value of filtered columns with new jsonb value
  _append: task_append_input

  # delete the field or element with specified path (for JSON arrays, negative integers count from the end)
  _delete_at_path: task_delete_at_path_input

  # delete the array element with specified index (negative integers count from
  # the end). throws an error if top level container is not an array
  _delete_elem: task_delete_elem_input

  # delete key/value pair or string element. key/value pairs are matched based on their key value
  _delete_key: task_delete_key_input

  # increments the numeric columns with given value of the filtered values
  _inc: task_inc_input

  # prepend existing jsonb value of filtered columns with new jsonb value
  _prepend: task_prepend_input

  # sets the columns of the filtered rows to the given values
  _set: task_set_input

  # filter the rows which have to be updated
  where: task_bool_exp!
): task_mutation_response

For this, the following function is generated by mst-gql:

mutateUpdateTasks(variables: { append?: TaskAppendInput, deleteAtPath?: TaskDeleteAtPathInput, deleteElem?: TaskDeleteElemInput, deleteKey?: TaskDeleteKeyInput, inc?: TaskIncInput, prepend?: TaskPrependInput, set?: TaskSetInput, where: TaskBoolExp }, resultSelector: string | ((qb: TaskMutationResponseModelSelector) => TaskMutationResponseModelSelector) = taskMutationResponseModelPrimitives.toString(), optimisticUpdate?: () => void) {
  return self.mutate<{ updateTasks: TaskMutationResponseModelType}>(`mutation updateTasks($append: task_append_input, $deleteAtPath: task_delete_at_path_input, $deleteElem: task_delete_elem_input, $deleteKey: task_delete_key_input, $inc: task_inc_input, $prepend: task_prepend_input, $set: task_set_input, $where: task_bool_exp!) { updateTasks(_append: $append, _delete_at_path: $deleteAtPath, _delete_elem: $deleteElem, _delete_key: $deleteKey, _inc: $inc, _prepend: $prepend, _set: $set, where: $where) {
    ${typeof resultSelector === "function" ? resultSelector(new TaskMutationResponseModelSelector()).toString() : resultSelector}
  } }`, variables, optimisticUpdate)
},

Note that every argument from the graphql schema is listed in the generated mutation updateTasks(...) as arguments.

When I try to use this function like this (I only want to set a specific value):

store.mutateUpdateTasks({
    where: {
        id: {
            _eq: 1
        }
    },
    set: {
        tag: "foo"
    }
},
selectFromTaskMutationResponse().affected_rows.toString())

I get this error:

{
  "response": {
    "errors": [
      {
        "extensions": {
          "path": "$.selectionSet.updateTasks.args._inc",
          "code": "validation-failed"
        },
        "message": "expected an object for type \"task_inc_input\", but found null"
      }
    ],
    "status": 200
  },
  "request": {
    "query": "mutation updateTasks($append: task_append_input, $deleteAtPath: task_delete_at_path_input, $deleteElem: task_delete_elem_input, $deleteKey: task_delete_key_input, $inc: task_inc_input, $prepend: task_prepend_input, $set: task_set_input, $where: task_bool_exp!) { updateTasks(_append: $append, _delete_at_path: $deleteAtPath, _delete_elem: $deleteElem, _delete_key: $deleteKey, _inc: $inc, _prepend: $prepend, _set: $set, where: $where) {\n        __typename\naffected_rows\n\n      } }",
    "variables": {
      "where": {
        "id": {
          "_eq": 1
        }
      },
      "set": {
        "tag": "foo"
      }
    }
  }
}

The problem is that while _inc (of type task_inc_input) is defined as optional _inc: $inc somehow Hasura expects to have value for it in variables because it is mentioned among the updateTasks() parameters. In case of queries I didn't see this happen, only in mutations. Maybe mutation arguments have a different semantics than query arguments?

Anyways, I think it would be feasible to only generate arguments, which are set in variables. This needs runtime evaluation of the variables and based on that should be the graphql mutation string generated.

A similar mechanism is also implemented in #361, so I could fix this mutation issue as well.