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

Flutter api docs #2818

Merged
merged 18 commits into from
Jan 15, 2021
1 change: 1 addition & 0 deletions docs/lib/graphqlapi/authz.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ description: Learn more about how to configure authorization modes in Amplify Fr
<inline-fragment platform="ios" src="~/lib/graphqlapi/fragments/native_common/authz/common.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/graphqlapi/fragments/native_common/authz/common.md"></inline-fragment>
<inline-fragment platform="js" src="~/lib/graphqlapi/fragments/js/authz.md"></inline-fragment>
<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/flutter/authz.md"></inline-fragment>
1 change: 1 addition & 0 deletions docs/lib/graphqlapi/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ description: Learn more about the foundation concepts of Amplify Framework's API
<inline-fragment platform="js" src="~/lib/graphqlapi/fragments/native_common/concepts.md"></inline-fragment>
<inline-fragment platform="android" src="~/lib/graphqlapi/fragments/native_common/concepts.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/graphqlapi/fragments/native_common/concepts.md"></inline-fragment>
<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/native_common/concepts.md"></inline-fragment>
1 change: 1 addition & 0 deletions docs/lib/graphqlapi/existing-resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ description: Configure the Amplify Libraries to use existing AWS AppSync resourc

<inline-fragment platform="android" src="~/lib/graphqlapi/fragments/existing-resources.md"></inline-fragment>
<inline-fragment platform="ios" src="~/lib/graphqlapi/fragments/existing-resources.md"></inline-fragment>
<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/existing-resources.md"></inline-fragment>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upon completion, `amplifyconfiguration.json` will be updated to reference provisioned backend resources. Note that these files should already be a part of your project if you followed the [Project setup walkthrough](~/lib/project-setup/create-application.md).
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
## Generate Todo Model class
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

To generate the `Todo` model, change directories to your project folder and **execute the command**:

```bash
amplify codegen models
```

The generated files will be under the `app/src/main/java/com/amplifyframework.datastore.generated.model` directory.
134 changes: 134 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/authz.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
For client authorization AppSync supports API Keys, Amazon IAM credentials, Amazon Cognito User Pools, and 3rd party OIDC providers. This is inferred from the `amplifyconfiguration.json` file when you call `Amplify.configure()`.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

#### API key

API Key is the easiest way to setup and prototype your application with AWS AppSync. This means it is also prone to abuse since anyone can easily discover the API Key and make requests to your public service. To have authorization checks, use the other auth modes such as Cognito user pool or AWS IAM. API Key will expiry according to the expiry time set when provisioning AWS AppSync and will require extending it or creating a new one if needed.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

#### Amazon Cognito User Pools

Amazon Cognito's user pool is most commonly used with AWS AppSync when adding authorization check on your API calls. If your application needs to interact with other AWS services besides AWS AppSync, such as Amazon S3, you will need to use AWS IAM credentials with Amazon Cognito's identity pools. Amplify CLI can automatically configure this for you when running `amplify add auth` and will also automatically use the authenticated user from user pools to federate with the identity pools to provide the AWS IAM credentials in the application. [See this for more information about the differences](https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pools-identity-pools/). This allows you to have both user pool credentials for AWS AppSync and AWS IAM credentials for other AWS resources. You can learn more about Amplify Auth outlined in the [Accessing credentials section](~/lib/auth/access_credentials.md). For manual configuration, add the following snippet to your `amplifyconfiguration.json` file, under the `awsCognitoAuthPlugin`:
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

```json
{
...
"awsCognitoAuthPlugin": {
"CognitoUserPool": {
"Default": {
"PoolId": "[POOL-ID]",
"AppClientId": "[APP-CLIENT-ID]",
"Region": "[REGION]"
}
}
}
}
```
and under the `awsAPIPlugin`
```json
{
...
"awsAPIPlugin": {
"<YOUR-GRAPHQLENDPOINT-NAME": {
"endpointType": "GraphQL",
"endpoint": "[GRAPHQL-ENDPOINT]",
"region": "[REGION]",
"authorizationType": "AMAZON_COGNITO_USER_POOLS",
}
}
}

```

<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/flutter/authz/10_userpool.md"></inline-fragment>

#### IAM

Amazon Cognito identity pools allows you to use credentials from AWS IAM in a mobile application. The Amplify CLI can automatically configure this for you when running `amplify add auth`. For manual configuration, add the following snippet to your `amplifyconfiguration.json` file:

```json
{
...
"awsCognitoAuthPlugin": {
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "[COGNITO-IDENTITY-POOLID]",
"Region": "[REGION]"
}
}
}
}
}
```
and under the `awsAPIPlugin`
```json
{
...
"awsAPIPlugin": {
"<YOUR-GRAPHQLENDPOINT-NAME": {
"endpointType": "GraphQL",
"endpoint": "[GRAPHQL-ENDPOINT]",
"region": "[REGION]",
"authorizationType": "AWS_IAM",
}
}
}
```


