Terakhir diperbaharui: Jul 1, 2021
Membuat ulang Aplikasi DinoTes #1
Daftar Isi
1.Setup Next.js 2.Setup Tailwind CSS 3.Setup Backend AWS Amplify 4.Layout 5. Add New Note Page - Buat Component - Menambah API - Deploy API - Admin UI - Integrasi API1. Setup Next.js
Kita gunakan tool yang mirip dengan Create React App yaitu Create Next App untuk membuat sebuah project Next.js yang baru.
1$ npx create-next-app dinotes2# or3$ yarn create next-app dinotes
Gunakan perintah berikut untuk mengeksekusi aplikasi Next.js yang barus saja dibuat.
1$ yarn run dev
Hasilnya:
2. Setup Tailwind CSS
Untuk urusan styling kita gunakan CSS library yang sama dengan yang digunakan di aplikasi DinoTes sebelumnya yaitu Tailwind CSS. Tetapi tanpa menambahkan library styled-components.
Install Tailwind CSS dan package yang dibutuhkan.
1$ npm install -D tailwindcss@latest postcss@latest autoprefixer@latest23atau45$ yarn add -D tailwindcss@latest postcss@latest autoprefixer@latest
Selanjutnya kita perlu membuat file yang berisi informasi konfigurasi dari tailwind.
Jalankan perintah berikut:
1npx tailwindcss init -p
Hasilnya adalah dua file konfigurasi untuk Tailwind can PostCSS.
Update konfigurasi menjadi seperti ini agar Tailwind menghapus style yang tidak digunakan ketika berada di production environment.
1// tailwind.config.js2module.exports = {3 purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],4 darkMode: false,5 theme: {6 extend: {}7 },8 variants: {9 extend: {}10 },11 plugins: []12};
Langkah terakhir import Tailwind ke dalam project.
1// pages/_app.js23import 'tailwindcss/tailwind.css';45function MyApp({ Component, pageProps }) {6 return <Component {...pageProps} />;7}89export default MyApp;
Ganti isi dari file styles/global.css menjadi seperti ini:
1/* ./styles/globals.css */2@tailwind base;3@tailwind components;4@tailwind utilities;
Jalankan perintah yarn run dev
dari terminal dan akses alamat http://localhost:3000, jika tidak ada kendala kita akan mendapatkan tampilan seperti ini:
3. Setup Backend AWS Amplify
Dengan menggunakan AWS Amplify kita bisa tambahkan bagian backend aplikasi dengan mudah, backend disini meliputi API, database, autentikasi dll.
Dari root folder aplikasi DinoTes jalankan perintah berikut ini:
1$ amplify init
Proses konfigurasi amplify dilakukan dengan menjawab beberapa pertanyaan:
Untuk melihat backend yang sudah dibuat melalui perintah amplify init bisa dilakukan dengan cara login ke AWS Management Console dan pilih services - AWS Amplify
Perintah amplify init
secara otomatis akan membuat sebuah folder dengan nama amplify di dalam folder project yang berisi file backend.
Install Amplify Libraries
Install beberapa library yang akan digunakan pada proses pembuatan aplikasi.
1npm install aws-amplify @aws-amplify/ui-react23//atau45yarn add aws-amplify @aws-amplify/ui-react
4. Layout
Pada bagian ini kita akan membuat layout tampilan aplikasi DinoTes.
Layout adalah kumpulan shared component yang muncul di setiap page. Untuk membuat layout di Next.js kita buat sebuah folder baru bernama components.
Sehingga susunan folder menjadi seperti ini:
Isi dari Layout adalah Header, Footer dan children component yang mewakili component lain.
Header
Buat sebuah file baru bernama Header.js di dalam folder components kemudian tambahkan code berikut:
components/Header.js
1import React, { useState } from 'react';23const Header = () => {4 return (5 <>6 <div className="flex justify-between items-center border-b-2 border-gray-100 py-6 md:justify-start md:space-x-3">7 <img className="h-14 w-auto sm:h-16" src="/header-logo.png" alt="logo" />8 </div>9 </>10 );11};1213export default Header;
Tempatkan file header-logo.png di dalam folder public agar bisa diakses.
Footer
Buat sebuah file di dalam folder components bernama Footer.js dan tambahkan code berikut:
components/Footer.js
1import React from 'react';23const Footer = () => {4 return (5 <div className="m-4 p-2">6 <p>7 <a href="https://devsaurus.com">devsaurus</a> © 20218 </p>9 </div>10 );11};1213export default footer;
Selanjutnya buat sebuah file bernama Layout.js dan import component Header & Footer ke dalam file tersebut.
components/Layout.js
1import Header from './Header';2import Footer from './Footer';34const Layout = ({ children }) => {5 return (6 <div className="max-w-7xl mx-auto px-4 sm:px-6">7 <Header />8 {children}9 <Footer />10 </div>11 );12};1314export default Layout;
Ganti isi dari file index.js menjadi seperti ini:
1import Layout from '../components/Layout';23const Home = () => (4 <div className="text-center">5 <Layout />6 </div>7);89export default Home;
Hasil Akhir:
5. Add New Note Page
Halaman atau page pertama yang kita buat adalah halaman untuk menambahkan note atau catatan baru.
Step by step
Buat sebuah file baru bernama add.js di dalam folder pages.
Kemudian tambahkan code berikut:
pages/add.js
1import React from 'react';23import Layout from '../components/Layout';45const Add = () => {6 return (7 <Layout>8 <div className="flex flex-col items-center justify-center m-4">9 <p>This is Add Page</p>10 </div>11 </Layout>12 );13};1415export default Add;
Karena Next.js menggunakan sistem routing berdasarkan pages maka kita bisa akses halaman ini menggunakan alamat http://localhost:3000/add.
Setiap file yang ada di dalam folder pages dapat diakses menggunakan alamat yang sama dengan nama file.
Buat Component
Selanjutnya buat component utama dari halaman Add. Component utama ini berupa form yang berfungsi untuk menambahkan data note yang baru.
Buat sebuah file bernama AddNoteForm.js di dalam folder components.
Kita gunakan form library Formik untuk mempermudah kita dalam menghandle React Form. Library formik ini sudah pernah digunakan saat proses implementasi sistem autentikasi.
Install Formik:
1$ npm install formik23// atau45$ yarn add formik
Selain itu kita juga akan tambahkan package fontawesome untuk icon.
1$ npm i --save @fortawesome/fontawesome-svg-core2$ npm install --save @fortawesome/free-solid-svg-icons3$ npm install --save @fortawesome/react-fontawesome45//atau67$ yarn add @fortawesome/fontawesome-svg-core8$ yarn add @fortawesome/free-solid-svg-icons9$ yarn add @fortawesome/react-fontawesome
Di dalam file AddNoteForm.js tambahkan code berikut ini:
1import React from 'react';2import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';3import { faSave } from '@fortawesome/free-solid-svg-icons';4import { useFormik } from 'formik';56const AddNoteForm = () => {7 const formik = useFormik({8 initialValues: {9 title: '',10 content: ''11 },12 onSubmit: async (values) => {13 setIsSuccess(true);14 }15 });16 return (17 <>18 <form className="flex flex-col w-4/5" onSubmit={formik.handleSubmit}>19 <div className="flex flex-col">20 <input21 className="my-8 p-2 text-xl font-bold w-full focus:outline-none focus:ring focus:border-blue-300"22 type="text"23 name="title"24 placeholder="Title"25 onChange={formik.handleChange}26 value={formik.values.title}27 ></input>28 <textarea29 className="resize-y mb-8 p-2 focus:outline-none focus:ring focus:border-blue-300"30 name="content"31 rows="12"32 placeholder="Your content goes here.."33 onChange={formik.handleChange}34 value={formik.values.content}35 ></textarea>36 </div>37 <div className="flex justify-end">38 <button className="bg-purple-700 text-white text-base m-2 p-3 border rounded-md" type="submit">39 <FontAwesomeIcon icon={faSave} /> Save40 </button>41 </div>42 </form>43 </>44 );45};4647export default AddNoteForm;
Import component AddNoteForm pada file pages/add.js.
1import React from 'react';23import Layout from '../components/Layout';4import AddNoteForm from '../components/AddNoteForm';56const Add = () => {7 return (8 <Layout>9 <div className="flex flex-col items-center justify-center m-4">10 <AddNoteForm />11 </div>12 </Layout>13 );14};1516export default Add;
Hasilnya:
Menambah API
Seperti yang sudah dijelaskan sebelumnya, kita bisa menggunakan AWS Amplify untuk menambah API yang sudah terkoneksi dengan database ke dalam aplikasi DinoTes.
Jalankan perintah berikut di terminal:
1amplify add api
Kemudian kita perlu jawab beberapa pertanyaaan untuk konfigurasi awal
1? Please select from one of the below mentioned services:2# GraphQL3? Provide API name:4# dinotes5? Choose the default authorization type for the API:6# API key7? Enter a description for the API key:8#9? After how many days from now the API key should expire (1-365):10# 711? Do you want to configure advanced settings for the GraphQL API?12# Yes, I want to make some additional changes.13? Configure additional auth types?14# Yes15? Choose the additional authorization types you want to configure for the API:16# Amazon Cognito User Pool17? Do you want to use the default authentication and security configuration?18# Default configuration19? How do you want users to be able to sign in?20# Username21? Do you want to configure advanced settings?22# No, I am done.23? Enable conflict detection?24# No25? Do you have an annotated GraphQL schema?26# No27? Choose a schema template:28# Single object with fields (e.g., “Todo” with ID, name, description)29? Do you want to edit the schema now?30# Yes
Secara garis besar kita akan gunakan GraphQL dengan mode autentikasi API key dan Amazon Cognito User Pool.
Apa itu Amazon Cognito User Pool?
Amazon Cognito User Pool adalah direktori user yang ada di dalam layanan Amazon Cognito. Dengan menggunakan user pool, user bisa login ke aplikasi DinoTes menggunakan Amazon Cognito.
Amazon Cognito sendiri merupakan layanan milik AWS untuk membantu menghandle proses autentikasi.
Langkah berikutnya kita perlu mengubah graphql schema yang sebelumnya tergenerate secara otomatis saat proses menambahkan api.
Schema diubah menyesuaikan bentuk data yang ingin disimpan pada aplikasi DinoTes.
Lokasi file: amplify/backend/api/dinotes/schema.graphql
Dari
1type Todo @model {2 id: ID!3 name: String!4 description: String5}
Menjadi
1type Note2 @model3 @auth(rules: [{ allow: owner }, { allow: public }]) {4 id: ID!5 username: String6 title: String!7 content: String8 createdAt: AWSDateTime9 updatedAt: AWSDateTime10}
Yang perlu kita ketahui pada perubahan schema diatas adalah directive @auth
yang berfungsi untuk mengatur mekanisme autentikasi pada GraphQL API.
@auth(rules: [{ allow: owner }, { allow: public }]
berarti yang memiliki akses ke GraphQL API adalah:
- owner, setiap user yang sign in menggunakan Amazon Cognito User Pool
- public, terbuka untuk publik namun harus menggunakan API key
Untuk lebih lengkapnya kamu bisa lihat di sini.
Deploy API
API yang sudah ditambahkan masih bersifat lokal, kita perlu deploy API tersebut ke AWS.
Untuk melakukannya jalankan perintah berikut:
1amplify push
1Current Environment: dev23| Category | Resource name | Operation | Provider plugin |4| -------- | --------------------- | --------- | ----------------- |5| Auth | dinotese043671b | Create | awscloudformation |6| Api | dinotes | Create | awscloudformation |7? Are you sure you want to continue? Y89# You will be walked through the following questions for GraphQL code generation10? Do you want to generate code for your newly created GraphQL API? Y11? Choose the code generation language target: javascript12? Enter the file name pattern of graphql queries, mutations and subscriptions: graphql/**/*.js13? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions? Y14? Enter maximum statement depth [increase from default if your schema is deeply nested]: 2
Proses deploy API membutuhkan waktu beberapa menit.
Setelah berhasil kita bisa lihat hasilnya di AWS Amplify Console.
Atau melihat statusnya dengan menjalankan perintah amplify status
.
1➜ dinotes git:(main) ✗ amplify status23Current Environment: dev45| Category | Resource name | Operation | Provider plugin |6| -------- | --------------- | --------- | ----------------- |7| Auth | dinotese043671b | No Change | awscloudformation |8| Api | dinotes | No Change | awscloudformation |
Jika kita lihat pada AWS Amplify Console, API pada AWS Amplify terdiri dari dua bagian, yaitu GraphQL API yang terhubung dengan layanan AWS AppSync serta Data Source yang merupakan kumpulan table di DynamoDB.
Dengan kata lain saat ini aplikasi DinoTes menggunakan AppSync untuk keperluan API dan DynamoDB untuk database.
Admin UI
Kita bisa mendapatkan tampilan visual dari backend DinoTes dengan cara mengaktifkan fitur admin UI.
Untuk mengakses admin UI klik button "Open Admin UI" dari AWS Amplify console.
Tampilan Admin UI
Dengan Admin UI kita bisa mengelola semua layanan yang terhubung dengan backend dari aplikasi DinoTes dalam tampilan mirip dashboard.
Sebagai contoh pada menu GraphQL API kita akan temukan API yang baru saja dideploy.
Disini ada yang perlu diperhatikan, menu Data pada Admin UI berfungsi untuk mengelola data yang berasal dari Data Store sedangkan layanan AppSync secara default terhubung dengan DynamoDB, untuk melihat data yang tersimpan oleh AppSync kita harus melihatnya langsung di DynamoDB.
Oleh karena itu jika kita melihat menu Data pada Admin UI kita tidak akan temukan data yang disimpan oleh API.
Integrasi API
Pada bagian ini kita akan update component AddNoteForm agar bisa menyimpan note baru ke dalam database.
Sebelumnya kita perlu membuat component untuk menghandle feedback dari form.
Buat file dengan nama Message.js di dalam folder components dan isi dengan code berikut:
1import React from 'react';23const Message = (props) => {4 const { text, type } = props;56 return (7 <>8 {type === 'error' ? (9 <div className="flex flex-col items-center justify-center m-4 p-4 border-2 border-red-500 rounded">10 <p>❌ {text}</p>11 </div>12 ) : (13 <div className="flex flex-col items-center justify-center m-4 p-4 border-2 border-green-500 rounded">14 <p>✅ {text}</p>15 </div>16 )}17 </>18 );19};2021export default Message;
Update file AddNoteForm.js dengan code berikut ini:
1import React, { useState } from 'react';2import { API } from '@aws-amplify/api';3import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';4import { faSave } from '@fortawesome/free-solid-svg-icons';5import { useFormik } from 'formik';67import { createNote } from '../graphql/mutations';8import Message from './Message';910const InfoWrapper = (props) => {11 const { status } = props;1213 if (status !== null) {14 if (status === false) {15 return <Message type="error" text="Title cannot be empty" />;16 }17 return <Message type="success" text="Data successfully saved" />;18 }19 return <></>;20};2122const AddNoteForm = () => {23 const [isSuccess, setIsSuccess] = useState(null);2425 const formik = useFormik({26 initialValues: {27 title: '',28 content: ''29 },30 onSubmit: async (values) => {31 const { data } = await API.graphql({32 authMode: 'API_KEY',33 query: createNote,34 variables: {35 input: {36 title: values.title,37 content: values.content38 }39 }40 });41 console.log(data.createNote.id);42 setIsSuccess(true);43 }44 });45 return (46 <>47 <InfoWrapper status={isSuccess} />48 <form className="flex flex-col w-4/5" onSubmit={formik.handleSubmit}>49 <div className="flex flex-col">50 <input51 className="my-8 p-2 text-xl font-bold w-full focus:outline-none focus:ring focus:border-blue-300"52 type="text"53 name="title"54 placeholder="Title"55 onChange={formik.handleChange}56 value={formik.values.title}57 ></input>58 <textarea59 className="resize-y mb-8 p-2 focus:outline-none focus:ring focus:border-blue-300"60 name="content"61 rows="12"62 placeholder="Your content goes here.."63 onChange={formik.handleChange}64 value={formik.values.content}65 ></textarea>66 </div>67 <div className="flex justify-end">68 <button className="bg-purple-700 text-white text-base m-2 p-3 border rounded-md" type="submit">69 <FontAwesomeIcon icon={faSave} /> Save70 </button>71 </div>72 </form>73 </>74 );75};7677export default AddNoteForm;
Kita akan sedikit bahas baris code berikut ini yang merupakan bagian penting dari proses integrasi API.
1...2 const { data } = await API.graphql({3 authMode: 'API_KEY',4 query: createNote,5 variables: {6 input: {7 title: values.title,8 content: values.content9 }10 }11...
API.graphql({}) merupakan method yang kita ambil dari package @aws-amplify/api yang berfungsi untuk menghandle operasi Query dan Mutation pada GraphQL API.
Beberapa parameter yang digunakan pada method API.graphql ini:
- authMode, jenis autentikasi yang digunakan
- query, jenis query yang digunakan, dan diambil dari file yang ada di dalam folder graphql. Pada code diatas kita gunakan query jenis mutation dan method yang dipanggil adalah createNote
- variables, berisi payload atau data yang akan dikirim ke GraphQL API
Karena setiap request ke AWS server harus dievaluasi maka kita perlu menambahkan konfigurasi AWS di file index.js atau _app.js.
pages/_app.js
1import Amplify from '@aws-amplify/core';23import awsconfig from "../src/aws-exports";45import '../styles/globals.css';67Amplify.configure({ ...awsconfig, ssr: true });89function MyApp({ Component, pageProps }) {10 return <Component {...pageProps} />;11}1213export default MyApp;
Penjelasan singkat:
- aws-exports, berisi AWS credential yang digunakan agar bisa berkomunikasi dengan AWS Amplify
- Karena kita menggunakan Next.js yang support SSR maka perlu ditambahkan opsi ssr:true
Test API
Pengujian atau test API dapat dilakukan dengan mengakses alamat localhost:3000/add kemudian tambahkan title dan content.
Kemudian kita bisa cek apakah data berhasil disimpan pada Admin UI.