Membuat aplikasi menggunakan AWS Amplify

Apa itu AWS Amplify?

AWS Amplify adalah kumpulan tools & service yang digunakan untuk mengembangkan aplikasi Full Stack (mobile & web) yang terintegrasi dengan layanan cloud computing dari Amazon Web Service (AWS).

Dengan menggunakan AWS Amplify kita bisa gunakan layanan cloud computing AWS untuk membuat backend dari aplikasi, seperti database, API, storage, hosting & authentication.

Jadi tugas seorang full stack developer hanya membuat Frontend untuk kemudian diintegrasikan dengan layanan backend dari AWS. Tanpa harus install database, membuat server untuk hosting, install library untuk autentikasi dll.

Jika kamu sudah pernah menggunakan Firebase, maka konsep AWS Amplify mirip dengan Firebase tapi berbeda pada fitur yang dimiliki.

BaaS

Sebelum melanjutkan kita perlu bahas tentang Backend as a Service (BaaS).

BaaS adalah model layanan cloud dimana Backend dari aplikasi dikelola oleh pihak lain.

Ketika kita menggunakan layanan BaaS maka kita fokus pada frontend dan bagaimana menghubungkan frontend yang dibuat dengan layanan BaaS.

Pada umumnya layanan BaaS meliputi Database Management, API, Cloud Storage, Authentication System, Hosting, Real Time Monitoring, Push Notification dll. Apakah AWS Amplify termasuk BaaS?

Bisa dikatakan iya, karena AWS Amplify menyediakan semua yang kita butuhkan untuk membuat sebuah backend memanfaatkan teknologi cloud.

Tetapi kita juga bisa memilih untuk tidak menggunakan semua layanan yang ada pada AWS Amplify, AWS Amplify menyediakan open source framework bernama Amplify Framework untuk mengintegrasikan frontend aplikasi dengan satu atau lebih layanan cloud AWS. 

Jenis Aplikasi

Jenis aplikasi seperti apa yang bisa kita bangun menggunakan AWS Amplify?

Saat tulisan ini dibuat AWS Amplify mendukung banyak web framework seperti React, Angular, Vue, Next.js. Sedangkan untuk mobile platform AWS Amplify mendukung Android, iOS, React Native, Ionic, Flutter (Preview).

Tools

AWS Amplify bisa dibagi menjadi 2 bagian:

  • Amplify Frameworks
  • Amplify Console

Amplify Frameworks

Sebuah open source framework yang terdiri dari:

  • Amplify CLI, cli untuk mengkonfigurasi semua layanan yang ada
  • Amplify Libraries, kumpulan libraries untuk menambahkan fitur ke aplikasi
  • Amplify UI Components, komponen UI tinggal pakai yang memiliki fungsi tertentu

Amplify Console

Sebuah Console untuk membantu proses deployment aplikasi baik frontend ataupun backend.

Tools atau service yang ada di dalam Amplify Console:

Amplify Hosting, untuk membantu proses hosting aplikasi (frontend) dilengkapi dengan CI/CD

Admin UI, semacam dashboard untuk mengatur dan mengelola backend yang bisa dikases dari luar AWS Management Console

Bagi yang belum pernah menggunakan AWS, untuk mengoperasikan semua layanan dari AWS kita harus login ke AWS Management Console. Dengan adanya Admin UI ini kita tidak perlu login ke AWS Managament Console dan bahkan kita tidak perlu memiliki sebuah akun AWS.

Features

Beberapa fitur dari AWS Amplify:

  • Datastore

Storage engine dengan kemampuan sinkronisasi offline, layanan yang digunakan adalah AWS AppSync & Amazon DynamoDB.  Dengan datastore, data masih bisa diakses meskipun dalam kondisi offline, sinkronisasi data antara device atau client dengan server akan dilakukan di background.

  • Storage

Data aplikasi berupa object seperti file gambar, video dapat disimpan di cloud storage S3.

  • Serverless API

