Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve the serialization order for mutations #575

Merged
merged 4 commits into from
Nov 29, 2021

Conversation

kyasu1
Copy link
Sponsor Contributor

@kyasu1 kyasu1 commented Nov 29, 2021

Hi!

I run into a problem when sending multiple mutations in a single request to Hasura server backed with PostgreSQL. The mutation query requires to execute update and insert operations sequentially in a transaction of PostgreSQL, however elm-graphql is serializing their GraphQL operations into alphabetical order which is the problem.

More specifically, with this code we expect the updateUser runs first then the insertUser.

SelectionSet.map2 Tuple.pair updateUser insertUser

However actually this is serialized to something like follows.

query: “mutation {
  insert_user12345: insert_user(…)
  update_user12345: update_user(…)
}”

With this query, Hasura issues PostgreSQL query in order of insert then update which will fail in my schema. I think this behavior is counter intuitive and can be a pitfall for users. Also I have searched a bit for another projects and I found this and GraphQL specs

http://spec.graphql.org/October2021/#sec-Normal-and-Serial-Execution

which says the execution order must be in serial for mutations.

The current implementation uses standard Dict package for serializing fields

mergedFields : List RawField -> List RawField
mergedFields children =
let
mergeThing : MergedFields
mergeThing =
mergeFields children
in
(mergeThing.leaves |> Dict.values |> List.map leafToField)
++ (mergeThing.composites |> Dict.values |> List.map compositeToField)
type alias MergedFields =
{ leaves : Dict String ( { typeString : String, fieldName : String }, List Argument )
, composites : Dict String ( { name : String, args : List Argument }, List RawField )
}

which cause serialization of the fields in alphabetical order.

To prevent this re-ordering, in this PR, I have naively replaced it with j-mass/elm-ordered-containers and it seems to give us the expected result.

Thanks

@dillonkearns
Copy link
Owner

Thank you for the PR @kyasu1! It is indeed very important that the order be preserved for mutations. I wasn't thinking about that when I worked on #556. Thank you for the report and the PR!

I went ahead and made a few changes to get this green and also to handle some additional cases (so that ordering is preserved between leaf and composite fields correctly).

@dillonkearns dillonkearns merged commit dff1294 into dillonkearns:master Nov 29, 2021
@dillonkearns
Copy link
Owner

This is now live in Elm package version 5.0.8. Thanks again!

@kyasu1 kyasu1 deleted the serialize-by-ordered-dict branch November 30, 2021 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants