Apa itu JSON ?
JSON (JavaScript Object Notation) adalah format pertukaran data yang ringan. Sangat mudah bagi manusia untuk membaca dan menulisnya. Mudah bagi mesin untuk memprosesnya dan membuatnya. Format ini didasarkan pada Standar Bahasa Pemrograman JavaScript ECMA-262 Edisi ke-3 – Desember 1999. JSON adalah format teks yang sepenuhnya terbebas dari bahasa pemrograman apapun, akan tetapi dalam prakteknya json ini menggunakan konvensi yang akrab dengan bahasa pemrograman dari keluarga bahasa C, termasuk C, C++, C#, Java, JavaScript, Perl, Python, dan masih banyak lainnya. Kemudahan dan keunggulannya ini menjadikan JSON sebagai bahasa pertukaran data yang ideal dan terkenal untuk saat ini.
Dalam topik ini nanti kita hanya akan membahas cara menggunakan JSON dengan Flutter. Ini nanti akan mencakup solusi yang diberikan oleh JSON dalam skenario yang berbeda, dan mengapa itu diperlukan.

Pengkodean (Encoding) dan serialisasi (serialization) adalah hal yang sama, mengubah struktur data menjadi string. Decoding dan deserialization adalah proses yang berlawanan, mengubah string menjadi struktur data. Namun, serialisasi juga biasanya mengacu pada keseluruhan proses penerjemahan struktur data ke dan dari format yang lebih mudah dibaca. Untuk menghindari kebingungan, dalam topik ini kita akan menggunakan “serialization” saat mengacu pada keseluruhan proses, dan “encoding” – “decoding” saat secara khusus merujuk pada proses tersebut.
Memilih Json Serialization yang tepat?
– Manual Serialization
– Automated serialization menggunakan code
generation
Proyek yang berbeda tentunya mempunyai kompleksitas dan kasus logic yang berbeda. Untuk proyek proof-of-concept yang sederhana atau prototipe, menggunakan code generator mungkin terlalu berlebihan. Dan juga untuk aplikasi dengan beberapa model JSON yang lebih kompleks, Manual serialization bisa menjadi membosankan, sering berulang, dan dapat menyebabkan lebih banyak kesalahan kesalahan kecil yang berimpact ke aplikasi.
Manual Serialization
Decoding JSON secara manual mengacu pada penggunaan Json decoder bawaan dari dart:convert. Caranya memasukan string JSON ke dalam fungsi jsonDecode(), hasilnya nanti berupa Map. Dengan Map ini kita sudah dapat mencari nilai yang kita inginkan dalam bentuk object. Decode manual tidak bekerja dengan baik saat proyek kita menjadi lebih besar. Menulis logika decoding secara manual bisa menjadikan kode kita sulit untuk dikelola dan rawan kesalahan. Jika Anda salah ketik saat mengakses kolom JSON yang tidak ada, kode kita akan menampilkan kesalahan selama runtime. Jika kita tidak memiliki banyak model JSON dalam proyek kita dan hanya ingin menguji konsep dengan cepat, manual serialization mungkin merupakan cara yang tepat untuk dimulai. Untuk contoh manual encoding, lihat Serialisasi JSON secara manual menggunakan dart:convert.

- Flutter Basic JSON Serialization
Serialisasi JSON di Flutter sangatlah sederhana. Flutter
memiliki library dart:convert bawaan yang
menyediakan fungsi encoder dan decoder JSON secara
langsung.
Contoh JSON berikut mengimplementasikan secara
sederhana model user
Dengan dart:convert, kita dapat membuat serialize
model JSON ini dengan dua cara:
1. Serializing JSON secara inline
2. Serializing JSON didalam class model

- Serializing JSON inline
Dengan melihat dokumentasi dart:convert, kita akan melihat bahwa kita dapat mendekode JSON dengan memanggil fungsi jsonDecode(), dengan string JSON sebagai argumen metode.

Sayangnya, jsonDecode() mengembalikan Map, artinya kita tidak mengetahui tipe data dari nilai sampai runtime. Dengan pendekatan ini, kita kehilangan sebagian besar fitur statically typed, type safety, autocomplete, dan yang terpenting, compile-time exceptions atau pesan error ketika waktu compile. Itu artinya kode kita akan langsung menjadi lebih rawan dari kesalahan.

Misalnya, setiap kali kita mengakses name atau email, kita bisa saja langsung salah ketik. Kesalahan ketik ini tidak akandiketahui oleh kompiler karena JSON berada dalam struktur map. Error ini akan diketahui ketika runtime atau ketika aplikasi sedang berjalan.