Kita bisa memilih antara menggunakan REST API atau GraphQL.

  • Authentication

Sistem autentikasi yang terintegrasi dengan layanan Amazon Cognito.

  • Analytics

Membuat analisa dari penggunaan aplikasi.

Selain fitur yang disebutkan diatas masih ada fitur Push Notification, PubSub, Interaction(Chatbots) dan AI/ML predictions.

Penggunaan 

Tiga kondisi dimana AWS Amplify bisa digunakan atau bisa menjadi solusi:

  1. Membuat backend dari awal
  2. Menghubungkan frontend dengan backend yang sudah ada
  3. Hosting static web app

Membuat Backend

Pada bagian ini kita akan membuat sebuah aplikasi untuk membuat postingan singkat secara acak yang kita sebut dengan Random Post Generator.  Dengan React sebagai frontend dan AWS Amplify sebagai backend.

Arsiktektur Aplikasi

Tradisional

Maksud tradisional disini adalah backend dikelola sendiri dalam suatu server.

traditional web app

AWS Amplify

aws amplify

Step by Step

Membuat backend di AWS Amplify bisa dilakukan dengan mudah menggunakan Admin UI.

Kita bisa menggunakan Admin UI tanpa akun AWS, tetapi aplikasi hanya bisa dijalankan terbatas di komputer lokal. Agar aplikasi bisa di deploy maka kita butuh sebuah akun AWS. Buat akun AWS disini. (Registrasi akun AWS membutuhkan kartu kredit atau kartu debit online)

Jika tetap ingin mencoba tanpa akun AWS gunakan amplify sandbox

Akses AWS Amplify Console

Langkah pertama adalah login ke AWS Management Console kemudian pada menu Services pilih atau cari AWS Amplify. (Optional) Pilih region AWS terdekat. 

Tampilan AWS Amplify Console:

aws amplify console

Buat Aplikasi

Buat sebuah aplikasi baru *New app -> Create backend app.

create new app backend

Kemudian beri nama aplikasi random-post-generator.

name new backend app

Proses deployment memakan waktu beberapa menit.

Setelah proses deployment backend selesai, selanjutnya kita akan melakukan 3 hal:

  1. Membuat Data Model
  2. Menambah Sistem autentikasi
  3. Deploy Frontend (Hosting)

Membuat Data Model

Buka Admin UI kemudian pilih menu DataSource.

admin ui datastore 1

admin ui datastore 2

Dari menu drop down pilih Add Model.

Model data dari aplikasi kita buat sangat sederhana, terdiri dari satu model bernama Post dengan 4 field, yaitu id, title, content & author.

admin ui data modeling

Kemudian klik Save and Deploy.

Database yang digunakan adalah jenis NoSQL Database yaitu DynamoDB

Alur data dari front end ke database kurang lebih seperti ini:

amplify datastore sync workflow

Setiap data dari frontend akan disimpan di DataStore yang bersifat local untuk kemudian disinkronkan ke DynamoDB lewat AppSync.

Frontend

Saatnya berpindah ke local development atau frontend dari aplikasi.

Buat sebuah project React menggunakan create-react-app.

1$ npx create-react-app random-post-generator

Install AWS CLI:

1$ npm install -g @aws-amplify/cli

Kemudian package aws-amplify

1$ npm install aws-amplify @aws-amplify/ui-react

Tambahkan backend ke frontend dengan menjalankan perintah berikut:

1$ amplify pull --appId [appId] --envname staging

amplify pull

Saat menjalankan perintah aws amplify pull kita harus menjawab beberapa pertanyaan seperti ini:

? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: build
? Build Command: npm run-script build
? Start Command: npm run-script start
? Do you plan on modifying this backend? Yes

Setelah menjalankan perintah aws amplify pull kita akan dapati dua folder baru yaitu amplify & models.

amplify new folder created

amplify folder mewakili file backend dan models adalah folder berisi model data yang sudah kita buat di admin UI sebelumnya.

