AWS Amplify: A Friend Indeed

AWS Amplify: A Friend Indeed

Sep 18, 2022ยท

10 min read

INTRODUCTION

If it weren't for the AWS Amplify x Hashnode hackathon for this September month, I wouldn't have known of this awesome framework that would very easily help you build full-stack apps in just a few hours.

The start of my journey in exploring AWS Amplify wasn't merry at all, a fair share of it is because I was too excited to try it out first and then do basic things. So, that's a fault on my side. For beginners, it could take a little time to understand all the pieces but it would be all worth it.

Here are a few errors I observed from my initial development :

  • This is when your auth component isn't integrated correctly. image.png

  • Builds can fail for several reasons, here's an example: image.png You can view detailed logs by downloading them from the console. In this case, the error was due to unrecognised flags for graphqltransformer on amplify/cli.json

    2022-09-17T14:58:09.580Z [INFO]: These feature flags are defined in the "amplify/cli.json" configuration file and are unknown to the currently running Amplify CLI:
                                     - graphqltransformer.showfieldauthnotification
                                     - graphqltransformer.usesubusernamefordefaultidentityclaim
                                     - graphqltransformer.usefieldnameforprimarykeyconnectionfield
                                     - graphqltransformer.enableautoindexquerynames
                                     - graphqltransformer.respectprimarykeyattributesonconnectionfield
                                     - graphqltransformer.shoulddeepmergedirectiveconfigdefaults
                                     - graphqltransformer.populateownerfieldforstaticgroupauth
                                   This issue likely happens when the project has been pushed with a newer version of Amplify CLI, try updating to a newer version.
                                   Ensure that the CI/CD pipeline is not using an older or pinned down version of Amplify CLI.
                                   Learn more about feature flags: https://docs.amplify.aws/cli/reference/feature-flags
    
  • The other kind of errors you could probably see is Unexpected Token in JSON error
  • For NextJS you'll require few more changes, use < img > instead of < Image > and this below change on package.json file.
    "scripts": {
      "dev": "next dev",
      "build": "next build && next export",
      "start": "next start"
    }
    
    Honestly, I've have had to start over a lot of times that I've lost count on which attempt I was able to get all pieces working but the learning curve was just brilliant. All the hiccups were worthy to my learning. Each stumbling block and the errors I hit taught me where exactly I was going wrong. Of course, due credits to amazing community members who documented their AWS Amplify setups and StackOverflow is where you should find answers to most of the questions.

There's so much made available to you that you'd still be all set with minimal coding given all the amazing baked in templates for you to just edit and customize for your app needs. If you enable full-stack continuous deployments (CI/CD), as soon as you do a fresh commit, a new build be scheduled to deploy your latest changes -

image.png

First things first, don't make the same mistakes as me. I tried different variants of Auth, Data Models, API mixing up with the AWS Console and Amplify CLI which is why I had to keep building my app from the scratch. If you are completely new to AWS Amplify, please, pretty please watch the tutorial videos and properly read the documentation. Once you have done that, decide what are the components would you like build on AWS Amplify, and with what language.

I finally picked NextJs for frontend and GraphQL (API) for backend. I was conflicted to go with react native and Vue, but NextJs makes things a lot more simpler. Interesting part being, I had seen easier and quicker implementation videos of NextJs apps and hence the feeling of it will help me build my app faster. Of course, I was mistaken. Anything new takes its due course to understand. To top that, I am not familiar with GraphQL either. This is why AWS Amplify can truly be your buddy as you get started to build your apps.

Here's a video on Full Stack Photobook app with vue, graphQL variant if you'd like to refer.

DETAILS

  • Front-End: NextJs
  • API: GraphQL,
  • Storage: DyanamoDB (auto created as part of amplify add api step) image.png
  • Hosting, API, Authentication: AWS Amplify

IMPLEMENTATION

  • To create new nextjs app:
    npx create-next-app@latest
    
  • Install amplify cli or follow steps from Install Amplify CLI
    npm install -g @aws-amplify/cli
    
  • From AWS Amplify Studio, create new app -

image.png image.png

  • Configure Auth from Amplify Studio

image.png

image.png

image.png

  • After Auth is deployed, do amplify pull as instructed on your screen with your amplify appId
  • Install aws-amplify, note: This will take really long time to fully install, as it will install all the modules for aws-amplify, if you would like to keep your node_modules/build size smaller, import selectively. This medium article explains it.
    npm install aws-amplify
    
  • Import Auth
    import { Auth } from "aws-amplify";
    
  • For the login page/authentication, I used Auth with username and email verification,
    It was fairly easy to integrate the auth piece. I'd recommend adding Auth from the AWS console, because I faced some challenges to set the settings right when I tried directly from the amplify cli and it hadn't synced up settings correctly.

  • To use Amplify Auth, simply wrap your index page with Authenticator:

    export default withAuthenticator(MyApp);
    

    image.png You can customize your sign in pages if you like, and have a specific/custom user config also defined. Here's what my _app.js looks like:

import { Amplify, Auth } from "aws-amplify";
import { Link, withAuthenticator } from "@aws-amplify/ui-react";
import React, { useState, useEffect } from "react";
import "@aws-amplify/ui-react/styles.css";
import awsconfig from "../src/aws-exports";

Amplify.configure(awsconfig);

