FluentStack

Service Layer

Mode tersedia: dark, light, paper
MasukDaftar
Advanced · Level 16: Frontend ArchitectureAdvanced65 menitBahasa Indonesia

Service Layer

Memisahkan request, mapping response, dan error boundary dari component UI agar feature lebih mudah diuji serta diubah.

StatusMemuat progres
ProgresMemuat...

...

Memuat progres

Menyiapkan langkah berikutnya

Tujuan belajar

  • Menjelaskan service function sebagai boundary data access yang kecil dan jelas
  • Memisahkan request atau SDK call dari component presentation
  • Menempatkan mapping response dekat source data atau feature yang memakainya
  • Membedakan service layer sederhana dari abstraction data yang berlebihan
Service LayerData AccessTypeScriptTesting

Isi lesson

6 blok
  1. 1.
    Component sebaiknya tidak perlu mengetahui detail transport dataBelum selesaiWajib
  2. 2.
    UI memakai operation product, bukan response mentahBelum selesaiWajib
  3. 3.
    Coding practiceBelum selesaiWajib
  4. 4.
    Cek pemahamanBelum selesaiWajib
  5. 5.
    Jangan menyembunyikan failure sebagai data kosongBelum selesaiOpsional
  6. 6.
    RingkasanBelum selesaiWajib

Component sebaiknya tidak perlu mengetahui detail transport data

Wajib

Component UI perlu menjelaskan apa yang dilihat dan dilakukan user. Ketika ia juga membangun URL, memanggil SDK, membedakan response mentah, memetakan data, dan memilih error teknis, component menjadi sulit dibaca serta sulit diuji. Service function memberi nama pada operation product seperti getSavedCourses atau updateProfile. Ia menjadi satu tempat kecil untuk request, response mapping, dan error contract yang relevan. UI tetap menentukan loading, error, empty, dan success state. Jangan membuat service layer menjadi framework internal: satu function untuk satu operation yang jelas sering lebih baik daripada generic repository dengan banyak parameter yang tidak dipahami feature.

Bagian ini memengaruhi progres lesson.

UI memakai operation product, bukan response mentah

Wajib
ts
type CourseSummary = {
  id: string;
  title: string;
};

type CourseResponse = {
  id: string;
  name: string;
};

export async function getSavedCourses(userId: string): Promise<CourseSummary[]> {
  const response = await fetch("/api/users/" + userId + "/saved-courses");
  const courses = (await response.json()) as CourseResponse[];

  return courses.map((course) => ({
    id: course.id,
    title: course.name,
  }));
}

Service memberi UI data shape yang ia butuhkan: id dan title. Jika endpoint atau SDK berubah, mapping dapat ditinjau di satu tempat tanpa memaksa CourseList memahami field transport seperti name. Error policy yang dipilih service perlu tetap jujur bagi caller; jangan menelan failure lalu mengembalikan array kosong karena UI akan salah membaca error sebagai empty state.

Bagian ini memengaruhi progres lesson.

Coding practice

WajibDibuka di workspace khusus

Extract course service function

Pindahkan request dan mapping saved courses ke service function yang mengembalikan shape UI sederhana.

Tujuan awal: Fokus di tab TS.

Practice ini dibuka di workspace khusus. Buka practice untuk memakai editor, preview, dan cek otomatis.

Tombol selesai aktif setelah semua validasi wajib lolos.

7 cek otomatis5 checklist
Belum selesaiBuka practice

Cek pemahaman

WajibJawab dulu

Cek pemahaman singkat

Tanggung jawab yang paling tepat untuk service getSavedCourses adalah

Progres lesson naik setelah jawaban benar.

Peringatan

Opsional

Jangan menyembunyikan failure sebagai data kosong

return [] ketika network gagal dapat membuat UI menampilkan Belum ada course padahal data tidak dapat dimuat. Tentukan error contract yang dapat direspons caller, misalnya throw error yang jelas atau result type yang membedakan success dan failure. Ini lebih penting daripada menambahkan layer generik baru.

Opsional, tidak menghambat penyelesaian lesson.

Ringkasan

Wajib
  • Service function memberi nama pada operation data yang dimiliki feature.
  • Request dan mapping response tidak perlu memenuhi component presentasi.
  • UI tetap memiliki loading, error, empty, success, serta event behavior untuk user.
  • Error harus dibedakan dari data kosong agar user mendapat feedback yang benar.
  • Berikutnya, kita menempatkan type dan static content di owner yang tepat agar import tidak menyebar tanpa arah.

Bagian ini memengaruhi progres lesson.

Langkah berikutnya

Selesaikan bagian penting lesson ini

Lanjutkan blok wajib berikutnya: Component sebaiknya tidak perlu mengetahui detail transport data.