Sinkronisasi antara frontend & backend dapat dilakukan dua arah:

  • Backend ke frontend menggunakan perintah aws amplify pull
  • Frontend ke backend menggunakan perintah aws amplify push

Setiap kali kita melakukan update melalui admin UI maka kita perlu melakukan proses sinkronisasi menggunakan perintah aws amplify pull, sedangkan jika kita melakukan perubahan di sisi frontend maka sinkronisasi dilakukan dengan perintah aws amplify push.

CRUD

Selanjutnya kita update frontend agar bisa melakukan operasi CRUD.

  • Create, generate sebuah random post baru
  • Read, query data post yang sudah di generate
  • Update, ubah konten dari post dengan random post yang lain
  • Delete, hapus post yang sudah di generate

Styling

Update code di dalam file App.css dengan code berikut, yang akan digunakan untuk styling component yang ada:

1.App {
2 text-align: center;
3 display: flex;
4 flex-direction: column;
5 align-items: center;
6 justify-content: center;
7}
8.App-header {
9 font-size: calc(10px + 2vmin);
10}
11.App-link {
12 color: #61dafb;
13}
14.App-container {
15 max-width: 80vh;
16}
17.Content {
18 display: flex;
19 flex-direction: column;
20 align-items: center;
21 justify-content: center;
22 text-align: left;
23 padding: 1rem;
24 border: 1px dashed #111111;
25}
26.Toolbar {
27 display: flex;
28 justify-content: flex-end;
29 margin-bottom: 1rem;
30}
31.Button {
32 margin: 0.5rem;
33 padding: 0.75rem 1rem;
34 border: 0;
35 border-radius: 0.25rem;
36}
37.Generate {
38 background-color: #0073bb;
39 color: white;
40}
41.Update {
42 background-color: #EB5F07;
43 color: white;
44}
45.Delete {
46 background-color: #232F3E;
47 color: white;
48}
49.List {
50 list-style-type:none;
51}
52.List-item {
53 margin-bottom: 1rem;
54}
55.Action {
56 display: block;
57}

Setiap post yang dibuat akan disimpan di penyimpanan lokal DataStore yang akan tersinkronisasi secara otomatis dengan database DynamoDB di backend.

Untuk membuat random post dan random author kita akan gunakan package tambahan bernama Lorem Ipsum dan Unique Names Generator.

Install package dari terminal.

1$ yarn add lorem-ipsum unique-names-generator

Buat konfigurasi dari package lorem-ipsum dan unique-names-generator.

App.js

1import { LoremIpsum } from "lorem-ipsum";
2import { uniqueNamesGenerator, names } from "unique-names-generator";
3...
4const lorem = new LoremIpsum({
5 sentencesPerParagraph: {
6 max: 8,
7 min: 4,
8 },
9 wordsPerSentence: {
10 max: 16,
11 min: 4,
12 },
13});
14const config = {
15 dictionaries: [names],
16};
17...

Buat sebuah component dengan nama Toolbar yang berisi button untuk generate random post:

App.js

1...
2import { DataStore } from "@aws-amplify/datastore";
3...
4const Toolbar = () => {
5 const handleClick = async () => {
6 const title = lorem.generateWords(2);
7 const content = lorem.generateParagraphs(1);
8 const author = uniqueNamesGenerator(config);
9 await DataStore.save(
10 new Post({
11 title: title,
12 content: content,
13 author: author,
14 })
15 );
16 };
17return (
18 <div className="Toolbar">
19 <button className="Button Generate" onClick={handleClick}>
20 Generate Post
21 </button>
22 </div>
23 );
24};

Setiap kali button di klik sebuah random post akan disimpan ke dalam DataStore.

Kemudian untuk menampilkan data dari DataStore kita gunakan method DataStore.query() :

App.js