function MyApp({ Component, pageProps }) {
  const [user, setUser] = useState();
  useEffect(() => {
    const getUser = async () => {
      try {
        const user = await Auth.currentAuthenticatedUser();
        setUser(user);
      } catch (err) {
        console.log(err);
      }
    };
    getUser();
  }, []);

  return (
    <div>
        <nav className="navbar bg-dark justify-content-end">
        {user ? (
          <button
            className="btn btn-sm btn-info right"
            onClick={async () => {
              await Auth.signOut();
              setUser(null);
            }}
          >
            Sign Out
          </button>
        ) : (
          <Link href="/">Sign In</Link>
        )}

        <div>&nbsp;&nbsp;</div>
      </nav>
      <br></br>
      <div className="d-flex justify-content-start">
        &nbsp; &nbsp;{" "}
        <Link href="/">
          <button className="btn btn-sm btn-dark">๐Ÿ  Home</button>
        </Link>
      </div>
      <Component {...pageProps} />
    </div>
  );
}
export default withAuthenticator(MyApp);

I went for a simple home screen, with name of the logged in user printed and card styles,

  • For listing the existing playlists
  • For listing songs
  • For creating new playlist

I had few long-term ideas I wanted to work on which I knew I would take a good long while to implement. Hence, I decided to go with something basic so that I get comfortable with how to connect things and use amplify for all best things.

image.png

  • After I got the auth piece working, I wanted to add the API
    amplify add api
    ? Select from one of the below mentioned services: (Use arrow keys)
    > GraphQL
    REST
    
    ? Do you want to generate code for your newly created GraphQL API **Yes**
    ? Choose the code generation language target javascript
    ? 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
    

After the above step - skeletal structure for queries, mutations, subscriptions and setup for API was ready. On the auto generated schema, all I had to do was to modify it as per my requirement, I created model for Playlist, Song, Album, it looks like this:

type Playlist @model {
  id: ID!
  name: String!
  songs: [Song] @hasMany
}

type Song @model {
  id: ID!
  title: String!
  playlist: Playlist @belongsTo
  albums: [Album] @hasMany
}

type Album @model {
  id: ID!
  song: Song @belongsTo
  content: String!
}

You'll see your endpoint details after the first amplify push:

GraphQL endpoint: https://xyz.appsync-api.us-east-2.amazonaws.com/graphql
GraphQL API KEY: da2-xyz
GraphQL transformer version: 2
  • Once my edits were done, I did amplify push to sync the changes.
    amplify push
    
  • To check the status, you can run amplify status, if there are no new changes, you'll see something like below
amplify status
CategoryResource nameOperationProvider plugin
AuthmilocuratorNo Changeawscloudformation
ApimilocuratorNo Changeawscloudformation
  • There are ample videos on YouTube you could watch to learn, here's an example for react:

And if you are making the project on NextJs + GraphQL as well, you can refer documentation here.

  • For data creation, you can make use of AppSync or run GraphQL queries from Postman/Insomnia. Remember to add X-Api-Key header with API key that was generated for you after the amplify add api step.

image.png

  • Here's what /playlist/1 screen looks for me:

image.png

  • Currently, I have only implemented list/get functions, updates/deletes/subscriptions would be the next steps.
  • Add hosting for your app - by adding your Repo/Zip File. Detailed steps can be referred from here image.png

  • If you are seeing access denied, it is either because your final build directory is wrongly defined or due to missing permissions, this doc could help. If you would like to modify your build settings, you could do it here:

image.png

You can choose to have custom pre-build steps as well if you like, the yaml reference and the steps can be found here.

  • To setup your app on custom domain, you can follow steps here

  • If you would like to dive into more detailed documentation, I'd suggest starting from AWS Amplify Docs and here.

  • My app is currently hosted here. You can try creating a new user or use a test user,

    username: amplify-user
    password: Test@123
    
  • Project Link: Milo Curator

WHY PLAYLIST CURATOR?

  • The idea was to build something similar to ToDo App with all flows. With more features like being able to upload mp4/media files, map similar songs, filter searches by same musical notes - this app could be useful to music artists, who would like to keep a backup of any new music they are creating and would like to keep reference of similar music for inspiration.
  • The original intention was to build something which could help me organize my playlist into different buckets - based on time of day, mood, occasion, source of original song collection, specifically looking for similar songs while exploring for something new (Wynk/Spotify and other music streaming apps already do that - but I am looking for is a combined effect of something that could help me find new songs I could potentially like based on historical likes and auto create playlist for me based on the choice of classification)
  • Although, I wasn't able to implement much of it for this project, perhaps in future when I am slightly familiar with enough machine learning to try that out, I will.

AWS Amplify - An Awesome Friend

  • It can be ussed with multiple frameworks : image.png
  • UI-driven approach to building apps, enhances web/mobile app building experience, performance for sure.
  • Auth, Storage, AppSync components are amazing. What's more amazing is predictions, interactions and notifications: image.png. I haven't tried them for this project, but hoping to someday. Imagine having the full power of AWS Amplify.

BEST WISHES & THANK YOU

All the best to all the participants on this Hackathon, hope their learning journey would have been as fun and exciting as it was for me. Thank you AWS Amplify & Hashnode team for organizing this, without this motivation I don't think I would have tried building something myself. Another call out for a friend who was around to motivate me, and insisted on taking timely breaks so I could hop on back with more ideas. Good part, I couldn't take take my mind off working on this project until I got the basic flow right. Tiresome part, I hardly slept on weekends. The best part is finding something you are so driven by that you won't rest until you get it done. This opportunity was one such for me.

ย