To configure Amplify you need to install the toolchain globally and initialize the Amplify functionality in your project folder.
Toolchain
Install the CLI toolchain:
npm install -g @aws-amplify/cli
Configure Amplify Tools
Configure Amplify:
amplify configure
Project Setup
Initialize Amplify in your project directory:
amplify init
Add Categories
Add functionality to your project:
amplify add [notifications, api, auth, custom, storage, analytics, function, geo, hosting, interactions, predictions, xr]
JS Lib + React UI
If using Amplify JS library and UI React library:
npm i @aws-amplify/ui-react aws-amplify
Add styles:
import '@aws-amplify/ui-react/styles.css';
Add fonts:
@import url('https://fonts.googleapis.com/css2?family=Inter:slnt,wght@-10..0,100..900&display=swap');
Deployment
To deploy the project run:
amplify push
AWS Amplify provides a declarative and easy-to-use authentication system that enables developers to create and manage user accounts.
Add category
Add and setup Authentication in your project:
amplify add auth
JS Lib: Sing-up, Sign-in, Sign-out
import { Auth } from 'aws-amplify';
const { user } = await Auth.signUp({
username,
password,
attributes: {
email,
},
autoSignIn: {
enabled: true,
}
});
const user = await Auth.signIn(username, password);
await Auth.signOut();
React Lib: Sing-up, Sign-in, Sign-out
import { Amplify } from 'aws-amplify';
import { Authenticator } from '@aws-amplify/ui-react';
import awsExports from './aws-exports';
Amplify.configure(awsExports);
<Authenticator>
{({ signOut, user }) => (
<main>
<h1>Logged in as: {user.username}</h1>
<button onClick={signOut}>Log out</button>
</main>
)}
</Authenticator>
Amplify UI library consists of connected components that simplify complex workflows like authentication and dynamic data, primitive components that form the building blocks of a UI, and themes to make Amplify UI fit any brand.
Cloud Connected Componenets
Auth Hook:
import { Amplify } from 'aws-amplify';
import awsExports from './aws-exports';
import { withAuthenticator } from '@aws-amplify/ui-react';
Amplify.configure(awsExports);
function App({ signOut, user }) {
return (
<>
<h1>Hello {user.username}</h1>
<button onClick={signOut}>Sign out</button>
</>
);
}
export default withAuthenticator(App);
File Uploader:
import { FileUploader } from '@aws-amplify/ui-react';
<FileUploader
acceptedFileTypes={['image/*']}
accessLevel="public"
/>
Account Settings component:
import { AccountSettings } from '@aws-amplify/ui-react';
<AccountSettings.ChangePassword onSuccess={handleSuccess}/>
<AccountSettings.DeleteUser onSuccess={handleSuccess} />
In App Messaging:
import { Amplify, Notifications } from 'aws-amplify';
import {
Text,
InAppMessagingProvider,
InAppMessageDisplay,
} from '@aws-amplify/ui-react';
const { InAppMessaging } = Notifications;
function App() {
useEffect(() => {
InAppMessaging.syncMessages();
}, []);
return (
<InAppMessagingProvider>
<InAppMessageDisplay />
<Text>In-App Messaging Example</Text>
</InAppMessagingProvider>
);
}
Map:
import { MapView } from '@aws-amplify/ui-react';
<MapView />
Components
Flexbox:
<Flex
direction="row"
justifyContent="flex-start"
alignItems="stretch"
alignContent="flex-start"
wrap="nowrap"
gap="1rem"
>
...
</Flex>
Text:
<Text
variation="primary"
as="p"
color="blue"
lineHeight="1.5em"
fontWeight={400}
fontSize="1em"
fontStyle="normal"
textDecoration="none"
width="30vw"
>
Hello World!
</Text>
Button:
<Button
variation="primary"
loadingText=""
onClick={() => alert('hello')}
ariaLabel=""
>
Click me!
</Button>
Textfield:
<TextField
descriptiveText="Enter a valid last name"
label="Last name"
errorMessage="There is an error"
/>
Theming
Wrap your app in ThemeProvider element:
import { ThemeProvider } from '@aws-amplify/ui-react';
//optionally define a custom theme
const customTheme = {...};
const App = (
<ThemeProvider theme={customTheme}>
<MyApp>/* AmplifyUI */</MyApp>
</ThemeProvider>
);
Override default theme values:
import { ThemeProvider, defaultTheme } from '@aws-amplify/ui-react';
const customTheme = {
name: 'my-theme',
overrides: [
{
colorMode: 'light',
tokens: {
colors: {
neutral: {
10: { value: defaultTheme.tokens.colors.neutral[100].value }
},
},
},
}
],
};
const App = (
<ThemeProvider theme={customTheme}>
<MyApp>AmplifyUI</MyApp>
</ThemeProvider>
);
CSS Overrides:
/* single element style */
.amplify-alert {
border-radius: 100px;
}
/* global styles */
:root, [data-amplify-theme] {
--amplify-primary-color: #333;
}
Responsive design:
<View
color={{
base: 'black',
small: 'black',
medium: 'black',
large: 'white',
xl: 'white',
xxl: 'white',
}}
>
Hello
</View>
Breakpoint hook:
import { Alert, useBreakpointValue } from '@aws-amplify/ui-react';
const variation = useBreakpointValue({
base: 'info',
small: 'warning',
medium: 'error',
large: 'success',
});
<Alert variation={variation}>Responsive Alert</Alert>;
The API service category allows developers to quickly create an API with a GraphQL schema, as well as configure authorization and access control.
Add category
amplify add api
Select GraphQL
as the service type.
Model Relationships
Has One
type Project @model {
id: ID!
name: String
team: Team @hasOne
}
type Team @model {
id: ID!
name: String!
}
Has Many
type Post @model {
id: ID!
title: String!
comments: [Comment] @hasMany
}
type Comment @model {
id: ID!
content: String!
}
Belongs To
type Post @model {
id: ID!
title: String!
comments: [Comment] @hasMany
}
type Comment @model {
id: ID!
content: String!
post: Post @belongsTo
}
Many To Many
type Post @model {
id: ID!
title: String!
content: String
tags: [Tag] @manyToMany(relationName: "PostTags")
}
type Tag @model {
id: ID!
label: String!
posts: [Post] @manyToMany(relationName: "PostTags")
}
Authorization
Public authorization grants unauthenticated users or devices access protected by API key.
type Todo @model @auth(rules: [{ allow: public }]) {
content: String
}
Owner authorization grants Cognito user access to specific CRUD permissions.
type Todo @model @auth(rules: [{ allow: owner, operations: [create, read, update] }]) {
content: String
}
Multi-User authorization grants multiple Cognito users access to specific CRUD permissions.
type Todo @model @auth(rules: [{ allow: owner, ownerField: "authors" }]) {
content: String
authors: [String]
}
Signed-in data access grants ANY signed-in user specific CRUD permissions.
type Todo @model @auth(rules: [{ allow: private }]) {
content: String
}
Queries and Mutations
Create an Item
import { API } from "aws-amplify";
import * as mutations from './graphql/mutations';
const todoDetails = {
name: 'Todo 1',
description: 'Learn AWS AppSync'
};
const newTodo = await API.graphql({ query: mutations.createTodo, variables: {input: todoDetails}});
Read Items
import { API } from 'aws-amplify';
import * as queries from './graphql/queries';
const allTodos = await API.graphql({ query: queries.listTodos });
console.log(allTodos);
const oneTodo = await API.graphql({
query: queries.getTodo,
variables: { id: 'some id' }
});
Update an Item
import { API } from "aws-amplify";
import * as mutations from './graphql/mutations';
const todoDetails = {
id: 'some_id',
description: 'My updated description!'
};
const updatedTodo = await API.graphql({ query: mutations.updateTodo, variables: {input: todoDetails}});
Delete an Item
import { API } from "aws-amplify";
import * as mutations from './graphql/mutations';
const todoDetails = {
id: 'some_id',
};
const deletedTodo = await API.graphql({ query: mutations.deleteTodo, variables: {input: todoDetails}});
Custom authorization
const todos = await API.graphql({
query: queries.listTodos,
authMode: 'AWS_IAM' | 'API_KEY' | 'AMAZON_COGNITO_USER_POOLS'
});
AWS Amplify provides a DataStore service to easily create and manage a backend database. The service allows developers to quickly create a database with offline and online synchronization capabilities.
Setup API
Set conflict detection as required if you have not done so:
amplify update api
Select the default resolution strategy -> Auto Merge
CRUD operations
Create:
import { DataStore } from 'aws-amplify';
await DataStore.save(
new Post({
title: 'My First Post',
rating: 10,
status: PostStatus.INACTIVE
})
);
Read:
// find by ID
const post = await DataStore.query(Post, "1234567");
// find by predicate
const posts = await DataStore.query(
Post,
(c) => c.and((c) => [
c.rating.gt(4),
c.status.eq(PostStatus.ACTIVE)
]),
{
sort: (s) => s.rating(SortDirection.ASCENDING),
page: 0,
limit: 100,
}
);
Update:
const original = await DataStore.query(Post, id);
await DataStore.save(
Post.copyOf(original, updated => {
updated.title = newTitle
})
);
Delete:
const original = await DataStore.query(Post, id);
DataStore.delete(original);
Real-time subscriptions
Observe single item:
const subscription = DataStore.observe(Post, id).subscribe(msg => {
console.log(msg.model, msg.opType, msg.element);
});
// Call unsubscribe to close the subscription
subscription.unsubscribe();
Observe collection:
const subscription = DataStore.observeQuery(
Post,
p => p.and(p => [
p.title.beginsWith("post"),
p.rating.gt(10)
]), {
sort: s => s.rating(SortDirection.ASCENDING)
}
).subscribe(snapshot => {
const { items, isSynced } = snapshot;
console.log(`[Snapshot] item count: ${items.length}, isSynced: ${isSynced}`);
});
The storage service allows developers to store and retrieve data from Amazon S3 and Amazon DynamoDB, as well as other cloud-based services. The Amplify Storage module provides APIs to read, write, and list files, as well as metadata information.
Add category
amplify add storage
For S3 bucket setup select Content
.
Uploads and Downloads
Upload:
async function onChange(e) {
const file = e.target.files[0];
try {
await Storage.put(file.name, file, {
contentType: "image/png",
level: "private" | "protected" | "public"
});
} catch (error) {
console.log("Error uploading file: ", error);
}
}
<input type="file" onChange={onChange} />;
Download link:
const signedURL = await Storage.get(key, {
level: "private" | "protected" | "public"
});
<a href={signedURL} target="_blank" rel='noreferrer'>{fileName}</a>
Download blob:
const result = await Storage.get('filename.txt', {
download: true
});
result.Body.text().then(string => {
// handle the String data return String
});
The API service allows developers to quickly create an API with REST endpoints, as well as configure authorization and access control.
Add category
amplify add api
Select REST
as the service type.
GET and POST
GET Data:
import { API } from "aws-amplify";
API.get("MyApiName", path, {
headers:{},
queryStringParameters:{}
})
.then((response) => {
// Add your code here
})
.catch((error) => {
console.log(error.response);
});
POST Data:
import { API } from "aws-amplify";
API.post("MyApiName", path, {
headers:{},
body:{}
})
.then((response) => {
// Add your code here
})
.catch((error) => {
console.log(error.response);
});