1import { useState, useEffect } from "react";
2...
3import { Post } from "./models";
4...
5const App = () => {
6 const [allPosts, setAllPosts] = useState(null);
7useEffect(() => {
8 async function getPosts() {
9 const posts = await DataStore.query(Post);
10 setAllPosts(posts);
11 }
12 getPosts();
13 }, [allPosts]);
14return (
15 <div className="App">
16 <header className="App-header">
17 <p>Random Post Generator</p>
18 </header>
19 <div className="App-container">
20 <Toolbar />
21 <div className="Content">
22 <ul className="List">
23 {allPosts &&
24 allPosts.map((post) => {
25 return (
26 <li className="List-item">
27 <h1>{post.title}</h1>
28 <p>Author: {post.author}</p>
29 <p>{post.content}</p>
30 </li>
31 );
32 })}
33 </ul>
34 </div>
35 </div>
36 </div>
37 );
38};
39export default App;

Sampai disini data masih disimpan di dalam DataStore dan belum disimpan pada database di backend.

Untuk proses sinkronisasi data ke backend kita perlu import konfigurasi yang ada di dalam file aws-export.js ke dalam aplikasi.

index.js

1...
2import Amplify from 'aws-amplify';
3import awsconfig from './aws-exports'
4Amplify.configure(awsconfig)
5...

Eksekusi perintah yarn start untuk menjalankan aplikasi, hasilnya:

Kita bisa lihat proses sinkronisasi berjalan (via grahpql) dengan melihat dari browser developer tools (Ctrl+Shift+I):

amplify check graphql sync

Dimana kita bisa melihat data yang sudah ditambah pada sisi backend?

Semua data akan disinkronkan dengan database DynamoDB, kita bisa akses lewat amplify console:

amplify check backend data 1

amplify check backend data 2

Jika kamu tidak menemukannya, pastikan kamu pilih region dimana kamu deploy backend pertama kali.

amplify check backend data 3

amplify check backend data 4

Selanjutnya yang akan kita lakukan adalah menambah button untuk update & delete.

App.js

1...
2// update
3const handleUpdate = async (id) => {
4 const content = lorem.generateParagraphs(1);
5 const original = await DataStore.query(Post, id);
6 await DataStore.save(
7 Post.copyOf(original, (item) => {
8 item.content = content;
9 })
10 );
11 };
12
13// delete
14const handleDelete = async (id) => {
15 const modelToDelete = await DataStore.query(Post, id);
16 DataStore.delete(modelToDelete);
17 };
18...
19 <div className="Action">
20 <button
21 className="Button Update"
22 onClick={() => handleUpdate(post.id)}
23 >
24 Random Update
25 </button>
26 <button
27 className="Button Delete"
28 onClick={() => handleDelete(post.id)}
29 >
30 Delete
31 </button>
32 </div>
33...

Hasilnya:

Menambah Sistem Autentikasi

Pada bagian ini kita akan membuat sistem autentikasi yang terdiri dari Sign Up, Sign In & Sign Out.

Sistem autentikasi pada AWS Amplify terintegrasi dengan layanan AWS cognito.

Buka Admin UI, pilih menu Authentication:

admin ui auth

Ada banyak mekanisme autentikasi yang bisa kita gunakan:

  • Email / Username
  • Phone Number
  • Facebook
  • Google
  • Amazon

Kita akan menggunakan mekanisme login menggunakan email.

Pada bagian Configure sign in pastikan memilih mekanisme email

admin ui auth configure login

Pada bagian Configure Sign Up > Password protection settings pilih email.

admin ui auth configure sign up

Kemudian klik Save & Deploy.

Frontend #2

Setelah deployment selesai eksekusi perintah amplify pull untuk proses sinkronisasi.

1$ amplify pull --appId [appId] --envname staging

AWS Amplify sudah menyediakan component untuk proses sign up, sign in & sign out yang bisa kita gunakan pada aplikasi React yang ada di daalam package aws-amplify/ui-react.

Pada file App.js di bagian component utama (App), tambahkan code berikut ini:

