Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ capi/src/__tests__/*/www
client/src/api
client/src/assets
report.*.json
_site/

#amplify
amplify/\#current-cloud-backend
Expand Down
3 changes: 2 additions & 1 deletion client/src/amplify-ui/code-block/code-block.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ export const lineCountStyle = css`
position: sticky;
left: 0;
background-color: var(--code-bg-color);
color: var(--code-font-color);
color: var(--code-line-numbers-color);
text-align: center;
padding: 0 1rem;
user-select: none;
opacity: 0.8;

> div {
display: flex;
Expand Down
1 change: 1 addition & 0 deletions client/src/amplify-ui/styles/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const variablesStyle = css`
--border-color: var(--color-grey-md);
--code-bg-color: var(--color-ink-hv);
--code-font-color: var(--color-white);
--code-line-numbers-color: rgba(255, 255, 255, 0.3);
--font-color-contrast: var(--color-white);

--breakpoint-fablet: ${Breakpoint.FABLET};
Expand Down
39 changes: 38 additions & 1 deletion docs/lib/datastore/conflict.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,43 @@ title: Conflict resolution
description: description
---

## Setup

When syncing with AWS AppSync, DataStore updates from multiple clients will converge by tracking object versions and adhere to different conflict resolution strategies. The default strategy is called *Automerge* where GraphQL type information on an object is inspected at runtime to perform merge operations. You can read more about this behavior and alternatives such as *Optimistic Concurrency* Control and *custom Lambda functions* in the [AWS AppSync documentation](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html). To update the conflict resolution strategies navigate into your project from a terminal and run `amplify update api` choosing *Yes* when prompted to change the conflict detection and conflict resolution strategies:

```
amplify update api # Select GraphQL

? Do you want to configure advanced settings for the GraphQL API
❯ Yes, I want to make some additional changes.

? Configure conflict detection? Yes
? Select the default resolution strategy
Auto Merge
❯ Optimistic Concurrency
Custom Lambda
Learn More
```

### Per model configuration

Note that this flow will also allow you to change the strategy on each individual GraphQL type, though is is recommended to use the same strategy for your whole schema unless you have an advanced use case:

```
? Do you want to override default per model settings? Yes
? Select the models from below:
❯◉ Post
◯ PostEditor
◯ User

? Select the resolution strategy for Post model Custom Lambda
? Select from the options below (Use arrow keys)
❯ Create a new Lambda Function
Existing Lambda Function
```

## Optional configurations

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/conflict.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/conflict.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/conflict.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/conflict.md"></inline-fragment>
82 changes: 79 additions & 3 deletions docs/lib/datastore/data-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,82 @@ title: Manipulating data
description: description
---

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access.md"></inline-fragment>
## Save Data

To write any data to the DataStore you can pass an instance of a Model to `DataStore.save()` and it will be persisted in offline storage. At this point you can use it as an item in a normal data store such as querying, updating or deleting. If you choose to later connect to the cloud the item will be synchronized using GraphQL mutations and any other systems connected to the same backend can run queries or mutations on these items as well as observe them with GraphQL subscriptions.

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/save-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/save-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/save-snippet.md"></inline-fragment>

## Query Data

Querying data is always against the locally synchronized data, which is updated in the background for you by the DataStore Sync Engine when connected to the cloud. You can query using models as well as conditions using predicate filters for finer grained results.

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/query-basic-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/query-basic-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/query-basic-snippet.md"></inline-fragment>

### Query with Predicates

You can apply predicate filters against the DataStore using the fields defined on your GraphQL type along with the following conditions supported by DynamoDB:

**Strings:** `eq | ne | le | lt | ge | gt | contains | notContains | beginsWith | between`

**Numbers:** `eq | ne | le | lt | ge | gt | between`

**Lists:** `contains | notContains`

For example if you wanted a list of all `Post` Models that have a `rating` greater than 4:

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/query-predicate-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/query-predicate-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/query-predicate-snippet.md"></inline-fragment>

Multiple conditions can also be used, like the ones defined in [GraphQL Transform condition statements](~/cli/graphql-transformer/resolvers.md). For example, fetch all posts that has a rating greater than `4` and are `active`:

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/query-predicate-multiple-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/query-predicate-multiple-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/query-predicate-multiple-snippet.md"></inline-fragment>

Alternatively, the `or` logical operator can also be used:

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/query-predicate-or-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/query-predicate-or-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/query-predicate-or-snippet.md"></inline-fragment>

### Pagination

Query results can also be paginated, you can optionally pass in a limit and page. This will return a list of the first 100 items:

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/query-pagination-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/query-pagination-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/query-pagination-snippet.md"></inline-fragment>

## Update Data

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/update-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/update-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/update-snippet.md"></inline-fragment>

You can also apply conditions to update and delete operations. The condition will be applied locally and if you have enabled synchronization with the cloud it will be placed in a network mutation queue. The GraphQL mutation will then include this condition and be evaluated against the existing record in DynamoDB. If the condition holds the item in the cloud is updated and synchronized across devices. If the check fails then the item is not updated and the source of truth from the cloud will be applied to the local DataStore. For instance if you wanted to update if the `rating` was greater than 3:

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/update-condition-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/update-condition-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/update-condition-snippet.md"></inline-fragment>

Conditional updates can only be applied to single items and not lists. If you wish to update a list of items you can loop over them and apply conditions one at a time.

## Delete Data

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/delete-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/delete-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/delete-snippet.md"></inline-fragment>

## Observe Data

You can subscribe to changes on your Models. This reacts dynamically to updates of data to the underlying Storage Engine, which could be the result of GraphQL Subscriptions as well as Queries or Mutations that run against the backing AppSync API if you are synchronizing with the cloud.

<inline-fragment platform="js" src="~/lib/datastore/fragments/js/data-access/observe-snippet.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/datastore/fragments/ios/data-access/observe-snippet.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/datastore/fragments/android/data-access/observe-snippet.md"></inline-fragment>
31 changes: 3 additions & 28 deletions docs/lib/datastore/fragments/android/conflict.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,5 @@
When syncing with AWS AppSync, DataStore updates from multiple clients will converge by tracking object versions and adhere to different conflict resolution strategies. The default strategy is called *Automerge* where GraphQL type information on an object is inspected at runtime to perform merge operations. You can read more about this behavior and alternatives such as *Optimistic Concurrency* Control and *custom Lambda functions* in the [AWS AppSync documentation](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html). To update the conflict resolution strategies navigate into your project from a terminal and run `amplify update api` choosing *Yes* when prompted to change the conflict detection and conflict resolution strategies:
<amplify-callout>

```sh
amplify update api #Select GraphQL
**Note:** custom conflict resolution is not generally available yet. The API is currently being designed for Android. Check back soon for updates.

? Do you want to configure advanced settings for the GraphQL API
❯ Yes, I want to make some additional changes.

? Configure conflict detection? Yes
? Select the default resolution strategy
Auto Merge
❯ Optimistic Concurrency
Custom Lambda
Learn More
```

Note that this flow will also allow you to change the strategy on each individual GraphQL type, though is is recommended to use the same strategy for your whole schema unless you have an advanced use case:

```sh
? Do you want to override default per model settings? Yes
? Select the models from below:
❯◉ Post
◯ PostEditor
◯ User

? Select the resolution strategy for Post model Custom Lambda
? Select from the options below (Use arrow keys)
❯ Create a new Lambda Function
Existing Lambda Function
```
</amplify-callout>
129 changes: 0 additions & 129 deletions docs/lib/datastore/fragments/android/data-access.md

This file was deleted.

16 changes: 16 additions & 0 deletions docs/lib/datastore/fragments/android/data-access/delete-snippet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
To delete an item, simply pass in an instance to `Amplify.DataStore.delete()`. Below, we query for an instance with an `id` of `"123"`, and then delete it, if found:

```java
Amplify.DataStore.query(Post.class, Post.ID.eq("123"),
matches -> {
if (matches.hasNext()) {
Post post = matches.next();
Amplify.DataStore.delete(post,
deleted -> Log.i("GetStarted", "Deleted a post."),
failure -> Log.i("GetStarted", "Delete failed.", failure)
);
}
},
failure -> Log.e("GetStarted", "Query failed.", failure)
);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```java
Amplify.DataStore.observe(Post.class,
cancelable -> Log.i("GetStarted", "Observation began."),
postChanged -> {
Post post = postChanged.item();
Log.i("GetStarted", "Post: " + post);
},
failure -> Log.e("GetStarted", "Observation failed.", failure),
() -> Log.i("GetStarted", "Observation complete.")
);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```java
Amplify.DataStore.query(Post.class,
allPosts -> {
while (allPosts.hasNext()) {
Post post = allPosts.next();
Log.i("GetStarted", "Title: " + post.getTitle());
}
},
failure -> Log.e("GetStarted", "Query failed.", failure)
);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<amplify-callout>

The pagination API is not available for Android yet. Check back soon.

</amplify-callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```java
Amplify.DataStore.query(
Post.class,
Post.RATING.gt(4).and(Post.STATUS.eq(PostStatus.ACTIVE)),
goodActivePosts -> {
while (goodActivePosts.hasNext()) {
Post post = goodActivePosts.next();
Log.i("GetStarted", "Post: " + post);
}
},
failure -> Log.e("GetStarted", "Query failed.", failure)
);
```
Loading