Creating Web Application Using Spring Boot
Using start.spring.io
to build apps
Banyak web stack diluarsana menggunakan banyak pustakan atau tools untuk membangun web application dan semuanya berisikan modul-modul yang saling berhubungan. Termasuk dengan Spring Boot, terdiri dari module-module.
Dahulu, sebelum lahirnya spring boot, setidaknya programmer dalam membangun sebuah web application mereka harus mencari sample maven di stackoverflow atau beberapa blog yang menyediakan kumpulan modul yang sudah siap dipakai.
Namun setelah hadirnya Spring Boot, kita dapat memanfaatkan start.spring.io. Website tersebut dibuat dan dimaintain oleh Spring Team.
Sebelum membuat package, kita dapat memimilih yang disediakan, diantaranya;
- Kita dapat memilih versi dari Spring Boot
- Dapat memilih tool yang digunakan untuk membangun website, (Gradle atau Maven)
- Dapat memilih versi java (Minimum 17)
- Dapat memilih module (Spring atau third party module lainnya) untuk digunakan pada project
Warning
Saat memilih Packaging, Lebih baik memilih JAR files dari pada WAR files (hanya untuk beberapa aplikasi server) sebagai packaging mechanism.
-
Setidaknya untuk bagian ini, ikuti pilihan dibawah ini
Choose | Value |
---|---|
Project | Maven |
Langauge | Java |
Spring Boot | 3.08 |
Project Metadata | Bebas, disesuaikan |
Depedencies | Spring Web |
Setelah memilih field yang tersedia maka secara otomatis web akan mendownload compress file dengan ekstensi rar. Selanjutnya uncompress file tersebut lalu buka folder menggunakan IDE yang digunakan.
Creating a Spring MVC web controller
Setelah membuat folder project tersebut menggunakan IDE (saya menggunakan Intellij). InsyaAllah pada bagian ini kita akan membuat web controller.
Jadi apa itu web controller ? itu adalah sebuah kumpulan kode yang dapat menerima HTTP request dan dapat memberikan respone. Biasanya, respone yang diberikan oleh web controller adalah HTML namun web controller juga dapat memberikan respone dalam bentuk JSON (Java Script Object Notation). HTTP request yang diterima oleh web controller dapat bervariasi, umumnya menggunakan GET atau POST.
Bagain dari Spring yang membuat kita dapat mambangu web controller adalah Spring MVC (Movel View Control). Spring MVC adalah Module dari spring framework yang membuat kita dapat membangun sebuah aplikasi web diatas servlet-based containers menggunakan paradigma MVC.
Jika kita melihat file pom.xml
yang berada pada root project. Pada bagian dependecies kita dapat melihat depedency Spring MVC
Dependency diatas membuat kita dapat menggunaka anotasi yang disedian oleh Spring MVC dan komponen lainnya, serta membuat kita dapat mendefinisikan web controller. Untuk membuat web controller pertama, mari kita buat sebuah class dengan nama HomeController
Code
Deskripsi kode diatas sebagai berikut
-
@controller
: Anotasi Spring MVC untuk berkomunikasi ke Spring Boot bahwa class ini adalah web controller. Jadi, ketika aplikasi dijalankan, Spring Boot akan secara otomatis mendeteksi class ini melalau component scanning dan akan membuat instance class tersebut. (Dengan demikian, kita tidak perlu membuat instance dari class tersebut, karena hal itu sudah ditangani oleh Spring Boot) -
@GetMapping("/")
: Anotasi Spring MVC untuk pemetaan HTTP GET pada alamat root /. Jika client mengirim request alamat root, maka Spring Boot akan memanggil method dengan anotasi ini. -
index
: Karena kita menggunakan anotasi@Controller
, maka return nilaiindex
akan menjadi nama dari template yang akan dirender.
Info
Nama dari class atau method tidak terlalu penting, namun anda harus memberikan dengan nama yang menggambarkan fungsi dari class dan method tersebut. Yang paling penting adalah anotasi @Controller`` dan`` @GetMapping
yang mana memberikan sinyal bahwa class ini adalah web controller dan method yang dipanggil saat menerima request.
Alhamdulillah, kita sudah membaut sebuah web controller, namun ada yang terlewat, yaitu template. Dimana baru saja kita lihat pada catatan ini, method yang menggunakan @GetMapping
mengembalikan nama dari template yang akan dirender. Pada bagian selanjutnya kita akan menambahkan module yang berguna untuk menrender template.
Leveraging template to create content
Kita akan menggunakan module mustache. Saat awal membuat project di spring.initializr, kita dapat memilih mustache sebagai template engine.
Namun bagaimana jika kita sudah membuat web controller selama 3 bulan, dan apakah kita harus membuat project dari awal ?
Tentu tidak, kita dapat menambahkan module tersebut pada exisiting project dengan cara menambahkan depdency pada file pom.xml
pada root folder.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
</dependencies>
...
</project>
Jika module telah ada pada project kita, kita dapat langsung membuat sebuah template.
Bawaanya, Spring Boot akan membaca semua template yang ada pada folder src/resources/templates
. Setiap template engine1 memiliki suffix masing-masing. Untuk template mustache akhirannya adalah .mustache
. Ketika method pada controller kita mengambilan nilai index
, spring boot akan mentransform kedalam src/resources/templates/index.mustache
, lalu mengambil file tersebut dan mengirimnya ke Template Engine.
Selanjutnya mari kita buat file index.mustache
pada src/resources/templates/
.
Code
Selanjutnya kita jalankan aplikasi dan bukan alamat localhost:8080
2. Jika tidak ada error, insyaAllah kita dapat melihat tampilan web sedeharna. Alhamdulillah sekarang kita telah membuat web controller dan template hamalam HTML.
Folder Contoh
Kode dapat dilihat pada module bagian_2_awal
Adding demo data to a template
Applikasi web sesungguhnya menyediakan data. Data tersebut bisa bersumber dari DataBase, file pada server atau semisalnya. Untuk contoh kali ini, kita akan membuat demo data yang nantinya akan kita tampilkan pada template. Dibawah ini adalah update dari file HomeController.java
Code
@Controller
public class HomeController {
// #1
record Video(String name){};
// #2
List<Video> videos = List.of(
new Video("Film 1"),
new Video("Film 2"),
new Video("Film 3")
);
/**
* Anotasi untuk pemetaan HTTP GET alamat / untuk memanggil method ini
* @return
*/
@GetMapping("/")
public String index(Model model){ // #3
// #4
model.addAttribute("videos",this.videos);
return "index";
}
}
Pada kode diatas kita menambah beberapa baris kode;
- Kita membuat sebuah class baru dengan nama
Video
. - Kita men-declare dan initiate property
videos
untuk class HomeController. - Kita menambahkan parameter Model dari pada method dengan anotasi @GetMapping
- Kita menambahkan attribute menggunakan method
model.addAttribute
dan memberikan nama dengan nilaivideos
dan data dari propertythis.videos
.
Info
Java 17 menyediakan beberapa fitur yang sangat membantu kita dalam mengambangkan aplikasi menggunakan Spring Boot. Salah satunya dapat kita lihat pada contoh diatas. Dimana kita membuat sebuah Object Video hanya dengan satu baris kode menggunakan statement record
Tip
Mengapa kita harus membuat record
untuk meng- encapsulation data dengan elemen tunggal ?
Karena Mustache beroperasi menggunakan attribute yang bernama. Kita dapat secara manual membuat JSON yang berisikan name dan value, namun dengan adanya Java 17 kita dapat langsung dengan mudah menggunakan record
. Ditambah, fitur tersebut memberikan type safety.
Untuk mengirim data ke template, kita membutuhkan objek yang dipahami oleh Spring MVC. Kita butuh holder untuk menyimpan data. Untuk itu, kita membutuhkan parameter Model
pada method index.
Spring MVC memiliki attribute opsional yang dapat kita gunakan untuk web method apapun, contoh ini kita menggunakan, Model
yang berguna jika kita ingin mengirim data ke template enggine.
Pada HomeController.java
kita juga telah membuat data dummy List<Video>.
dan mengirimnya menggunakan method attribute yang diberi nama videos.
Untuk membaca data videos yang dikirim ke template enggine menggunakan fungsi model.addAttribute()
kita perlu mengubah file index.mustache
sebagai berikut,
Code
Penjelasan kode yang di- highlight diatas sebagai berikut;
-
{{#videos}}
: Directive untuk mengambil attributevideos
yang kita berikan pada objectModel
. Karena yang kita berikan dalam bentuk data list maka mustache memperlebar sebanyak data yang ada pada list. It will iterate over each entry of theList<Video>
collection stored in Model and create a separate HTML<li>
entry. -
{{name}}
: Indicates we want the name field of the data construct. This lines up with our Video type’s name field. In other words, for each entry ofList<Video>
, print out the name field between<li>
and</li>
. -
{{/videos}}
: Indicates the end of the looping fragment.
Folder Contoh
Kode dapat dilihat pada module bagian_2
Building our app with a better design
Aplikasi terakhir yang kita buat masih sederhana. Secara gamblang kita membuat data model dan menyediakannya untuk ditampilkan pada template.
Namun terdapat masalah kedepannya, dimana design kode kita tidak dapat digunakan kembali (not reusable). Maka dari itu kita butuh controller kedua dimana ada beberapa alasan mengapa kita melakukan itu;
-
Controller seharusnya tidak mengurusi definisi data. Karena tugas mereka hanyalah memberikan respone atas request lalau berinteraksi dengan service lain atau sistem, definisi ni harus berada pada tingkat bawah.
-
Web controller yang menangani beban yang banyak (serving data, manage data, calculate data, etc) akan membuat kita kesuliat saat ada penyesuaian pada web. Maka dari itu, sangat disaranakan jika managemen data ditaruh pada tingkat yang lebih bawah.
Maka dari itu, kita akan memindahkan class Video
ke file tersendiri, Video.java
.
Selanjutnya, kita akan memisahkan daftar objek Videos kedalam service yang terpisah. Kita akan membuat class baru dengan nama VideoService dengan isi sebagai berikut;
Code
@Service
: Anotasi yang menunjukan sebuah class yang harus diambil saat component scanning dan ditambahkan pada application context.
Injecting dependencies through constructor calls
Constructor injectiong adalah yang paling disukai oleh programmer untuk memberikan dependecies yang Spring bean butuhkan melalui constructor. Untuk itu, setiap kita membuat Java class yang diambil oleh Spring Boot sata componet scanning. Spring Boot secara ototmatis akan melihat apakah ada injection points, dan jika ada, maka Spring Boot akan melihat apllication contextnya dan menginject-nya. Metode tersebut disebut dengan Autowiring. Kita membiarkan Spring yang menangani pencarian dependencies dari Spring pada application context serta memasang depedencies tersebut.
Selanjutnya kita akan memodifikasi kode dari HomeController
menjadi sebagai berikut, membuat depedency injection;
Code
Karena kita sudah meng-inject VideoServive
kedalam HomeController
, kita dapat mengupdate method index()
sebagai berikut;
Code
Folder Contoh
Kode dapat dilihat pada module bagian_2_2
Changing the data through HTML forms
Pada bagian kali ini kita akan membuat sebuah web yang dapat menerima dan menampung data pada List<String>
. Pertama kita harus membuat perubahan pada index.mustache
agar bisa menerima input dari user.
Code
Jika kita melihat kode diatas, pada nilai di attribute action dan method artinya setelah user mengisi nilai masukan, user akan membuat request ke HTTP POST /new-video
. Maka dari itu kita harus membuat mapping untuk memberikan respone atas request tersebut. Dibawah ini adalah update dari HomeController.java
;
Code
@Controller
public class HomeController {
private VideoService videoService;
public HomeController(VideoService videoService){
this.videoService = videoService;
};
@GetMapping("/")
public String index(Model model){
model.addAttribute("videos", videoService.getVideos());
return "index";
}
@PostMapping("/new-video")
public String addVideo(@ModelAttribute Video newVideo){
this.videoService.create(newVideo);
return "redirect:/";
}
}
Dibawah ini adalah penjelasan dari kode yang kita highlight
@PostMapping("/new-video")
: Anotasi untuk menerima POST /new-video dan mengarahakannya ke method ini.@ModelAttributes Video newVideo
: Anotasi untuk mem-parse, mengurai incoming HTML form kedalam Video ObjectvideoService.create()
: Method yang akan kita buat setelah ini, fungsi ini untuk menambahkan nilai masukan keList<String>
"redirect:/"
: Spring MVC directive yang mengirim ke browser HTTP 302 Found to URL /. 302 redirect adalah standar yang digunakan untuk merujuk kembali ke url tertentu.
Sekarang kita harus membuat method dengan nama videoService.create(Video newVideo)
. Namun ada yang perlu diperhatikan, kita menggunakan List.of()
untuk membuat kumpulan video, yang mana menghasilkan immutable lists.Namun, karena Immutable list implement java List interface, yang mana memberikan kita akses method add()
. Namun jita kita menggunakan method tersebut, akan memunculkan exception UnsupportedOperationException
.
Code
@Service
public class VideoService{
private List<Video> videos = List.of(
new Video("Film 1"),
new Video("Film 2"),
new Video("Film 3")
);
public List<Video> getVideos(){
return this.videos;
}
public Video create(Video addedVideo){
ArrayList<Video> extend = new ArrayList<Video>(this.videos);
extend.add(addedVideo);
this.videos = List.copyOf(extend);
}
};
Holla, sekarang kita bisa mengirim data pada form.
Folder Contoh
Kode dapat dilihat pada module bagian_2_3
Creating JSON-based APIs
Salah satu yang membuat Spring Boot powerfull adalah, ketika kita menambahkan Spring web kesebuah project, module tersebut sekaligus menambahkan Jackson ke classpath. Jackson adalah pustaka untuk Serialization/Deserialization JSON ke Java Object atau sebaliknya.
Kali ini, isnyaAllah kita akan membuat REST API. Maka dari itu, kita harus membuat sebuah class baru pada package yang sama. Kita akan membuat class dengan nama ApiController
dan diberi anotasi @RestController.
@RestController mirip dengan @Controller. Itu adalah anotasi yang memberikan sinyal ke Spring Boot bahwa class ini secara otomatis harus diambil saat component scanning dan dijadikan sebuah Spring bean. Bean ini akan didaftarkan pada application context dan juga dengan Spring MVC sebagai conroller class sehingga dapat merujuk ke web calls.
Namun ada tambahan property, anotasi tersebut merubah semua method dari template-based ke JSON-based. Dalam kata lain, dari pada web method mengembalikkan nama dari template yang Spring MVC render melalaui template engine, anotasi tersebut akan mengembalikan serialize data menggunakan Jackson.
Code
@RestController
public class APIVideos {
private VideoService videosService;
public APIVideos(VideoService videos){
this.videosService = videos;
}
@GetMapping("/API/videos")
public List<Video> getAll(){
return this.videosService.getVideos(); //#(1)!
}
}
- Akan dirender otomatis dari
List<Video>
kedalam JSON oleh Jackson
Method diatas akan mengambil list dari vide dan mengembalikan list tersebut, yang menyebabkan list tersebut dirender kedalam bentuk JSON Array oleh Jackson.
Sekarang coba kita gunakan postman untuk mengirim request, maka hasil yang didapatkan sebagai berikut;
API yang hanya menghasilkan JSON tidak dikatan API yang sesungguhnya, API tersebut juga harus menerima nilai masukan dan melakukan sesuatu dibelakangnya dan memberikan respone balikan juga dalam bentuk JSON. Untuk itu kita harus membuat HTTP Post call pada class yang sama, ApiController
.
Sekarang kita tambahkan method addVideo()
pada class APIVideos
Code
@RestController
public class APIVideos {
private VideoService videosService;
public APIVideos(VideoService videos){
this.videosService = videos;
}
@GetMapping("/API/videos")
public List<Video> getAll(){
return this.videosService.getVideos();
}
@PostMapping(value = "/API/videos", consumes = {"*/*"})
public Video addVideo (@RequestBody Video addVideo){
return this.videosService.create(addVideo);
}
}
Kode diatas dijelaskan sebagai berikut;
-
@PostMapping
: Memetakan pemanggilan HTTP POST pada/api/vidoes
ke methodaddVideo()
. -
@RequestBody
: Anotasi Spring MVC yang berfungsi untuk menandakan bahwa request body yang masuk pada HTTP request harus di deserialisasi menggunakan Jacskon kedalam argumenaddVideo
sebagai objek Video. -
Selanjutnya kita mengembalikan nilai kembalian dari method
#!videosService.create()
, yang mana berisi judl video yang baru ditambahkan.
Selanjutnya kita buka aplikasi Postman lalu jalankan request ke HTTP Post /API/videos
, dan memberikan body data JSON seperti dibawah ini
Request and Respone
Folder Contoh
Kode dapat dilihat pada module bagian_2_4
Warning
Pada buku ini mengenai JPA sangat terbatas, insyaAllah akan ada catatan yang saya buat yang diambil dari sumber lain. Diantaranya mengenai
- Penggunaan
@Pathvariable
- Memanfaat ResponseStatusException dan membuat costume exception result JSON
- Menambahkan message error dan Exception pada respone error
Dapat melihat ke sini JPA,RestFullAPI
Hooking in Node.js to a Spring Boot web app
Sudah menjadi "standard defacto" bahwasanya JavaScript wajib digunakan pada aplikasi web modern. Banyak front-end menggunakan JavaScript, salah satu framework yang akan kita gunakan, React. Namun, untuk menggunakan framework tersebut kita harus masuk ke dunia Node.js. Alhamdulilah -nnya, ada plugin Maven yang menjembatani kita antara Spring Boot dengan Node.js, plugin tersebut disebut dengan Maven Frontend Plugin. Plugin ini menggabungkan Node.js dengan siklus hidup Maven, sehingga membuat kita dapat secara benar melibatkan Node.js seperti saat kita ingin mengunduh packages hingga menggabungkan kode JavaScript menjadi satu kesatuan dengan aplikasi java kita (Spring Boot).
Tentu, compiling dan bundling JavaScript Payload akan sia-sia jika tidak ada cara bagi Spring Boot untuk membuatnya Online. Alhamdulillahnya, Spring Boot memiliki solusi. Apapun yang ada di path src/main/resources/static
secara otomatis akan diambil dan akan dijadikan sebagai alamat basis dari aplikasi web ketika digabungkan. Artinya, kita hanya perlu mengarahkan tool bundling dari Node.js untuk menaruhnya hasil dari compile react ke alamat tersebut.
Bismillah, pada catatan ini akan dipaparkan bagimana meng-install plugin, Node.js, npm, react.js dan integrasi dengan SpringBoot API yang telah dibuat pada bagian Creating JSON based API
Pertama kita mulai dengan front-end-maven-plugin
. Pada file pom.xml
yang berada pada dasar direktori kita perlu menambahkan element plugin dan informasi terkait plugin tersebut. Masukan konfigurasi dibawah ini pada file tersebut.
Info
Element plugins
sama seperti dengen depdencies
, dimana kita dapat menginstall lebih dari satu depedency dan plugin.
Install front-end-maven-plugin
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.12.1</version>
<executions>
<execution>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<executions>
<configuration>
<nodeVersion>v18.17.0</nodeVersion>
</configuration>
</plugin>
Penjelasan:
- Kita menambahkan kordinat versi 1.12.1 untuk
frontend-maven-plugins
. - Untuk saat ini pada plugin kita hanya memiliki satu buah execution yaitu install-node-and-npm.
- Pada element
configuration
kita membuat spesifikasi untuk versi Node.js, V18.17.0
Note
Plugins akan melakukan tugasnya saat fase generate-resouces
Warning
Proses setup pada catatan ini dipecah-pecah agar kita dapat memahami setiap konfigurasi yang kita tuliskan pada pom.xml
. Namun sebenarnya kita dapat menuliskan setup sekaligus dalam proses jalannya maven.
Perlu diketahui, proses yang dijalankan maven adalah mengunduh Node.js, npm (Node Package Manager), dan npx (Node Package Execution) pada project root didalam folder node.
Tips
Node.js and all its tools and modules can be considered intermediate build artifacts. There’s no need to commit them to version control. So, be sure to add the node folder as well as the intermediate node_modules folder to your list of items to not commit (for example, add node and node_modules to the project’s .gitignore file).
Bundling JavaScript with Node.js
Sekarang kita sudah memiliki tools, npm. Namun kita belum memiliki module. Sebelum kita menulis kode Node.js, pertama kita harus menginstall Node.js Package Bundler yaitu pickles. Kita akan menggunakan npm. Bukalah CMD atau terminal pada root folder dan jalankan command dibawah ini.
Perintah diatas akan menggunakan Node.js yang terinstall lokal hanya pada project tersebut dan memerintahkan npm untuk membuat file package.json
. Opsi --save-dev
memberi sinyal bahwa module tersebut sebagai module yang hanya digunakan untuk pengembangan dan bukan package yang digunakan oleh applikasi kita.
Sekarang kita memliki package.json
untuk project, selanjutnya kita harus mengaitkannya kedalam frontend-maven-plugin. Untuk itu kita harus menamhkan element <execution>
dibawah ini pada file pom.xml
.
Install front-end-maven-plugin
Fragement tersebut akan mengkonfigurasi frontend-maven-plugin
untuk menjalankan perintah npm install
, yaitu sebuah perintah yang akan membangun JavaScript bundle.
Sebelum kita menambahkan module JavaScript, kita harus menambahkan mengkonfigurasi pada package.json
agar build berjalan dengan benar. Edit package.json
dan pindahkan perintah dibawah ini pada element executions
.
Konfigurasi
Penjelasan penambahan diatas sebagai berikut;
source
menandakan entrypoint dari aplikasi JavaScript. Karena kita menggunakan module parcel maka tidak masalah dimana file ini berada. Namun, karena kita menggunakan Maven Based Project, kita dapat menempatkannya disrc/main/javascript/index.js
.- Sebagai target definition, kita dapat mengkonfigurasi default target pada
distDir
dengan nilaitarget/clasess/static
. Parcel mendukung building multiple target untuk browser yang berbeda, namun saat ini tidak perlukan. Dengan memasukan hasil pada target folder, setiap kita menjalankan Maven clean cycle, bundel yang telah di compile akan dibersihkan.
Karena npm adalah tool dari Node.js untuk men-download dan meng-install packages, npx
adalah tool dari Node.js untuk menajalankan perintah. Dengan menambahkan <execution>
entry pada frontend-maven-plugin
kita dapat menjalankan Parcel's build command.
Konfigurasi
langkah tambahan diatas akan menjalankan npx parcel build.
Creating a React.js Apps
Pertama kita harus meng-install module React.js menggunakan perintah npm
.
Perintah diatas akan memperbarui konten dari file package.json
dengan tambahan module react
dan react-dom
. Sekarang buatlah file index.js
dan letakan pada alamat src/main/javascript
Code
Berikut adalah penjelasan dari kode diatas;
- Baris pertama kita meng
import
module react-dom. Module penting dalam membangun aplikasi React. - Selanjutnya kita mengimport UI (User Interface) class yang kita buat nantinya.
- Baris ke-3 kita mengambil Data Object Model element HTML menggunakan
getElementById()
. - Baris terakhir kita me-render
<App/>
component.
React beroperasi dari perspektif paling atas ke paling bawah (top-down persepctive). Kita me-render top-level component, lalu selanjutnya component tersebut, akan merender component didalamnya (nested) dan terus berlanjut hingga component yang paling bawah.
React juga menggunakan Document Object Model (DOM) dimana kita tidak menetapkan node sesungguhnya untuk dirender, namun kita menggunakan virtual nodes. React akan memperhitungkan perubahan yang terjadi dari kondisi saat ini dan men-generate perubahan yang terjadi.
Diatas kita memanggil module App, maka dari itu sekarang kita akan membuat file App.js pada alamat src/main/javascript
Code
import React from 'react'
import ListOfVideos from './ListOfVideos'
import NewVideo from './NewVideo'
import Footer from './Footer'
class App extends React.Component {
render(){
return (
<div>
<ListOfVideos/>
<NewVideo/>
<Footer/>
</div>
)
}
}
export default render
Warning
Jika anda menggunakan opsi ini, maka pada top-level saat mengimport menggunakan open and close bracket. Pada kasusu ini pada file src/main/javascript/App.js.
import { App } from ./App
.
Penjelasan kode diatas App.js (Langsung meng-export function)
;
- Kita mengimport module
react
untuk membangun komponen - Kita meng-import class ListOfVideos, AddVideo dan Footer (insyaAllah akan kita buat nantinya)
Pada titik ini, kita memiliki fungsi App()
yang di export secara umum. Karena fungsi tersebut mengembalikan element HTML, ini menjadi sinya untuk Parcel bahwasanya kita menggunakan JavaScript XML (JSX), yang mana mengandung beberapa komponen React untuk dirender.
Pertama yang kita replikasikan dari applikasi yang menggunakan murni mustache adalah template yang menampilkan semua data video yang bersumber dari backend. Untuk men-generate HTML yang berisikan daftar tak terurut di React kita akan membuat class ListOfVideos dengan membuat file ListOfVideos
pada src/main/javascript/App.js
Code
Pada kode diatas kita diperkenalkan dengan properties dan state. Properties biasanya berisikan informasi yang disisipkan dari luar komponen kedalam React Component. Sedangkan State di-maintain dari dalam komponen. Sangat memungkinkan untuk menginisialisasi State dari Properties atau yang kita gunakan pada kode datas, komponen itu sendiri dapat memberikan data kepada state sebagaimana funcion componentDidMount
lakukan.
Yang perlu dipahami adalah, properties adalah immutable didalam React Component (nilainya tidak dapat berubah) sedangkan state dapat berubah-ubah didalam React Component.
Kita sudah membuat component untuk menampilkan daftar video. Sekarang kita akan membuat component untuk membuat form serta proses yang dilakukan ketika user mengisi video baru yang ingin ditambahkan pada field yang tersedia dan menekan tombol untuk menyimpan judeul video baru. Untuk itu pertama kita harus membuat class NewVideo dengan membuat file NewVideo.js pada alamat src/main/javascript
.
Code
Info
Aspek lain dari kode diatas adalah async/wait
modifiers yang digunakan untuk menangani fungsi handleSubmit()
. Umumnya JavaScript function mengembalikan nilai standard promises, seperti fungsi bawaan fetch
. Untuk mempermudah penggunakan APIs, ES6 memperkenalkan keyword await
yang membuat kita dapat mengindikasi sebuah fungsi bahwa kita menginginkan fungsi tersebut menunggu hasilnya terpenui lalu di return. Namun untuk mendukung penggunaan await
, kita harus memberikan flag async
pada function
Untuk memuat Applikasi React, kita harus memisahkan Mustache template. Buat react.mustache
didalam src/main/resources/templates
dan berikan nilai HTML seperti dibawah
Code
<!-- <div id="app"/> is the element that the React component <App /> will be rendered at
per the document.getElementById("app") from earlier in this section. -->
<div id ="app"></div>
<!-- The <script> tag will load our app through the index.js bundle Parcel will build. The
type="module" argument indicates it’s an ES6 module.-->
<script type="module" src="index.js"></script>
Langkah terakhir pada React App, kita harus memliki web controller method yang berbeda pada HomeController, buat method baru sebagai mapping dari Request URL ke Applikasi React.
Alhamdulillah, dengan demikian jika User meminta request GET /react
React App akan ditampilkan.
Dengan semua effort yang kita lakukan, dari memasang plugin frontend-maven-plugin
, menginstall npm, memasang <execution>
untuk menajalankan npx agar mem-build React app. Apakah sepadan ? sedangkan hasilnya sama dengan kita hanya menggunakan Spring Boot saja ? Ya, effort nya sangat besar.
Namun React sangat berguna jika kita membutuhkan design UI yang kompleks. Contohnya, jika kita membutuhkan berbagai macam komponen yang secara opsional yang ingin dirender atau membutuhkan komponen yang berbeda yang ingin ditampilkan, dititik inilah React sangat berguna.
React memiliki shadow DOM. Kita tidak perlu dipusingkan dengan konsep mencari bagian dari DOM dan secara manual meng-update node-node tersebut. Akan tetapi, dengan React, kita hanya membuat kumpulan HTML component. Selanjutnya, jika ada internal state yang diperbarui, component akan dirender ulang. React akan memperhitungkan perubahan pada elemnt DOM aslinya dan secara otomatis meng-update sendiri.
Set Up IDE
Kita perlu menambahkan beberapa konfigurasi pada IDE agar perubahan yang terjadi pada React tercompile sekaligus saat kita me- run applikasi kita. Yaitu dengan menambahkan Run Maven Goal dengan script maven generate-resources
.
Folder Contoh
Kode dapat dilihat pada module bagian_2_5