Episode ini mengajarkan Spring Web MVC untuk membangun REST API: @RestController dan @RequestMapping, cara menangkap path variable, request param, request body, dan headers, hingga penggunaan ResponseEntity dengan status code dan serialisasi JSON.

Di episode 3 kalian membuat endpoint pertama yang mengembalikan teks. Sekarang kita membangun fondasi yang sesungguhnya: REST API yang menerima input dari berbagai sumber, mengembalikan data dalam format JSON, dan memberikan status code yang benar.
Spring Web MVC adalah modul yang menangani seluruh request HTTP. Di episode ini kalian akan menguasai @RestController, berbagai cara menangkap parameter request, serta ResponseEntity untuk mengontrol respons secara penuh — keterampilan yang dipakai di hampir semua aplikasi backend.
Annotation @RestController menggabungkan @Controller dengan @ResponseBody: setiap nilai yang dikembalikan method secara otomatis diserialisasi menjadi JSON atau XML. Untuk memetakan URL, gunakan @RequestMapping — bisa di level class untuk prefix, atau di level method bersama dengan @GetMapping, @PostMapping, @PutMapping, dan @DeleteMapping.
@RestController
@RequestMapping("/api/items")
public class ItemController {
@GetMapping
public List<Item> listItems() {
return List.of(new Item(1L, "Laptop"));
}
}Kelas di atas menangani semua request GET /api/items. Objek Item yang dikembalikan akan diserialisasi menjadi JSON oleh Jackson secara otomatis — tanpa konfigurasi tambahan.
Data dari URL bisa diambil dengan dua annotation. Path variable menangkap segmen di dalam path, sedangkan request param menangkap nilai dari query string:
@GetMapping("/{id}")
public Item getItem(@PathVariable Long id) {
return itemService.findById(id);
}
@GetMapping("/search")
public List<Item> search(@RequestParam String q,
@RequestParam(defaultValue = "10") int limit) {
return itemService.search(q, limit);
}Untuk GET /api/items/search?q=laptop&limit=5, nilai q menjadi laptop dan limit menjadi 5. Parameter yang tidak wajib diisi diberi defaultValue.
Untuk membuat atau memperbarui data, kirim payload JSON di body request dan tangkap dengan @RequestBody. Baca header tertentu dengan @RequestHeader:
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Item createItem(@RequestBody ItemRequest request,
@RequestHeader("X-Client-Id") String clientId) {
return itemService.create(request, clientId);
}Annotation @ResponseStatus(HttpStatus.CREATED) menetapkan kode status 201 untuk respons sukses. Jackson memetakan field JSON di body ke field class ItemRequest secara otomatis — detail validasi akan dibahas di episode 7.
Terkadang kalian perlu mengontrol status code, headers, dan body secara bersamaan. Di sinilah ResponseEntity berperan. Contoh endpoint yang mencari data dan mengembalikan 404 jika tidak ditemukan:
@GetMapping("/{id}")
public ResponseEntity<Item> getItem(@PathVariable Long id) {
return itemService.findById(id)
.map(item -> ResponseEntity.ok(item))
.orElse(ResponseEntity.notFound().build());
}Gaya ini membuat API kalian mengikuti konvensi HTTP dengan benar: 200 OK untuk sukses, 404 Not Found untuk data yang tidak ada, dan seterusnya. Konsistensi status code sangat penting agar API bisa dikonsumsi dengan baik oleh client.
Jackson adalah serialiser default Spring Boot. Kalian bisa mengontrol bentuk JSON yang dikeluarkan lewat annotation pada field, misalnya menyembunyikan field sensitif:
public class Item {
private Long id;
private String name;
@JsonIgnore
private String internalNote;
}Field internalNote dengan @JsonIgnore tidak akan muncul di JSON — berguna untuk field internal yang tidak ingin diekspos ke client. Untuk penamaan field, Spring Boot secara default memakai camelCase; konfigurasi spring.jackson memungkinkan kustomisasi lebih lanjut.
Seluruh endpoint di atas bisa diuji langsung lewat terminal:
curl http://localhost:8080/api/items
curl -X POST http://localhost:8080/api/items \
-H "Content-Type: application/json" \
-H "X-Client-Id: web" \
-d '{"name":"Laptop"}'Perintah curl -X POST http://localhost:8080/api/items -H "Content-Type: application/json" -d '{"name":"Laptop"}' mengirim payload JSON dan memicu endpoint createItem. Amati respons JSON yang dikembalikan — itulah hasil serialisasi Jackson.
Terjadi ketika request body JSON tidak disertai header Content-Type: application/json. Selalu sertakan header ini saat mengirim data.
Terjadi ketika nilai parameter tidak cocok dengan tipe — misalnya mengirim teks ke parameter Long. Periksa tipe data parameter dan pastikan nilainya valid. Untuk pesan error yang ramah, kita akan membangun global exception handling di episode 7.
Episode 5 membekali kalian dengan kemampuan membangun REST API menggunakan Spring Web MVC: @RestController dan @RequestMapping, menangkap path variable, request param, request body, dan headers, mengontrol status code dengan ResponseEntity, serta memahami serialisasi JSON oleh Jackson.
Inti yang harus dibawa pulang:
@RestController otomatis menyerialisasi nilai balik method menjadi JSON.@PathVariable, @RequestParam, @RequestBody, dan @RequestHeader menangkap input dari URL dan body.ResponseEntity memberi kontrol penuh atas status code, headers, dan body.@JsonIgnore untuk menyembunyikan field.Content-Type: application/json saat mengirim payload.curl untuk memastikan status code dan bentuk JSON.Di episode 6 selanjutnya kita akan membahas data access dan repositori — Spring Data JPA dengan @Entity dan CrudRepository, query method otomatis, custom query dengan @Query, konfigurasi datasource, hingga database in-memory H2 untuk testing. API kalian akan mulai menyimpan data sungguhan.