- Serializing JSON di dalam class model
Dalam menghadapi masalah yang disebutkan sebelumnya, saya akan memperkenalkan class model. Dalam contoh ini kita dapat menyebutnya class User. Di dalam class User
ini, kita akan menemukan:
Constructor User.fromJson(), untuk membuat instance User baru dari struktur Map. Metode toJson(), yang mengubah instance User menjadi Map.
Dengan pendekatan ini, pemanggilan kode dapat memiliki keamanan tipe (type safety), autocompletion untuk kolom name dan email, dan compile-time exceptions.. Jadi kalau kita ada kesalahan ketik atau menganggap name dan email sebagai int, bukan String, aplikasi tidak akan bisa dikompilasi, sehingga tidak akan crash ketika runtime.

Tanggung jawab untuk decode sekarang pindah ke dalam class model. Dengan pendekatan baru ini, Anda dapat decodeUser dengan mudah.

Untuk encoding User, masukan objek User ke fungsi jsonEncode(). kita tidak perlu memanggil metode toJson(), karena jsonEncode() sudah melakukannya untuk kita.
Dengan pendekatan ini, pemanggilan kode tidak perlu mengkhawatirkan serialisasi JSON sama sekali. Namun, class model tetap harus kita perhatikan. Dalam aplikasi production, kita harus memastikan bahwa serialisasi berfungsi dengan baik. Dalam praktiknya, metode User.fromJson() dan User.toJson() harus memiliki unit test untuk memverifikasi serialization ini berjalan dengan benar.

Serialization using Code Generator
Serialisasi JSON dengan code generator artinya kita memiliki eksternal library yang menghasilkan encoding boilerplate untuk kita. Setelah menyiapkan class sesuai dengan aturan code generator, kita akan menjalankan file watcher yang akan menghasilkan kode dari class model tersebut. Misalnya, json_serializable dan freezed adalah jenis library yang dapat kita pakai.
Pendekatan ini sangat baik untuk proyek yang besar. Tidak diperlukan boilerplate secara manual, dan tidak ada kesalahan ketik saat mengakses file JSON pada waktu kompilasi. Kelemahan dari pembuatan kode adalah memerlukan beberapa pengaturan di awal. Juga, file yang dihasilkan mungkin memperlihatkan visual yang kurang enak di navigator proyek kita.
Untuk melihat contoh encoding JSON berbasis code generator, lihat Serialisasi JSON menggunakan library berikut.
Setup json_serializable dalam project
Untuk menyertakan json_serializable dalam proyek kita, Anda memerlukan satu dependensi reguler, dan dua dependensi dev. Singkatnya, dependensi dev adalah dependensi yang tidak disertakan dalam sourcecode aplikasi kita, mereka hanya digunakan di lingkungan development. Jalankan flutter pub get ke dalam folder root kita untuk membuat dependensi baru ini tersedia di project kita.

Membuat class model dengan json_serializable
Berikut ini menunjukkan bagaimana cara mengkonversi class User menjadi class
json_serializable. Kode berikut ini menggunakan model JSON yang disederhanakan dari contoh sebelumnya.
Dengan setup ini, code generator menghasilkan kode untuk encoding dan decoding field name dan email dari JSON.
Jika perlu, juga mudah untuk menyesuaikan strategi penamaan. Misalnya, jika API mengembalikan objek dengan snake_case, dan kita ingin menggunakan lowerCamelCase di model kita, kita bisa menggunakan anotasi @JsonKey dengan name parameter:

Running code generator
Saat membuat class json_serializable pertama kali, Anda akan mendapatkan kesalahan yang serupa dengan yang ditunjukkan pada gambar di samping.

Kesalahan ini sepenuhnya normal dan hanya karena kode yang dihasilkan untuk class model belum ada. Untuk mengatasinya, jalankan code generator untuk menghasilkan class boilerplate yang sudah terserialisasi.
cara menjalankan code generator
- Dengan menjalankan flutter pub run build_runner build –delete-conflicting-outputs di root project, ini memicu build satu kali yang menelusuri files, memilih yang sesuai setup code generator, dan menghasilkan kode serialisasi.
- Generate kode secara terus menerus. watcher membuat proses pembuatan kode kami lebih nyaman. Itu mengawasi perubahan dalam file project kita dan secara otomatis membuat file yang diperlukan. Memulai watcher dengan cara menjalankan perintah flutter pub run build_runner watch –delete-conflicting-outputs di root project.

Mengkonsumsi model dari json_serializable
Untuk decode JSON string dengan cara
json_serializable, Anda sebenarnya tidak perlu
melakukan perubahan apapun pada kode yang
pernah kita buat sebelumnya.

https://jagoflutter.com/wp-content/uploads/2023/10/CWB-Flutter-Json-Serialization-Rest-API.pdf