#### OIDC

<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/flutter/authz/20_oidc.md"></inline-fragment>

#### Multi-Auth

This section talks about the capability of AWS AppSync to configure multiple authorization modes for a single AWS AppSync endpoint and region. Follow the [AWS AppSync Multi-Auth](https://docs.aws.amazon.com/appsync/latest/devguide/security.html#using-additional-authorization-modes) to configure multiple authorization modes for your AWS AppSync endpoint.

You can now configure a single GraphQL API to deliver private and public data. Private data requires authenticated access using authorization mechanisms such as IAM, Cognito User Pools, and OIDC. Public data does not require authenticated access and is delivered through authorization mechanisms such as API Keys. You can also configure a single GraphQL API to deliver private data using more than one authorization type. For example, you can configure your GraphQL API to authorize some schema fields using OIDC, while other schema fields through Cognito User Pools and/or IAM.

As discussed in the above linked documentation, certain fields may be protected by different authorization types. This can lead the same query, mutation, or subscription to have different responses based on the authorization sent with the request; Therefore, it is recommended to use the different `friendly_name_<AuthMode>` as the `apiName` parameter in the `Amplify.API` call to reference each authorization type.

The following snippets highlight the new values in the `amplifyconfiguration.json` and the client code configurations.

The `friendly_name` illustrated here is created from Amplify CLI prompt. There are 4 clients in this configuration that connect to the same API except that they use different `AuthMode`.

```json
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"api": {
"plugins": {
"awsAPIPlugin": {
"[FRIENDLY-NAME-API-WITH-API-KEY]": {
"endpointType": "GraphQL",
"endpoint": "[GRAPHQL-ENDPOINT]",
"region": "[REGION]",
"authorizationType": "API_KEY",
"apiKey": "[API_KEY]"
},
"[FRIENDLY-NAME-API-WITH-IAM": {
"endpointType": "GraphQL",
"endpoint": "[GRAPHQL-ENDPOINT]",
"region": "[REGION]",
"authorizationType": "AWS_IAM",
},
"[FRIENDLY-NAME-API-WITH-USER-POOLS]": {
"endpointType": "GraphQL",
"endpoint": "https://xyz.appsync-api.us-west-2.amazonaws.com/graphql",
"region": "[REGION]",
"authorizationType": "AMAZON_COGNITO_USER_POOLS",
},
"[FRIENDLY-NAME-API-WITH-OPENID-CONNECT]": {
"endpointType": "GraphQL",
"endpoint": "https://xyz.appsync-api.us-west-2.amazonaws.com/graphql",
"region": "[REGION]",
"authorizationType": "OPENID_CONNECT",
}
}
}
}
}
```

The `GRAPHQL-ENDPOINT` from AWS AppSync will look similar to `https://xyz.appsync-api.us-west-2.amazonaws.com/graphql`.

<inline-fragment platform="flutter" src="~/lib/graphqlapi/fragments/flutter/authz/30_multi.md"></inline-fragment>
8 changes: 8 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/authz/10_userpool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Add the following code to your app:

```dart
await amplify.addPlugin(
authPlugins: [AmplifyAuthCognito()]
apiPlugins: [AmplifyAPI()]
);
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
```
5 changes: 5 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/authz/20_oidc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<amplify-callout>

OIDC mode is not yet supported for Flutter. We are actively working on this.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

</amplify-callout>
5 changes: 5 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/authz/30_multi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<amplify-callout>

OIDC modes is not available just yet for Flutter. We are actively working on this.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

</amplify-callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<amplify-callout>

Amplify Flutter currently supports the advanced workflow for GraphQL which involves constructing custom requests by providing a GraphQL document and variables.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

Model based APIs that will generate a GraphQL request for you under the covers will be supported in the future.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

You can learn more about the structure of a request from [GraphQL Query Language](https://graphql.org/learn/) and [AppSync documentation](https://docs.aws.amazon.com/appsync/latest/devguide/graphql-overview.html). To test out constructing your own requests, open the AppSync console using `amplify console api` and navigate to the Queries tab.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

</amplify-callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
* [Install and configure Amplify CLI](https://docs.amplify.aws/cli/start/install)
* A Flutter application targeting Flutter SDK >= 1.20 with Amplify libraries integrated
* An iOS configuration targeting at least iOS 11.0
* An Android configuration targeting at least Android API level 21 (Android 5.0) or above
* For a full example please follow the [project setup walkthrough](~/lib/project-setup/create-application.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upon completion, `amplifyconfiguration.dart` will be updated to reference provisioned backend resources. Note that these files should already be a part of your project if you followed the [Project setup walkthrough](~/lib/project-setup/create-application.md).
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Add the following dependencies to your `pubspec.yaml` file and install dependencies when asked:

```yaml
dependencies:
flutter:
sdk: flutter
amplify_core: '<1.0.0'
amplify_api: '<1.0.0'
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
To initialize the Amplify API category you call `Amplify.addPlugin()` method for each category. To complete initialization call `Amplify.configure()`.
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

Your code should look like this:

```dart
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_api/amplify_api.dart';

import 'amplifyconfiguration.dart';

class MyAmplifyApp extends StatefulWidget {

Amplify amplify = Amplify();

@override
void initState() {
super.initState();

AmplifyAPI api = AmplifyAPI();
await amplify.addPlugin(apiPlugins: [api]);
haverchuck marked this conversation as resolved.
Show resolved Hide resolved
await amplify.configure(amplifyConfig);
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
```dart
try {
String graphQLDocument =
'''mutation CreateTodo(\$name: String!, \$description: String) {
createTodo(input: {name: \$name, description: \$description}) {
id
name
description
}
}''';

var operation = Amplify.API.mutate(
request: GraphQLRequest<String>(document: graphQLDocument, variables: {
"name": "my first todo",
"description": "todo description",
}));
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved

var response = await operation.response;
var data = response.data;

print('Mutation result: ' + data);
} catch(e) {
print(e);
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
}
```
53 changes: 53 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/mutate-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
## Run a mutation

Now that the client is set up, you can run a GraphQL mutation with `Amplify.API.mutate` to create, update, and delete your data.

```dart
try {
String graphQLDocument =
'''mutation CreateTodo(\$name: String!, \$description: String) {
createTodo(input: {name: \$name, description: \$description}) {
id
name
description
}
}''';

var operation = Amplify.API.mutate(
request: GraphQLRequest<String>(document: graphQLDocument, variables: {
"name": "my first todo",
"description": "todo description",
}));

var response = await operation.response;
var data = response.data;

print('Mutation result: ' + data);
} catch(e) {
print(e);
}
```

The response data will be a JSON String that looks like this:

```json
{
"createTodo": {
"name": "my first todo",
"id": "4422c06e-3f93-4db1-87c4-571f87e656a0",
"description": "todo description"
}
}
```

You can decode the data to a Map and access the attributes as needed:

```dart
//Decode the data to a Map
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
Map result = json.decode(response.data);
Map todoMap = result['createTodo'];

//access the attributes
fjnoyp marked this conversation as resolved.
Show resolved Hide resolved
final id = todoMap['id'];
print('Todo id: $id');
```
58 changes: 58 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/query-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## Query item

Now that you were able to make a mutation, take the `id` that was printed out and use it in your query to retrieve data.

```dart
try {
String graphQLDocument = '''query GetTodo(\$id: ID!) {
getTodo(id: \$id) {
id
name
description
}
}''';

var operation = Amplify.API.query(
request: GraphQLRequest<String>(
document: graphQLDocument,
variables: {"id": "8e0dd2fc-2f4a-4dc4-b47f-2052eda10775"}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to show how to retrieve this Id from the mutation result? Based on our example schema and selection set used in mutation, it should be consistent on how Id gets retrieved instead of using a dummy Id here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section actually starts with Now that you were able to make a mutation, take the 'id'... and references the previous section which demonstrated how to run a mutation and get the result.
iOS docs also pass in a dummy id like this for getTodo. Android passes an id variable but then is enclosed in a function that takes id as an argument. So would rather just keep this similar to iOS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only have advanced flows, and nowhere in our docs we are showing how to access the data, I think it's a huge value add here to show, and possibly in other examples as well (e.g. a query example)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added details for how to work with the mutation response as discussed.


var response = await operation.response;
var data = response.data;

print('Query result: ' + data);
} catch(e) {
print(e);
Comment on lines +24 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} catch(e) {
print(e);
} catch (error) {
print("Query failed: $error");

}
```

## List items

You can get the list of items in `Amplify.API.query`:

```dart
try {
String graphQLDocument = '''query ListTodos {
listTodos {
items {
id
name
description
}
nextToken
}
}''';

var operation = Amplify.API.query(
request: GraphQLRequest<String>(
document: graphQLDocument,
));

var response = await operation.response;
var data = response.data;

print('Query result: ' + data);
} catch(e) {
print(e);
}
Comment on lines +55 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} catch(e) {
print(e);
}
} catch (error) {
print("Query failed: $error");
}

```
5 changes: 5 additions & 0 deletions docs/lib/graphqlapi/fragments/flutter/subscribe-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<amplify-callout>

Subscribe is not yet available for Amplify Flutter and is being actively worked on.

</amplify-callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Upon completion, `amplifyconfiguration.json` will be updated to reference provisioned backend resources. Note that these files should already be a part of your project if you followed the [Project setup walkthrough](~/lib/project-setup/create-application.md).
Loading