Setting up Conflict Resolution
Server-side conflict resolution is an additional feature which is meant to be used alongisde Delta Queries.
#
SetupCreate a new Graphback Project with:
When the CLI asks you to pick a template, you may either:
- Pick the
apollo-mongo-datasync-server-ts
template which has out-of-the-box delta queries and server-side conflict resolution - Pick the
apollo-mongo-server-ts
template and follow along with the rest of the tutorial
When the CLI has finished bootstrapping your project, you may follow along with the rest of the tutorial (if you picked apollo-mongo-server-ts
) or you may skip to the end of the tutorial.
#
Annotate the required modelsAdd the @datasync
annotation to your model(s) in your GraphQL SDL found in the model
folder:
This configuration transforms your model for Delta Queries (adding _lastUpdatedAt
) as well as the following for Conflict resolution:
- A
_version
field in the model type used for fetching base document in conflict resolution. - A
_version
field in the corresponding Mutation Input Type.
The model type then becomes:
And the Mutation Input type for it would be:
An example mutation can be found at the end of this page.
createDataSyncAPI
#
Modify the template to use In the src/index.ts
file of the template, use createDataSyncAPI
instead of buildGraphbackAPI
:
The conflictConfig
argument is used to either configure conflicts for all @datasync
enabled models by directly setting global conflict parameters like enabled
or configuring specific models via a models
property. When conflicts are enabled for a specific model, a delta table is maintained for that model.
An example entry in the delta table would look as follows:
To improve efficiency of queries on the delta
table, a deltaTTL
argument (in seconds) is used along with a MongoDB TTL Index to prune older entries from the delta table. In the current configuration, a default strategy of ClientSideWins
is used. Please check the Conflict Resolution Strategies documentation for more information on using different strategies as well as implementing custom Conflict Resolution strategies.
note
You may only have delta queries for one model while having both delta queries and server-side conflict resolution for another model without them interfering with each other.
#
Example of Issuing a Delta QueryDelta Queries remain the same but with the addition of a _version
field as outlined in the above sections:
An example response may be:
#
Example MutationsBoth updates and deletes are implemented with a default server-side Conflict Resolution strategy when it is enabled i.e. The ClientWins
strategy, this means that in the event of an update or delete conflict, the client side always wins. Taking an example, suppose the comment
collection consists of the following document:
In order to update this document one has to issue a mutation as follows:
And receive a response like so:
note
To issue mutations for a model with server-side Conflict resolution, the current value of the _version
field must be passed in the input argument as is required by the corresponding Mutation Input Type.
Conflicts usually happen when a client does not have the most recent version of the data and tries to issue mutations. The server detects this using the aforementioned _version
field and checks to see if fields that the client is trying to update have changed since the client last fetched the data.
In case they have, the server calls upon the conflict resolution strategy to resolve the conflict. See Conflict Resolution Strategies for more info on these strategies.
Following the previous example, if another client did not receive the above update, and tries to issue another update like so:
No conflict will occur, even if the version field is out-of-date because the title
field has not changed since this client fetched the document. Therefore, it may receive a response as such: