I know most guides recommend a "single input
argument" pattern for mutations, but I wanted to get feedback on this alternate pattern. Here's what I mean.
Single Argument
The single argument makes sense for update
mutations where input
actually contains multiple nested arguments:
mutation updateMovie {
updateMovie(input: { filter: { title: "Die Hard" } }, data: { year: 1989 } }) {
result {
...SomeFragment
}
}
}
But for create
mutations for example that extra level of nesting doesn't seem useful?
mutation createMovie {
createMovie(input: { data: { title: "Die Hard", year: 1989 } }) {
result {
...SomeFragment
}
}
}
Double Argument
Maybe for that reason, Hasura for example uses two arguments, where
and _set
, and doesn't nest them inside an input
:
mutation update_article {
update_article(
where: {id: {_eq: 3}},
_set: {
title: "lorem ipsum",
content: "dolor sit amet",
rating: 2
}
) {
affected_rows
returning {
...
}
}
}
Elaborating on this, I would like to suggest that a double argument pattern can pretty much work for any of the basic CRUD queries and mutations. The two arguments being:
selector: { filter: { ... }, sort: { ... } }
: an argument used to select data.
data
(a.k.a. movie
, patch
, etc.): contains any data that will be mutated.
Unlike the Hasura example where where
is a top-level argument, selector
would itself contain filter
(a.k.a. where
), sort
(a.k.a. orderBy
), and so on. The idea is to use the same selector input type anywhere you need to select data, whether it's for a query or mutation.
Which gives us:
movie(selector)
movies(selector)
createMovie(data)
updateMovie(selector, data)
deleteMovie(selector)
(Note: to that I would even add a third options
argument that control how the server should behave (e.g. caching behavior). But that's another matter.)
Basically, I get why a single argument is better than n
arguments (as explained here) but I think two arguments is actually better than both of these approaches, since selecting vs mutating data seems to be a good natural distinction that lends itself to this 2-argument approach.
EDIT: oh and the selector
and data
names are just placeholders, maybe there are better ones.