Belajar Angular - API Communication & Caching
Episode 14 of 24

Belajar Angular - API Communication & Caching

Episode ini membahas komunikasi API dan caching: HTTP interceptors untuk penanganan error terpusat, strategi caching untuk API responses, state transfer dan server-side rendering cache, serta optimasi performa network requests.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Di episode 8 kalian belajar dasar HTTP. Sekarang saatnya membuat komunikasi API kalian profesional: penanganan error yang terpusat, caching yang cerdas, dan request yang ringan.

Episode 14 membahas HTTP interceptors untuk penanganan error terpusat, strategi caching untuk API responses, state transfer dan SSR cache, serta optimasi performa network requests. Ini jembatan dari aplikasi yang berfungsi menjadi aplikasi yang tangguh.

HTTP Interceptors dan Centralized Error Handling

Interceptor untuk Logging dan Error

Interceptor menangkap setiap request dan response HTTP, jadi tempat ideal untuk logika silang seperti error handling. Bentuk fungsional sejak Angular 17:

JSInterceptor error handling terpusat
import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { catchError, throwError } from 'rxjs';
import { NotifService } from './notif.service';
 
export const errorInterceptor: HttpInterceptorFn = (req, next) => {
  const notif = inject(NotifService);
 
  return next(req).pipe(
    catchError((err: HttpErrorResponse) => {
      if (err.status === 401) {
        notif.tampil('Sesi habis, silakan login kembali', 'error');
      } else if (err.status >= 500) {
        notif.tampil('Terjadi kesalahan server', 'error');
      }
      console.error(`[${err.status}] ${req.method} ${req.url}`);
      return throwError(() => err);
    }),
  );
};

errorInterceptor menangani semua error dari semua request di satu tempat: status 401 memberi tahu sesi habis, status 5xx menampilkan pesan server. Tidak ada lagi try-catch di setiap service — cukup daftarkan interceptor di provideHttpClient(withInterceptors([errorInterceptor])).

Urutan Interceptor

Interceptor berjalan sesuai urutan pendaftaran untuk request dan terbalik untuk response. Interceptor auth sebaiknya dipasang sebelum error interceptor agar request selalu membawa token saat error dihitung.

Caching Strategies untuk API Responses

Cache di Level Stream

Caching mencegah request berulang untuk data yang sama. Pendekatan RxJS paling sederhana adalah shareReplay seperti di episode 8, tetapi perlu kebijakan pembaruan:

JSCache dengan TTL sederhana
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, shareReplay, tap, timer, switchMap } from 'rxjs';
 
@Injectable({ providedIn: 'root' })
export class KatalogService {
  private readonly http = inject(HttpClient);
  private cache$: Observable<Produk[]> | null = null;
  private readonly ttl = 300000;
 
  listar(): Observable<Produk[]> {
    if (!this.cache$) {
      this.cache$ = this.http.get<Produk[]>('/api/produk').pipe(
        shareReplay(1),
        switchMap((data) =>
          timer(this.ttl).pipe(switchMap(() => this.cache$ = null)),
        ),
      );
    }
    return this.cache$;
  }
}

Setelah lima menit (TTL 300000 milidetik), cache$ di-set ke null sehingga request berikutnya dijalankan ulang. Ini memberi keseimbangan antara responsivitas dan kesegaran data.

Cache Invalidation

Cache harus bisa dibatalkan saat data berubah. Metode umum: method invalidate() yang meng-set cache$ = null, dipanggil setelah operasi create, update, atau delete. Untuk data yang sering berubah, pertimbangkan cache berbasis tag atau key dengan pustaka khusus.

State Transfer dan Server-side Rendering Cache

State Transfer dengan TransferState

Saat halaman di-render di server (SSR), data yang sama bisa langsung dipindahkan ke browser sehingga klien tidak perlu request ulang. Angular menyediakan TransferState:

JSTransferState untuk SSR
import { Injectable, inject, TransferState, makeStateKey } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { of, tap } from 'rxjs';
 
const PRODUK_KEY = makeStateKey<Produk[]>('produk-lengkap');
 
@Injectable({ providedIn: 'root' })
export class ProdukService {
  private readonly http = inject(HttpClient);
  private readonly state = inject(TransferState);
 
  listar() {
    const cached = this.state.get(PRODUK_KEY, null);
    if (cached) {
      return of(cached);
    }
    return this.http.get<Produk[]>('/api/produk').pipe(
      tap((data) => this.state.set(PRODUK_KEY, data)),
    );
  }
}

Di server, data diambil dan disimpan ke TransferState. Di browser, nilai langsung dibaca dari state sehingga tidak ada request kedua. Ini menghilangkan jeda dan mengurangi beban API untuk halaman yang sama.

SSR Cache

Hasil render SSR itu sendiri bisa di-cache di CDN atau server. Halaman publik dengan data jarang berubah bisa disimpan sebagai cache statis dengan TTL tertentu, sementara halaman yang personalisasi tetap dirender per request.

Performance Network Requests

Penggabungan dan Paralelisasi

Kurangi jumlah round-trip: gabungkan beberapa request yang independen dengan forkJoin, dan batalkan request yang sudah tidak relevan dengan switchMap. Kirim payload yang lebih kecil — minta hanya field yang dibutuhkan lewat query param atau sparse fields.

JSMenggabungkan request paralel
import { forkJoin } from 'rxjs';
 
forkJoin({
  profil: this.http.get<Profil>('/api/profil'),
  order: this.http.get<Order[]>('/api/order?limit=10'),
}).subscribe(({ profil, order }) => {
  this.profil.set(profil);
  this.order.set(order);
});

forkJoin menunggu semua request selesai lalu mengembalikan satu objek gabungan — satu subscription untuk dua request paralel. Ini memangkas waktu tunggu dibanding memuat satu per satu.

Mengukur dan Mengamati

Selalu ukur: pantau jumlah request per halaman, ukuran payload, dan waktu respons di jaringan yang lambat. Gunakan HttpClient dengan withFetch untuk performa fetch API, dan periksa waterfall network di DevTools untuk menemukan request yang boros atau berurutan padahal bisa paralel.

Penutup

Inti yang harus dibawa pulang:

  • Interceptor adalah satu tempat untuk penanganan error dan logging terpusat.
  • shareReplay plus TTL memberikan cache sederhana dengan pembaruan otomatis.
  • Sediakan metode invalidate untuk membatalkan cache saat data berubah.
  • TransferState memindahkan data dari server ke browser sehingga SSR tanpa request ganda.
  • Cache hasil render SSR di CDN untuk halaman publik yang jarang berubah.
  • Gabungkan request paralel dengan forkJoin dan ukur performa secara rutin.

Di episode 15 selanjutnya kita akan membahas performance optimization — profiling dengan Angular DevTools, strategi change detection Default versus OnPush, trackBy dan lazy loading untuk code splitting, serta analisis bundle dan optimasi production.

Belajar Angular - API Communication & Caching | Belajar Angular