B.14. AJAX JSON Payload
Sebelumnya kita telah mempelajari cara submit data dari front-end ke back-end dengan menggunakan payload Form Data. Kali ini kita akan belajar tentang cara request menggunakan payload JSON.
Form Data merupakan tipe payload default HTTP request via tag
<form />
Pada chapter ini, kita tidak akan menggunakan tag <form />
untuk submit data, melainkan dengan memanfaatkan teknik AJAX (Asynchronous JavaScript And XML) dengan payload JSON.
Sebenarnya perbedaan antara kedua jenis request tersebut ada di dua hal, yaitu isi header Content-Type
dan struktur informasi dikirimkan. Request lewat <form />
secara default memiliki content type application/x-www-form-urlencoded
, efeknya data dikirimkan dalam bentuk query string (key-value) seperti id=n001&nama=bruce
.
Pengiriman data via tag
<form />
sebenarnya bisa menggunakan content-type selainapplication/x-www-form-urlencoded
, yaitumultipart/form-data
.
Untuk payload JSON, Content-Type
yang digunakan adalah application/json
. Dengannya, data disisipkan di dalam Body
request dalam bentuk JSON string.
B.14.1. Struktur Folder Proyek
OK, mari praktek. Pertama siapkan proyek dengan struktur seperti gambar berikut.
Silakan unduh file JS jQuery dari situs official-nya.
B.14.2. Front End - HTML
Layout dari view perlu disiapkan terlebih dahulu, tulis kode berikut pada file view.html
.
<!DOCTYPE html>
<html>
<head>
<title>JSON Payload</title>
<script src="static/jquery-1.12.0.min.js"></script>
<script>
$(function () {
// javascript code here
});
</script>
</head>
<body>
<p class="message"></p>
<form id="user-form" method="post" action="/save">
<!-- html code here -->
</form>
</body>
</html>
Selanjutnya, pada tag <form />
tambahkan tabel sederhana dengan isi didalamnya adalah inputan form. Ada tiga buah inputan yang perlu dibuat yaitu: Name, Age, dan Gender. Selain itu, sebuah button untuk keperluan submit form juga perlu disiapkan.
<table noborder>
<tr>
<td><label>Name :</label></td>
<td>
<input required type="text" name="name" placeholder="Type name here" />
</td>
</tr>
<tr>
<td><label>Age :</label></td>
<td>
<input required type="number" name="age" placeholder="Set age" />
</td>
</tr>
<tr>
<td><label>Gender :</label></td>
<td>
<select name="gender" required style="width: 100%;">
<option value="">Select one</option>
<option value="male">Male</option>
<option value="female">Female</option>
</select>
</td>
</tr>
<tr>
<td colspan="2" style="text-align: right;">
<button type="submit">Save</button>
</td>
</tr>
</table>
B.14.3. Front End - HTML
Sekarang kita masuk ke bagian paling menyenangkan/menyebalkan (tergantung taste), yaitu javascript. Siapkan sebuah event submit
pada #user-form
. Default handler untuk event submit milik <form />
di-override, diganti dengan AJAX request.
$("#user-form").on("submit", function (e) {
e.preventDefault();
var $self = $(this);
var payload = JSON.stringify({
name: $('[name="name"]').val(),
age: parseInt($('[name="age"]').val(), 10),
gender: $('[name="gender"]').val()
});
$.ajax({
url: $self.attr("action"),
type: $self.attr("method"),
data: payload,
contentType: 'application/json',
}).then(function (res) {
$(".message").text(res);
}).catch(function (a) {
alert("ERROR: " + a.responseText);
});
});
Value semua inputan dalam form diambil, kemudian dimasukkan ke sebuah objek lalu di stringify, agar berubah menjadi JSON string untuk kemudian di jadikan sebagai payload request. Bisa dilihat pada kode AJAX di atas, contentType
nilainya adalah application/json
.
Respon dari AJAX di atas nantinya dimunculkan pada <p class="message"></p>
.
B.14.4. Back End
3 buah rute perlu disiapkan, yang pertama adalah untuk menampilkan view.html
, untuk keperluan submit data, dan registrasi asset.
package main
import "fmt"
import "net/http"
import "html/template"
import "encoding/json"
func main() {
http.HandleFunc("/", handleIndex)
http.HandleFunc("/save", handleSave)
http.Handle("/static/",
http.StripPrefix("/static/",
http.FileServer(http.Dir("assets"))))
fmt.Println("server started at localhost:9000")
http.ListenAndServe(":9000", nil)
}
Handler handleIndex
berisikan kode untuk parsing view.html
.
func handleIndex(w http.ResponseWriter, r *http.Request) {
tmpl := template.Must(template.ParseFiles("view.html"))
if err := tmpl.Execute(w, nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
Sedangkan handleSave
akan memproses request yang di-submit dari front-end.
func handleSave(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
decoder := json.NewDecoder(r.Body)
payload := struct {
Name string `json:"name"`
Age int `json:"age"`
Gender string `json:"gender"`
}{}
if err := decoder.Decode(&payload); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
message := fmt.Sprintf(
"hello, my name is %s. I'm %d year old %s",
payload.Name,
payload.Age,
payload.Gender,
)
w.Write([]byte(message))
return
}
http.Error(w, "Only accept POST request", http.StatusBadRequest)
}
Isi payload didapatkan dengan cara men-decode body request (r.Body
). Proses decoding tidak dilakukan menggunakan json.Unmarshal()
melainkan lewat JSON decoder dengan alasan efisiensinya lebih baik.
json.Decoder
cocok digunakan untuk decode data JSON yang sumber datanya adalah streamio.Reader
, contohnya sepertir.Body
.json.Unmarshal()
cocok untuk proses decoding yang sumber datanya sudah tersimpan di variabel (bukan stream).
B.14.5. Testing
Jalankan program yang telah dibuat, test hasilnya di browser.
Gunakan fasilitas Developer Tools pada Chrome untuk menginspeksi aktifitas AJAX-nya.