Dalam dunia rekayasa perangkat lunak, terutama pada pengembangan protokol komunikasi, serialisasi data, dan desain API, istilah reserved fields dan reserved numbers sering kali kita jumpai. Meski sepintas terdengar seperti “mengosongkan slot” tanpa fungsi nyata, keduanya memainkan peran strategis dalam menjaga kompatibilitas dan evolusi sistem.
Artikel ini akan membedah konsep reserved fields dan reserved numbers secara mendalam—dilengkapi dengan contoh kode, simulasi sederhana, serta diskusi strateginya dalam software engineering profesional.
1. Apa Itu Reserved Fields dan Reserved Numbers?
Reserved Fields
Reserved fields adalah bagian dari struktur data (paket, pesan, struct, dsb.) yang dilewati alias disisihkan untuk digunakan di masa depan. Field ini tidak memiliki makna saat ini, harus diabaikan oleh penerima, tetapi tetap dipertahankan dalam struktur.
Contoh situasi:
- Protokol baru akan lahir, tapi desainnya diduga bakal berkembang.
- Perubahan (extend) ingin dilakukan tanpa memecah kompatibilitas (backward/forward compatible).
Reserved Numbers
Reserved numbers adalah nilai/angka tertentu dalam field (umumnya enumerasi atau tipe pesan) yang dicadangkan—tidak digunakan sekarang, namun akan diperuntukkan pada revisi mendatang.
Dapat juga bermakna: angka tertentu tidak boleh digunakan oleh implementasi custom (reserved for internal use).
2. Mengapa Reserved Fields dan Numbers Penting?
Berikut tabel ringkas alasan penggunaan keduanya:
Tujuan | Reserved Fields | Reserved Numbers |
---|---|---|
Compatibility | ✔︎ | ✔︎ |
Future-proofing | ✔︎ | ✔︎ |
Menghindari konflik | ❍ | ✔︎ |
Mempercepat revisi | ✔︎ | ✔︎ |
- Compatibility: Agar sistem baru dan lama bisa tetap ‘bicara’.
- Future-proofing: Memastikan struktur/protokol tetap relevan setelah bertahun-tahun.
- Menghindari konflik: Pada assigned enum/ID tertentu, reserved numbers mencegah duplikasi makna antar implementasi.
- Mempercepat revisi: Memungkinkan penambahan fitur tanpa mengubah seluruh sistem.
3. Contoh Konkret: Reserved Fields pada Protokol
Mari ilustrasikan reserved fields pada desain format pesan sederhana. Katakanlah Anda sedang mendesain protokol pertukaran pesan antara IoT Device dan Server.
Definisi Struktur Data
// DevicePacket mencerminkan struct C: device_packet_t
type DevicePacket struct {
MessageType uint16 // 2 byte
DeviceID uint32 // 4 byte
Status uint8 // 1 byte
Reserved [5]byte // 5 byte
Timestamp uint32 // 4 byte
}
// Encode mengubah DevicePacket ke []byte (big-endian)
func (p *DevicePacket) Encode() ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.BigEndian, p)
return buf.Bytes(), err
}
// Decode mengubah []byte ke DevicePacket
func Decode(data []byte) (*DevicePacket, error) {
var p DevicePacket
buf := bytes.NewReader(data)
err := binary.Read(buf, binary.BigEndian, &p)
return &p, err
}
Catatan: reserved[5]
mungkin hanya akan diisi nilai 0x00
oleh pengirim, tapi penerima tetap harus membaca dan mengabaikan field ini.
Alur Pengiriman dan Penerimaan
flowchart LR Start -->|Isi struct| Sender[Device] Sender -->|Isi reserved = 0| Packet Packet -->|Serialisasi| Network Network -->|Deserialisasi| Receiver[Server] Receiver -->|abaikan reserved| ProsesData
Simulasi kode (Python mock):
package main
import (
"bytes"
"encoding/binary"
"fmt"
"log"
)
func encodePacket(messageType uint16, deviceID uint32, status uint8, timestamp uint32) []byte {
buf := new(bytes.Buffer)
// Tulis sesuai urutan dan endianness
binary.Write(buf, binary.BigEndian, messageType)
binary.Write(buf, binary.BigEndian, deviceID)
binary.Write(buf, binary.BigEndian, status)
buf.Write(make([]byte, 5)) // reserved 5 byte zero
binary.Write(buf, binary.BigEndian, timestamp)
return buf.Bytes()
}
func decodePacket(data []byte) (messageType uint16, deviceID uint32, status uint8, timestamp uint32, err error) {
buf := bytes.NewReader(data)
if err = binary.Read(buf, binary.BigEndian, &messageType); err != nil {
return
}
if err = binary.Read(buf, binary.BigEndian, &deviceID); err != nil {
return
}
if err = binary.Read(buf, binary.BigEndian, &status); err != nil {
return
}
reserved := make([]byte, 5)
if _, err = buf.Read(reserved); err != nil {
return
}
if err = binary.Read(buf, binary.BigEndian, ×tamp); err != nil {
return
}
return
}
func main() {
// Simulasi
packet := encodePacket(1, 12345, 2, 1721548800)
mt, did, st, ts, err := decodePacket(packet)
if err != nil {
log.Fatal(err)
}
fmt.Printf("type=%d, device=%d, status=%d, ts=%d\n", mt, did, st, ts)
}
4. Reserved Numbers: Studi Kasus Enum & Protobuf
Pada protobuf, sering ditemukan keyword reserved
, baik untuk field number ataupun nama. Ini krusial agar pada revisi di masa mendatang tidak terjadi penimpaan yang tidak diinginkan (breaking change).
Contoh Enum dengan Reserved Numbers
enum UpdateStatus {
UNKNOWN = 0;
PENDING = 1;
COMPLETED = 2;
// Reserved untuk future use
reserved 100 to 199;
}
Jika nanti di-protobuf definition ada status baru, tinggal tambahkan pada angka di blok reserved. Selain itu, reserved numbers mencegah external developer mengisi enum tersebut dengan nilai 100 - 199 (di plugin atau distribusi custom), sehingga integritas protokol tetap terjaga.
Simulasi Error Ketika Melanggar Reserved
// Ini akan error!
enum UpdateStatus {
UNKNOWN = 0;
RESERVED2 = 120; // <--- Error, masuk di blok reserved
reserved 100 to 199;
}
Protobuf compiler akan mengeluarkan error, menjaga implementasi tetap disiplin.
5. Reserved Fields di API & JSON
Tak hanya di protokol atau binary, reserved fields sering diadopsi pada REST API berbasis JSON.
Format respons:
{
"result": "ok",
"device_id": 12345,
"reserved": null
}
Di dokumennya dicatat: “Field ‘reserved’ boleh diabaikan, namun wajib disertakan untuk kompatibilitas ke depan.”
Manfaatnya? Ketika v2 rilis, field itu bisa mulai diisi makna baru, tanpa perubahan besar di sisi klien maupun server lama.
6. Reserved Fields/Numbers di Dunia Nyata
TCP/IP Options:
Di header paket TCP, terdapat field ‘Reserved’ 6 bit. RFC menginstruksikan agar nilainya 0, serta diabaikan oleh penerima—siap dipakai untuk future options (sampai kini sebagian memang belum pernah dipakai).
HTTP Header:
Banyak header custom didahului dengan ‘X-’, yang kemudian menjadi konvensi reserved area untuk vendor header, sebelum terstandarisasi.
7. Best Practices Reserved Fields & Numbers
Selalu isi reserved fields dengan nilai default (zero/NULL).
Pengisi field harus tetap disiplin bahkan jika field tidak digunakan.Jangan assign makna pada reserved di versi saat ini.
Penjelasan di dokumentasi dan comment harus explisit:// reserved, do not use - for future compatibility
Gunakan reserved numbers untuk “menghalangi” external/plug-in abuse.
Misal: enum 0-100 untuk protokol inti, 200-250 reserved untuk experimental/extension internal.Dokumentasi adalah wajib.
Without documentation, reserved field/number malah membingungkan developer berikutnya.
Kesimpulan
Reserved fields dan reserved numbers adalah strategi matang untuk menjaga agar protokol, API, dan sistem data tetap scalable dan compatible di masa depan. Seperti menyiapkan lahan kosong di sebelah rumah, reserved fields memungkinkan ekspansi tanpa mengusik struktur lama.
Sebagai engineer, disiplin dan transparansi dalam memelihara reserved spot adalah bagian dari engineering culture yang baik. Baik untuk versi berikutnya, maupun untuk generasi developer yang akan datang.
Referensi
✨ Semoga artikel ini membantumu dalam mendesain protokol atau API yang tahan masa depan.
Artikel Terhangat
26 Apa Itu Mutation dan Kapan Digunakan?
07 Jul 2025
48 Custom Options di Protobuf
07 Jul 2025
47 Reserved Fields dan Reserved Numbers
07 Jul 2025
23 Modularisasi File Resolver dan Skema
07 Jul 2025
45 Cara Menggunakan `option` di Protobuf
07 Jul 2025

26 Apa Itu Mutation dan Kapan Digunakan?

48 Custom Options di Protobuf

47 Reserved Fields dan Reserved Numbers

23 Modularisasi File Resolver dan Skema
