29
loading...
This website collects cookies to deliver better user experience
npx create-next-app national-parks
amplify init
amplify add auth
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.
amplify add storage
? Please select from one of the below mentioned services: Content (Images, audio, video, etc.)
? Please provide a friendly name for your resource that will be used to label this category in the project: s37cd140d1
? Please provide bucket name: nationalparkbrowser248f6fd94d4f46f99a951df475e8
? Who should have access: Auth and guest users
? What kind of access do you want for Authenticated users? create/update, read, delete
? What kind of access do you want for Guest users? read
? Do you want to add a Lambda Trigger for your S3 Bucket? No
amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: nationalparks
? Choose the default authorization type for the API API key
? Enter a description for the API key:
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)
amplify/backend/api/nationalparks
. There will be a sample GraphQL schema already in there, but we'll edit it to have the data format we need.Park
will store our parks -- each park will have an id, a name, and an image. That image will reference an image stored in Amazon S3 (we created a bucket when we ran amplify add storage
). The S3Object
will have information about the image stored on S3 -- it's bucket, region, and key. We'll use the key to access the images in our app.type S3Object {
bucket: String!
region: String!
key: String!
}
type Park @model {
id: ID!
name: String!
image: S3Object
}
amplify push
to deploy your resources to the cloud! You now have a fully deployed backend.npm i aws-amplify @aws-amplify/ui-react
Amplify.configure()
. We'll use the configuration information in the src/aws-exports.js
file that's automatically generated by Amplify and also make sure to set the ssr
flag to true
so that we can pull from our API on the server.pages/_app.js
:import Amplify from 'aws-amplify'
import config from '../src/aws-exports'
Amplify.configure({ ...config, ssr: true })
pages/create-park.js
that will house a page that will render our form. Create a React component in the file.// create-park.js
function CreatePark () {
return <h1>Create Park</h1>
}
export default CreatePark
withAuthenticator
higher-order component to require sign in before going to the /create-park
page. It will also enable sign up and require account confirmation.// create-park.js
import { withAuthenticator } from '@aws-amplify/ui-react'
function CreatePark () {
return <h1>Create Park</h1>
}
export default withAuthenticator(CreatePark)
// create-park.js
import { useState } from 'react'
import { withAuthenticator } from '@aws-amplify/ui-react'
function CreatePark () {
const [name, setName] = useState('')
const [image, setImage] = useState('')
const handleSubmit = async () => {
}
return (
<form onSubmit={handleSubmit}>
<h2>Create a Park</h2>
<label htmlFor='name'>Name</label>
<input type='text' id='name' onChange={e => setName(e.target.value)} />
<label htmlFor='image'>Image</label>
<input type='file' id='image' onChange={e => setImage(e.target.files[0])} />
<input type='submit' value='create' />
</form>
)
}
export default withAuthenticator(CreatePark)
handleSubmit
function which will upload the user's image to S3 and then store our newly created park in our data base using our GraphQL API. We'll import the configuration information from the aws-exports.js
again and one of the GraphQL mutations that Amplify generated in the src/graphql
directory.Storage.put()
with the image's name as the key and the image itself as the value. Then, we'll use API.graphql
to run the graphQL mutation with the user's inputted data and configuration information about the S3 bucket.// create-park.js
import { useState } from 'react'
import { API, Storage } from 'aws-amplify'
import { withAuthenticator } from '@aws-amplify/ui-react'
import { createPark } from '../src/graphql/mutations'
import config from '../src/aws-exports'
function CreatePark () {
const [name, setName] = useState('')
const [image, setImage] = useState('')
const handleSubmit = async e => {
e.preventDefault()
// upload the image to S3
const uploadedImage = await Storage.put(image.name, image)
console.log(uploadedImage)
// submit the GraphQL query
const newPark = await API.graphql({
query: createPark,
variables: {
input: {
name,
image: {
// use the image's region and bucket (from aws-exports) as well as the key from the uploaded image
region: config.aws_user_files_s3_bucket_region,
bucket: config.aws_user_files_s3_bucket,
key: uploadedImage.key
}
}
}
})
console.log(newPark)
}
return (
<form onSubmit={handleSubmit}>
<h2>Create a Park</h2>
<label htmlFor='name'>Name</label>
<input type='text' id='name' onChange={e => setName(e.target.value)} />
<label htmlFor='image'>Image</label>
<input type='file' id='image' onChange={e => setImage(e.target.files[0])} />
<input type='submit' value='create' />
</form>
)
}
export default withAuthenticator(CreatePark)
styles/globals.css
file to make the app look a little more presentable.amplify-s3-image {
--width: 70%;
overflow: hidden;
margin: 0 auto;
}
.container {
max-width: 1000px;
margin: 0 auto;
padding: 0 2rem;
text-align: center;
}
.img-square img h2 {
margin: 0 auto;
text-align: center;
}
listParks
graphql query that was generated in src/graphql/queries.js
to fetch the parks and the AmplifyS3Image
component to render the images on the page. We'll fetch the parks on the server-side so that our app will dynamically update when new parks are added.import Head from 'next/head'
import { withSSRContext } from 'aws-amplify'
import { listParks } from '../src/graphql/queries'
import { AmplifyS3Image } from '@aws-amplify/ui-react'
import Link from 'next/link'
export async function getServerSideProps () {
const SSR = withSSRContext()
const { data } = await SSR.API.graphql({ query: listParks })
return {
props: {
parks: data.listParks.items
}
}
}
export default function Home ({ parks }) {
return (
<div>
<Head>
<title>National Parks</title>
</Head>
<div className='container'>
<h1>National Parks <Link href='/create-park'>(+)</Link></h1>
<div className='img-grid'>
{parks.map(park => {
return (
<div key={park.id} className='img-square'>
<h2>{park.name}</h2>
{/* use the AmplifyS3Image component to render the park's image using its S3 key */}
<AmplifyS3Image imgKey={park.image.key} height='200px' />
</div>
)
})}
</div>
</div>
</div>
)
}
frontend environments tab
and then the connect app
button. Choose your repository, use the auto generated configuration, and save and deploy
. It'll take a few minutes and then your app will be live!delete app
button in the AWS console or run amplify delete
from your command line. This will de-provision your backend resources from your AWS account!