1import { AuthState, onAuthUIStateChange } from "@aws-amplify/ui-components";
2...
3const App = () => {
4 const [allPosts, setAllPosts] = useState(null);
5 const [authState, setAuthState] = useState();
6 const [user, setUser] = useState();
7 useEffect(() => {
8 onAuthUIStateChange((nextAuthState, authData) => {
9 setAuthState(nextAuthState);
10 setUser(authData);
11 });
12
13 async function getPosts() {
14 const posts = await DataStore.query(Post);
15 setAllPosts(posts);
16 }
17
18 getPosts();
19 }, [allPosts, authState]);
20...

Tambahan code diatas berfungsi menyimpan dan memonitor state dari hasil autentikasi yang akan kita gunakan untuk render component.

  • authState & setAuthState, menyimpan hasil autentikasi
  • user & setUser, state untuk menyimpan object user yang sudah terautentikasi
  • Sedangkan onAuthUIStateChange adalah method yang akan dieksekusi setiap terjadi perubahan component Autentikasi

Import component AmplifyAuthenticator yang akan menghandle proses login & sign up, serta AmplifySignOut untuk proses sign out.

Selanjutnya gunakan conditional rendering dimana jika user tidak melakukan login maka user akan diarahkan ke halaman login dan begitu sebaliknya.

1import { AmplifyAuthenticator, AmplifySignOut } from "@aws-amplify/ui-react";
2...
3return authState === AuthState.SignedIn && user ? (
4 <div className="App">
5 <AmplifySignOut />
6 <header className="App-header">
7 <p>My Blog</p>
8 </header>
9 <div className="App-container">
10 <Toolbar />
11 <div className="Content">
12 <ul className="List">
13 {allPosts &&
14 allPosts.map((post) => {
15 return (
16 <li className="List-item">
17 <h1>{post.title}</h1>
18 <p>Author: {post.author}</p>
19 <p>{post.content}</p>
20 <div className="Action">
21 <button
22 className="Button Update"
23 onClick={() => handleUpdate(post.id)}
24 >
25 Random Update
26 </button>
27 <button
28 className="Button Delete"
29 onClick={() => handleDelete(post.id)}
30 >
31 Delete
32 </button>
33 </div>
34 </li>
35 );
36 })}
37 </ul>
38 </div>
39 </div>
40 </div>
41 ) : (
42 <AmplifyAuthenticator />
43 );

Hasilnya jika kita akses aplikasi maka kita akan diarahkan ke halaman login:

amplify auth login

Kita bisa sign up dengan klik Create Account:

amplify auth sign up

Atau menambahkan user baru lewat Admin UI:

admin ui add user

Semua user yang terdaftar dapat dikelola dari Admin UI atau langsung ke halaman AWS Cognito.

Jika kita memilih menggunakan proses sign up maka kita harus melengkapi proses verifikasi via email.

Tampilan dari component autentikasi dapat diubah sesuai kebutuhan, untuk detailnya dapat dilihat disini.

Deploy Frontend (Hosting)

Langkah terakhir adalah deploy frontend.

Proses deploy-nya cukup mudah:

  1. Buat sebuah repository baru di Git provider seperti Github atau GitLab

  2. Kemudian hubungkan AWS Amplify ke Repository

Dari AWS Amplify Console (bukan Admin UI) pilih tab Frontend Environments, kemudian pilih Git provider dan klik Connect Branch.

amplify connect branch

Lengkapi proses authorisasi ke Git provider

  1. Pilih repository yang ingin dihubungkan

amplify add new repository

Setelah itu AWS Amplify akan melakukan proses deploy secara otomatis.

Setelah proses deploy selesai kita akan mendapatkan link dengan domain .amplifyapp.com.

Kita bisa mengganti domain dari aplikasi dengan custom domain lewat menu domain management:

amplify domain management

Kesimpulan

Jika kita ingin membuat sebuah aplikasi full stack dengan dukungan teknologi cloud dari AWS maka AWS Amplify bisa menjadi pilihan.