-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1201 from dabit3/v2-preview
Updated react + react native getting started guides
- Loading branch information
Showing
13 changed files
with
380 additions
and
775 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
## What we'll build | ||
|
||
This tutorial guides you through setting up a backend and integrating that backend with your React Native app. You will create a “Todo app” with a GraphQL API and to store and retrieve items in a cloud database. In addition, we'll demonstrate how to authenticate users, communicate with our API, and set up continuous deployment and hosting. | ||
This tutorial guides you through setting up a backend and integrating that backend with your React Native app. You will create a “Todo app” with a GraphQL API and to store and retrieve items in a cloud database. In addition, we'll demonstrate how to authenticate users, communicate with our API, and set up continuous deployment and hosting. | ||
|
||
## Pre-requisites | ||
|
||
The first thing you should do is initialize a new <a href="https://facebook.github.io/react-native/docs/getting-started" target="_blank">React Native application</a>. There are two ways to do this: | ||
|
||
1. Expo CLI - Easier for new React Native developers | ||
2. React Native CLI - If you are already familiar with mobile development, enables you to build native code into your project. | ||
|
||
This tutorial will cover both, so use what's best for you. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
Now that you’ve created and configured a React app and initialized a new Amplify project, you can add a feature. The first feature you will add is an API. | ||
|
||
The Amplify CLI supports creating and interacting with two types of API categories: REST and GraphQL. | ||
|
||
The API you will be creating in this step is a GraphQL API using AWS AppSync (a managed GraphQL service) and the database will be Amazon DynamoDB (a NoSQL database). | ||
|
||
## Create a GraphQL API and database | ||
|
||
To add the API, run the following command. | ||
|
||
```sh | ||
amplify add api | ||
|
||
? Please select from one of the below mentioned services: GraphQL | ||
? Provide API name: myapi | ||
? Choose the default authorization type for the API: API Key | ||
? Enter a description for the API key: demo | ||
? After how many days from now the API key should expire: 7 (or your preferred expiration) | ||
? Do you want to configure advanced settings for the GraphQL API: N | ||
? Do you have an annotated GraphQL schema? N | ||
? Do you want a guided schema creation? Y | ||
? What best describes your project: Single object with fields | ||
? Do you want to edit the schema now? Y | ||
``` | ||
The CLI should open this schema in your text editor (__amplify/backend/api/myapi/schema.graphql | ||
__). | ||
```graphql | ||
type Todo @model { | ||
id: ID! | ||
name: String! | ||
description: String | ||
} | ||
``` | ||
The schema generated is for a Todo app. You'll notice a directive on the `Todo` type of `@model`. This directive is part of the [GraphQL transform](/cli/graphql-transformer/directives) library of Amplify. | ||
The GraphQL Transform Library provides custom directives you can use in your schema that allow you to do things like define data models, set up authentication and authorization rules, configure serverless functions as resolvers, and more. | ||
A type decorated with the `@model` directive will scaffold out the database table for the type (Todo table), the schema for CRUD (create, read, update, delete) and list operations, and the GraphQL resolvers needed to make everything work together. | ||
From the command line, press __enter__ to accept the schema and continue to the next steps. | ||
### Test your API | ||
To test this out locally, you can run the `mock` command: | ||
```sh | ||
amplify mock api | ||
# Before mocking you will be walked through the following steps for GraphQL code generation | ||
? Choose the code generation language target: javascript (or preferred target) | ||
? Enter the file name pattern of graphql queries, mutations and subscriptions: src/graphql/**/*.js | ||
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions: Yes | ||
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2 | ||
``` | ||
This will open the GraphiQL explorer on a local port. From the test environment you can try out different operations locally, like queries and mutations, before deploying the backend. | ||
Try running a couple of mutations locally and then querying for the todos: | ||
```graphql | ||
mutation createTodo { | ||
createTodo(input: { | ||
name: "Build an API" | ||
description: "Build a serverless API with Amplify and GraphQL" | ||
}) { | ||
id | ||
name | ||
description | ||
} | ||
} | ||
query listTodos { | ||
listTodos { | ||
items { | ||
id | ||
description | ||
name | ||
} | ||
} | ||
} | ||
``` | ||
### Deploying the API | ||
To deploy this backend, run the `push` command: | ||
```sh | ||
amplify push | ||
? Are you sure you want to continue? Y | ||
# If you did not mock the API, you will be walked through the following questions for GraphQL code generation | ||
? Do you want to generate code for your newly created GraphQL API? Y | ||
? Choose the code generation language target: javascript | ||
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions? Y | ||
? Enter maximum statement depth [increase from default if your schema is deeply nested]: 2 | ||
``` | ||
Now the API and database have been deployed and you can start interacting with it. | ||
The API you have deployed is for a Todo app, including operations for creating, reading, updating, deleting, and listing todos. | ||
To view the GraphQL API in the AppSync console at any time, run the following command: | ||
```sh | ||
amplify console api | ||
``` | ||
To view your entire app in the Amplify console at any time, run the following command: | ||
```sh | ||
amplify console | ||
``` | ||
## Connect frontend to API | ||
For a user interface to interact with this API, you will create a way to list and create todos. To do this, you will create a form with a button to create todos and way to fetch and render a list of todos. | ||
Open __src/App.js__ and update it with the following code: | ||
```javascript | ||
/* src/App.js */ | ||
import React, { useEffect, useState } from 'react' | ||
import { API, graphqlOperation } from 'aws-amplify' | ||
import { createTodo } from './graphql/mutations' | ||
import { listTodos } from './graphql/queries' | ||
const initialState = { name: '', description: '' } | ||
const App = () => { | ||
const [formState, setFormState] = useState(initialState) | ||
const [todos, setTodos] = useState([]) | ||
useEffect(() => { | ||
fetchTodos() | ||
}, []) | ||
function setInput(key, value) { | ||
setFormState({ ...formState, [key]: value }) | ||
} | ||
async function fetchTodos() { | ||
try { | ||
const todoData = await API.graphql(graphqlOperation(listTodos)) | ||
const todos = todoData.data.listTodos.items | ||
setTodos(todos) | ||
} catch (err) { console.log('error fetching todos') } | ||
} | ||
async function addTodo() { | ||
try { | ||
const todo = { ...formState } | ||
setTodos([...todos, todo]) | ||
setFormState(initialState) | ||
await API.graphql(graphqlOperation(createTodo, {input: todo})) | ||
} catch (err) { | ||
console.log('error creating todo:', err) | ||
} | ||
} | ||
return ( | ||
<div style={styles.container}> | ||
<h2>Amplify Todos</h2> | ||
<input | ||
onChange={event => setInput('name', event.target.value)} | ||
style={styles.input} | ||
value={formState.name} | ||
placeholder="Name" | ||
/> | ||
<input | ||
onChange={event => setInput('description', event.target.value)} | ||
style={styles.input} | ||
value={formState.description} | ||
placeholder="Description" | ||
/> | ||
<button style={styles.button} onClick={addTodo}>Create Todo</button> | ||
{ | ||
todos.map((todo, index) => ( | ||
<div key={todo.id ? todo.id : index} style={styles.todo}> | ||
<p style={styles.todoName}>{todo.name}</p> | ||
<p style={styles.todoDescription}>{todo.description}</p> | ||
</div> | ||
)) | ||
} | ||
</div> | ||
) | ||
} | ||
const styles = { | ||
container: { width: 400, margin: '0 auto', display: 'flex', flex: 1, flexDirection: 'column', justifyContent: 'center', padding: 20 }, | ||
todo: { marginBottom: 15 }, | ||
input: { border: 'none', backgroundColor: '#ddd', marginBottom: 10, padding: 8, fontSize: 18 }, | ||
todoName: { fontSize: 20, fontWeight: 'bold' }, | ||
todoDescription: { marginBottom: 0 }, | ||
button: { backgroundColor: 'black', color: 'white', outline: 'none', fontSize: 18, padding: '12px 0px' } | ||
} | ||
export default App | ||
``` | ||
|
||
Let's walk through some of the functions: | ||
__useEffect__ - When the component loads, the `useEffect` hook is called and it invokes the `fetchTodos` function. | ||
__fetchTodos__ - Uses the Amplify `API` category to call the AppSync GraphQL API with the `listTodos` query. Once the data is returned, the items array is passed in to the `setTodos` function to update the local state. | ||
__createTodo__ - Uses the Amplify `API` category to call the AppSync GraphQL API with the `createTodo` mutation. A difference between the `listTodos` query and the `createTodo` mutation is that `createTodo` accepts an argument containing the variables needed for the mutation. | ||
## Run locally | ||
Next, run the app and you should see the form rendered to the screen and be able to create and view the list of todos: | ||
```sh | ||
npm start | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,65 @@ | ||
Now that our project is set up, the first thing we'll do is add authentication. This way we can keep track of which photos belong to which users, as well as make sure only people registered for the app can upload photos. | ||
The next feature you will be adding is authentication. | ||
|
||
## Authentication with Amplify | ||
|
||
The Amplify Framework uses [Amazon Cognito](https://aws.amazon.com/cognito/) as the main authentication provider. Amazon Cognito is a robust user directory service that handles user registration, authentication, account recovery & other operations. In this tutorial, you'll learn how to add authentication to your application using Amazon Cognito and username/password login. | ||
|
||
## Create authentication backend | ||
## Create authentication service | ||
|
||
We'll use the Amplify CLI to add the `auth` category to our project. From the root of your project, run the following: | ||
|
||
```bash | ||
```sh | ||
amplify add auth | ||
``` | ||
|
||
The CLI will prompt you for more information, | ||
|
||
```bash | ||
Do you want to use the default authentication and security configuration (default configuration) | ||
|
||
How do you want users to be able to sign in (Username) | ||
|
||
Do you want to configure advanced settings (No, I am done) | ||
? Do you want to use the default authentication and security configuration? Default configuration | ||
? How do you want users to be able to sign in? Username | ||
? Do you want to configure advanced settings? No, I am done. | ||
``` | ||
|
||
This will use the default settings in Cognito for username/password login. Now that we've defined our authentication needs it's time to deploy our Cognito user pool on AWS. To do that run: | ||
To deploy the service, run the `push` command: | ||
|
||
```bash | ||
```sh | ||
amplify push | ||
``` | ||
|
||
The Amplify `push` command takes the templates generated by the Amplify CLI and pushes them to the cloud. Your AWS resources are then updated to match the new requirements. | ||
? Are you sure you want to continue? Y | ||
``` | ||
|
||
Now, the authentication service has been deployed and you can start using it. To view the services deployed in your project at any time, run the following command: | ||
Now, the authentication service has been deployed and you can start using it. To view the deployed services in your project at any time, go to Amplify Console by running the following command: | ||
|
||
```sh | ||
$ amplify console | ||
amplify console | ||
``` | ||
|
||
## Create login UI | ||
|
||
Now that we have our authentication backend deployed to AWS, it's time to add authentication to our React app. Creating the login flow can be quite difficult and time consuming to get right. Luckily Amplify Framework has an authentication UI component we can use that will provide the entire authentication flow for us, using our configuration specified in our `aws-exports.js` file. | ||
Now that we have our authentication service deployed to AWS, it's time to add authentication to our React app. Creating the login flow can be quite difficult and time consuming to get right. Luckily Amplify Framework has an authentication UI component we can use that will provide the entire authentication flow for us, using our configuration specified in our __aws-exports.js__ file. | ||
|
||
Open __src/App.js__ and make the following changes: | ||
|
||
In your editor, open up `src/App.js` and replace it with the following: | ||
1. Import the `withAuthenticator` component: | ||
|
||
```javascript | ||
import React from "react"; | ||
import "./App.css"; | ||
import { withAuthenticator } from "aws-amplify-react"; | ||
|
||
function App() { | ||
return ( | ||
<div className="App"> | ||
<header className="App-header"> | ||
<p> | ||
Edit <code>src/App.js</code> and save to reload. | ||
</p> | ||
<a | ||
className="App-link" | ||
href="https://reactjs.org" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
Learn React | ||
</a> | ||
</header> | ||
</div> | ||
); | ||
} | ||
|
||
export default withAuthenticator(App, true); | ||
import { withAuthenticator } from 'aws-amplify-react' | ||
``` | ||
|
||
Run `npm start` to launch `localhost` to see the authentication UI below: | ||
2. Change the default export to be the `withAuthenticator` wrapping the main component: | ||
|
||
```javascript | ||
export default withAuthenticator(App) | ||
``` | ||
|
||
Run the app to see the new Authentication flow protecting the app: | ||
|
||
```sh | ||
npm start | ||
``` | ||
|
||
Now you should see the app load with an authentication flow allowing users to sign up and sign in. | ||
|
||
In this example, you used the React Native UI library and the `withAuthenticator` to quickly get up and running with a real-world authentication flow. | ||
|
||
You can also customize this component to add or remove fields, update styling, or other configurations. To configure this component, check out the documentation [here](). | ||
|
||
![login screen](https://raw.githubusercontent.com/aws-samples/create-react-app-auth-amplify/master/src/images/auth.gif) | ||
In addition to the `withAuthenticator` you can build custom authentication flows using the `Auth` class. | ||
|
||
Now that we have login support, go ahead and create a user. Once you successfully login, you should see the React boilerplate along with a new header and logout button. The header is part of the authentication component and can be customized or removed. We'll leave it here so we can focus on the photo sharing functionality. | ||
`Auth` has over 30 methods including `signUp`, `signIn`, `forgotPasword`, and `signOut` that allow you full control over all aspects of the user authentication flow. Check out the complete API [here](https://aws-amplify.github.io/amplify-js/api/classes/authclass.html) | ||
|
||
In the next step, we'll set our data model and API so that we can upload and display photos. | ||
In the next section, you'll host your app on the Amplify Console, a hosting service complete with a globally available CDN, atomic deployments, easy custom domains, and CI / CD. |
Oops, something went wrong.