Lompat ke konten utama
Mobile Capacitor

Contoh API TypeScript untuk Capacitor dan Capgo

Pelajari contoh API TypeScript praktis untuk plugin Capacitor dan Capgo. Kuasai typed interfaces, listener patterns, dan strategi implementasi.

Contoh API TypeScript untuk Capacitor dan Capgo

Setiap contoh API TypeScript yang bagus untuk Capacitor dimulai dengan cara yang sama: menggunakan typed plugin interface. Definisikan method, opsi, dan hasil Promise secara eksplisit, sehingga web code dan native layer Anda berbagi satu kontrak yang ditegakkan oleh TypeScript.

Table of Contents

Build Interface Plugin Capacitor yang Strongly Typed

Interface ini mendeskripsikan API yang dilihat oleh web code Anda. Implementasi native di baliknya harus mematuhi kontrak tersebut — dan TypeScript akan mengecek nama method, parameter, serta return value sebelum app Anda dijalankan.

import { registerPlugin } from ‘@capacitor/core’;

export interface DeviceStatus {\nonline: boolean;\nbatteryLevel?: number;\n}

export interface DevicePlugin {\ngetStatus(): Promise}; setLabel(options: { label: string }): Promise<{ saved: boolean }> }

export const Device = registerPlugin(‘Device’);

Banyak hal yang terjadi dalam beberapa baris ini:

  • Tipe return eksplisit menjaga setiap hasil tetap predictable.
  • Objek opsi bertipe data tangkap properti yang hilang atau salah ketik saat compile time.
  • Metode berbasis Promise memodelkan kerja native yang selesai secara asinkron.
  • Sebuah generic registerPlugin panggilan adalah penghubung antara web API ke native bridge.
  • Interfaces mendokumentasikan kontrak tanpa menambah satu byte pun runtime code.

Setiap call site mendapatkan perlakuan yang sama:

const status = await Device.getStatus(); console.log(status.online);

await Device.setLabel({ label: ‘Production’ });

Tukar { label: 'Production' } untuk { name: 'Production' } dan compiler akan langsung menandainya. Ini jauh lebih baik daripada baru menyadari adanya mismatch setelah rilis mobile.

Interface juga digunakan untuk memodelkan nilai opsional dan kasus error. Jika sebuah native method tidak selalu bisa menghasilkan pembacaan baterai, batteryLevel?: number memberitahu setiap caller untuk menangani undefined.

Diagram di bawah menunjukkan bagaimana typed methods, options, return values, bridge definitions, dan compile-time checks terhubung di dalam Capacitor API.

Diagram yang mengilustrasikan manfaat utama dari interface plugin TypeScript yang strongly-typed untuk framework pengembangan mobile.

Ide utamanya: definisi tipe mengalir dari web-facing interface menuju logika platform native, dan compile-time checks menjaga setiap call site.

Quick Lookup untuk Desain API

Elemen Kegunaan Contoh
Signature method Menentukan perilaku callable getStatus()
Tipe opsi Mengontrol bentuk input { label: string }
Hasil Promise Merepresentasikan proses async Promise<DeviceStatus>
Interface hasil Menentukan data yang dikembalikan online: boolean

Untuk referensi lebih dalam, baca panduan membangun API di TypeScript. Dua kebiasaan penting: jangan sertakan rahasia dan kredensial tanda tangan di client code, dan uji interface terhadap implementasi tiap platform sebelum Anda publish.

Tim mobile harus mengelola JavaScript, native code, izin perangkat, dan layanan platform asinkron secara bersamaan. Sebuah kontrak TypeScript yang kuat berfungsi seperti checklist bersama di setiap batasan tersebut, membuat ekspektasi menjadi eksplisit sebelum code mendarat di perangkat iOS atau Android.

Seseorang sedang coding di laptop yang menampilkan code di atas meja di samping cangkir kopi.

Untuk contoh contoh API TypeScript yang baguskonkret, bandingkan metode yang mengembalikan Promise<DeviceStatus> dengan metode yang mengembalikan data tanpa tipe (untyped). Versi bertipe memberi tahu editor dan setiap reviewer secara tepat field mana saja yang ada. Versi untyped memaksa proses penemuan tersebut ke runtime logs, testing manual, atau yang terburuk, insiden produksi.

Sinyal Adopsi

TypeScript telah berkembang jauh melampaui niche front-end. Adopsinya melonjak hingga 35% developer di tahun 2024, naik dari hanya 12% pada 2017, dan lebih dari satu juta kontributor GitHub menjadikannya bahasa utama pada tahun 2025. Pelajari selengkapnya di Temuan adopsi TypeScript jika Anda ingin melihat angka mentahnya.

Tren ini sangat berpengaruh bagi organisasi mobile secara praktis. Proses hiring, onboarding, dan review code semakin bergantung pada shared types. Developer baru di proyek Capacitor bisa membaca interface dan memahami perilaku native yang diharapkan tanpa harus menelusuri setiap implementasi.

Typed API juga mempermudah logika saat rilis. Ketika sebuah method membutuhkan objek options tertentu, properti yang diubah namanya atau field yang hilang akan error saat compile time, bukan malah menghasilkan native request yang tidak lengkap secara diam-diam.

Strong typing mempercepat feedback kritis, di mana perbaikan hanya butuh hitungan menit, bukan rilis hotfix darurat.

Keuntungan bagi Tim Capacitor

Aplikasi cross-platform biasanya mengekspos satu API berbasis web di atas beberapa implementasi native. TypeScript tidak bisa menjamin setiap detail native berperilaku identik, tapi TypeScript bisa menjaga konsistensi pemanggilan fungsi di seluruh aplikasi Anda.

Terapkan tipe eksplisit pada:

  • Input dari method, termasuk opsi wajib dan opsional
  • Hasil Promise, agar data sukses selalu punya struktur yang dapat diprediksi
  • Event dan listener, agar callback menangani payload yang sudah diketahui
  • Error dan nilai status, agar jalur fallback tetap terlihat

Struktur tersebut sangat berguna saat mengintegrasikan plugin device atau layanan operasional. Ini juga membantu tim saat meninjau otomatisasi update, di mana kesalahan channel, bundle identifier, atau field kompatibilitas dapat berdampak luas ke basis pengguna.

Untuk pembahasan lebih dalam mengenai pola terkait, baca panduan kami dalam membuat API bertipe dengan OpenAPI. Ini menjelaskan bagaimana definisi bersama mengurangi pergeseran manual yang biasanya muncul antara dokumentasi API dan code aplikasi.

Menyusun Business Case

Strict typing memang menuntut investasi awal, terutama saat JavaScript code lama memiliki bentuk data yang tidak konsisten. Hasilnya terasa seiring waktu: refactor lebih kecil, kepemilikan lebih jelas, dan jauh lebih sedikit kejutan integrasi.

Mulailah dari batasan yang paling berisiko:

  1. Definisikan interface response untuk panggilan native dan remote.
  2. Beri tipe pada object options dan payload event.
  3. Aktifkan strict compiler checks secara bertahap.
  4. Wajibkan type checks sebelum mempublikasikan update apa pun.

Bagi tim mobile enterprise, fondasi ini menjaga maintenance tetap bisa diprediksi lintas platform, rilis, dan kontributor.

ScreenOrientationPlugin milik Capacitor menjadi contoh API TypeScript yang bagus karena ia memetakan beberapa metode web sederhana ke perilaku perangkat yang spesifik platform. Kontrak publiknya tetap identik di semua platform, sementara iOS dan Android menangani detail native masing-masing di balik layar.

import { registerPlugin } from ‘@capacitor/core’;

export type OrientationType =\n| ‘portrait-primary’\n| ‘portrait-secondary’\n| ‘landscape-primary’\n| ‘landscape-secondary’;

export interface OrientationData {\ntype: OrientationType;\nangle: number;\n}

export interface LockOptions { orientation: OrientationType; }

export interface ScreenOrientationPlugin { orientation(): Promise};\nlock(options: LockOptions): Promise;\nunlock(): Promise;\naddListener(\neventName: ‘screenOrientationChange’,\nlistenerFunc: (data: OrientationData) =&gt; void,\n): Promise&lt;{ remove: () =&gt; Promise }&gt;; }

export const ScreenOrientation =\nregisterPlugin(‘ScreenOrientation’);

Berikut referensi cepat untuk tiap signature:

  • orientation() — membaca orientasi saat ini secara asinkron
  • lock() — hanya menerima nilai orientasi yang valid
  • unlock() — mengembalikan kontrol ke perilaku perangkat normal
  • addListener() — mengirimkan payload bertipe saat orientasi berubah

Karena setiap method mengembalikan Promise, Anda bisa menggunakan pola pemanggilan yang sama baik pada native bridge maupun implementasi browser. Tanpa percabangan, tanpa kasus khusus.

const current = await ScreenOrientation.orientation();

if (current.type.startsWith(‘landscape’)) {\nconsole.log("}Angle: ${current.angle}); }

await ScreenOrientation.lock({ orientation: 'landscape-primary', });

Ketik nilai yang salah ketik seperti landscape-main dan build akan langsung gagal. Ini adalah compile error yang bisa diperbaiki dalam hitungan detik — bukan bug runtime spesifik platform yang harus dicari lewat device logs.

Ketik Argumen Listener dengan Benar

Listener layak mendapatkan ketelitian yang sama dengan method biasa. Hindari any di sini, karena ini menyembunyikan perbedaan antara payload event dan hasil orientation() returns.

const handleChange = (data: OrientationData) => { document.body.dataset.orientation = data.type; };

const subscription = await ScreenOrientation.addListener(\n‘screenOrientationChange’,\nhandleChange,\n);

await subscription.remove();

Hanya gunakan satu OrientationData type saat kedua implementasi native menjamin field yang sama. Jika satu platform tidak menyertakan angle, buat menjadi opsional dan paksa pemanggil untuk menangani undefined.

Pilihan desain Pola yang lebih aman
Input Interface opsi bernama
Hasil Tipe Promise eksplisit
Event Nama event literal
Bersihkan Kembalikan subscription yang bisa dihapus

Interface adalah kontrak jembatan, bukan implementasi native. Buatlah tetap kecil, terprediksi, dan mudah diuji.

Untuk perilaku platform, izin, dan langkah instalasi, baca panduan plugin Capacitor Screen Orientation. Satu kebiasaan terakhir yang patut dicoba: uji panggilan valid maupun rejected di bawah pengaturan TypeScript yang ketat. Kombinasi ini akan menangkap kesalahan nama method, field yang hilang, dan payload listener yang tidak kompatibel jauh sebelum Anda memaketkan aplikasi mobile Anda.

Capgo memberikan Capacitor tim cara untuk push perbaikan JavaScript, CSS, konfigurasi, dan asset tanpa harus menunggu review app store. Kuncinya adalah memperlakukan update pipeline-nya seperti boundary API bertipe lainnya, sehingga channel, aturan rollout, pengecekan kompatibilitas, dan keputusan rollback tetap eksplisit sebelum bundle sampai ke perangkat pengguna.

Seseorang memegang smartphone yang menunjukkan perbedaan antara mode orientasi layar portrait dan landscape.

Definisikan Update Contracts

Mulailah dengan menentukan nilai apa saja yang diterima oleh otomatisasi Anda. Literal unions mencegah Anda salah deploy ke channel yang tidak sesuai, dan interface membuat hubungan antara bundle dan versi native yang dibutuhkan menjadi self-documenting.

type Channel = ‘beta’ | ‘staging’ | ‘production’;

interface UpdateRequest {\nchannel: Channel;\nbundleVersion: string;\nminNativeVersion: string;\nrolloutPercent: number;\nsigned: boolean;\n}

interface UpdateResult {\naccepted: boolean;\nappliedOnNextLaunch: boolean;\nrollbackEnabled: boolean;\n}

Sebuah cara simpel contoh API TypeScript yang bagus memvalidasi request sebelum diteruskan ke client Capgo:

async function publishUpdate(\nrequest: UpdateRequest,\n): Promise { if (!request.signed || request.rolloutPercent < 0 || request.rolloutPercent > 100) { throw new Error(‘Unsafe update request’); }

return capgo.publish(request);\n}

Nama metode client bisa berubah di antara versi Capgo SDK, jadi bungkuslah dengan interface Anda sendiri. Isolasi ini akan sangat berguna setiap kali Anda melakukan upgrade dan mencegah detail spesifik vendor bocor ke seluruh codebase Anda.

Proteksi Channel dan Kompatibilitas

Memilih channel tidak boleh sembarangan. Rilis produksi membutuhkan pengecekan yang lebih ketat daripada eksperimen beta, terutama saat web bundle memanggil kemampuan native yang belum ada di versi aplikasi sebelumnya.

function canDeploy( request: UpdateRequest, installedNativeVersion: string, ): boolean { return request.signed && installedNativeVersion >= request.minNativeVersion; }

Jangan bandingkan versi menggunakan string biasa. Gunakan library semantic-version yang tepat agar 1.10.0 mengurutkan setelah 1.9.0. Sebelum masuk ke channel, jalankan checklist berikut:

  1. Pastikan bundle sudah ditandatangani (signed).
  2. Verifikasi channel target sudah sesuai tujuan.
  3. Bandingkan rentang kompatibilitas native dan bundle.
  4. Publish ke audiens terbatas terlebih dahulu.
  5. Pantau sinyal kegagalan dan siapkan rollback.

Pipeline update bertipe mengubah kebijakan rilis menjadi code yang benar-benar bisa diperiksa reviewer dan CI.

Differential delivery dan kontrol channel dari Capgo cocok masuk ke pola tersebut, serta observability di level device memungkinkan tim melacak sinyal adopsi atau kegagalan setelah kejadian. Untuk sisi instrumentasi event, lihat panduan custom event tracking dengan Capgo ini.

Signing keys dan kredensial admin harus berada di server atau sistem CI, bukan di dalam aplikasi. Terapkan update saat peluncuran berikutnya, uji rollback dengan bundle yang sengaja ditolak, dan catat setiap keputusan dengan typed result. Kombinasi ini menjaga pengiriman cepat tetap kompatibel dengan kontrol rilis mobile yang disiplin.

Typed listener-lah yang membuat API asinkron mudah dipercaya. Baik callback yang melacak orientasi layar maupun event update Capgo, callback harus menerima bentuk payload yang sama di setiap platform — dan compiler-lah yang seharusnya menegakkannya.

interface UpdateEvent {\nversion: string;\nchannel: ‘beta’ | ‘production’;\navailable: boolean;\n}

tipe Listener = (payload: T) =&gt; void;

interface UpdateService {\naddListener(\nevent: ‘updateAvailable’,\ncallback: Listener,\n): Promise&lt;{ remove: () =&gt; Promise }&gt;;\nremoveAllListeners(): Promise; }

Ini contoh API TypeScript yang bagus mengunci nama event ke literal dan menghubungkan callback ke payload bertipe. Editor Anda akan memberikan autocomplete version secara gratis, dan compiler akan menolak callback yang mengharapkan data tidak terkait. Setup-nya simpel, tapi sangat berguna setiap kali API berubah.

Ingin melihat langsung cara kerjanya? Tonton tutorialnya:

Registrasi Listener dengan Aman

Di dalam komponen, simpan subscription handle agar proses cleanup tetap eksplisit. Pola yang sama bisa langsung diterapkan pada lifecycle hooks Angular, React effects, dan Vue mount hooks tanpa perubahan.

let orientationHandle: { remove: () => Promise } | undefined;

async function start() { orientationHandle = await ScreenOrientation.addListener( ‘screenOrientationChange’, ({ type, angle }) => { console.log(type, angle); }, ); }

async function stop() {\nawait orientationHandle?.remove();\norientationHandle = undefined;\n}

Jalankan cleanup saat layar menghilang — bukan hanya saat aplikasi ditutup. Jika dilewatkan, navigasi akan membiarkan callback tetap menempel pada native event sources. Akibatnya, terjadi duplikasi kerja dan update state yang usang yang sulit dilacak.

Setiap framework menyediakan hook untuk ini:

  • Angular — trigger cleanup dari ngOnDestroy
  • React — mengembalikan fungsi cleanup async-safe dari useEffect
  • Vue — menghapus subscription di onBeforeUnmount

Setiap addListener call harus memiliki jalur penghapusan yang sesuai.

Pilih Metode Cleanup yang Tepat

Handle yang dikembalikan adalah pilihan tepat jika satu komponen memiliki satu subscription. removeAllListeners() sangat berguna saat sebuah service memegang beberapa listener dan sedang di-reset sepenuhnya.

async function resetUpdates(service: UpdateService) { await service.removeAllListeners(); }

Jangan panggil method yang bersifat umum dari shared component jika layar lain masih bergantung pada service tersebut. Jika kepemilikannya bersifat lokal, gunakanlah secara individual remove() handle individu.

Situasi Rekomendasi tindakan
Satu subscription komponen Panggil handle.remove()
Layanan dimatikan Panggil removeAllListeners()
Registrasi berulang Inisialisasi guard
Payload tidak dikenal Validasi sebelum digunakan

Untuk notifikasi Capgo, pisahkan payload update dari event perangkat. Lalu uji registrasi, pengiriman, dan cleanup secara terpisah — Panduan pelacakan custom event Capgo punya info lebih lanjut soal sisi integrasi.

Sebelum rilis, cek tiga hal: unmounting benar-benar menghapus handler, rejected promise tertangani, dan tidak ada callback yang bisa mengupdate komponen yang sudah dihancurkan. Disiplin ini menjaga aplikasi Capacitor yang reaktif tetap responsif di Angular, React, dan Vue.

Seorang software developer profesional yang sedang mengerjakan code dengan setup dual-monitor sambil memakai headphone.

Sesuatu yang dibangun dengan baik contoh API TypeScript yang bagus dimulai dari nama yang menjelaskan intent. Gunakan kata kerja untuk method, kata benda untuk interface, dan pertahankan suffix yang konsisten seperti Options, Result, dan Event. Nama yang jelas mempercepat onboarding karena developer langsung paham kontraknya tanpa harus membuka implementasi.

Jaga interface publik tetap ringkas. Ekspos kapabilitas melalui method yang fokus daripada menumpuk operasi yang tidak terlalu terkait ke dalam satu objek.

  • getStatus() membaca state.
  • updateConfig(options) mengubah konfigurasi.
  • addListener(event, callback) berlangganan perubahan.

Tentukan Tipe Input dan Output Secara Presisi

Gunakan interface opsi bernama jika parameter berpotensi bertambah:

interface PublishOptions {\nchannel: ‘beta’ | ‘production’;\nrolloutPercent: number;\n}

interface PublishResult {\nversion: string;\naccepted: boolean;\n}

async function publish(\noptions: PublishOptions,\n): Promise {\nreturn client.publish(options);\n}

Generics sangat berguna saat API membungkus berbagai payload namun tetap perlu mempertahankan tipe data spesifiknya:

interface ApiResponse {\ndata: T;\nrequestId: string;\n}

async function request(path: string): Promise<ApiResponse>> { return fetchJson<ApiResponse>>(path); }

Tapi jangan asal tambah generics supaya terlihat fleksibel. Sebuah generic harus menunjukkan hubungan nyata antara input dan output — jika tidak, interface konkret akan lebih mudah dibaca dan dikelola.

Buat state yang tidak valid sulit direpresentasikan, terutama pada batas native, network, dan update.

Dokumentasikan perilaku tepat di samping kontraknya. Jelaskan izin, satuan, rejected promises, field opsional, dan apakah sebuah method berlaku langsung atau pada peluncuran berikutnya. Inline comments harus menjelaskan alasan pengambilan keputusan, bukan sekadar menulis ulang nama method.

Organisasi Code untuk Change

Pisahkan tipe, logika client, platform adapter, dan test ke dalam file yang terprediksi. Export tipe publik dari satu entry point dan jaga detail implementasi tetap private.

Concern Lokasi yang direkomendasikan
Antarmuka publik types.ts
metode API client.ts
Adapter Native platform/
Uji kompatibilitas tests/

Untuk perubahan plugin yang breaking, buatlah interface major baru atau layer kompatibilitas, pertahankan metode deprecated untuk sementara, dan tuliskan langkah migrasinya. Pelajari lebih lanjut tentang strategi versioning API sebelum mengubah consumer.

Jalankan strict type checks dan contract tests di CI sebelum rilis. Untuk workflow Capgo, verifikasi nilai channel, kompatibilitas native, signed bundles, dan perilaku rollback sebagai aturan rilis bertipe — ini menjaga fast updates tetap terkendali seiring berkembangnya tim, platform, dan integrasi.

Bagaimana Cara Mengetik Dynamic Native Results?

Jangan biarkan any data bocor ke code Anda saat metode native mengembalikan data yang tidak terprediksi. Sebaliknya, definisikan field yang pasti ada, tandai nilai yang benar-benar opsional dengan ?, dan sanitasi input yang tidak pasti di boundary sebelum diproses oleh bagian downstream lainnya.

interface NativeResult {\nsuccess: boolean;\nvalue?: string;\n}

async function readValue(): Promise {\nconst result = await NativePlugin.read();\nreturn {\nsuccess: Boolean(result.success),\nvalue: typeof result.value === ‘string’ ? result.value : undefined,\n};\n}

Pendekatan ini menjaga keamanan caller Anda sekaligus membuat ketidakpastian menjadi eksplisit dalam tipe datanya. Untuk melihat pola interface ini lebih luas, pelajari kembali membangun API di TypeScript.

Bagaimana Listener Bisa Menghindari Unhandled Rejections?

Callback asinkron harus bersifat defensif secara desain. Tangkap kegagalan di dalam listener itu sendiri daripada mengandalkan sistem event untuk menelan rejected promise secara diam-diam.

const handleUpdate = (event: UpdateEvent): void => { void applyUpdate(event).catch((error: unknown) => { console.error(‘Update failed’, error); }); };

Simpan referensi subscription dan hapus saat komponen unmount. Ini mencegah callback ganda dan update state yang usang — bagian listener lifecycle akan membahas ini secara detail.

Setiap listener asinkron membutuhkan error path dan cleanup path.

Bagaimana Cara Melindungi Capgo Updates?

Signing keys dan kredensial admin harus tetap di server atau sistem CI Anda. Titik. Client hanya boleh menerima signed bundle dan menggunakan typed results untuk menampilkan status — jangan pernah untuk membuat signature.

Sebelum publishing, siapkan channel union yang terpisah, jalankan pengecekan kompatibilitas, konfigurasi rollout limits, dan rencanakan jalur rollback Anda. Capgo menangani pengiriman bertanda tangan, kontrol channel, penerapan saat peluncuran berikutnya, dan perlindungan rollback untuk Capacitor serta aplikasi Electron. Dokumentasinya menunjukkan bagaimana workflow rilis bertipe dapat memperketat pipeline update Anda.

Live update untuk aplikasi Capacitor

Saat bug di web layer sudah live, kirim perbaikannya lewat Capgo alih-alih menunggu berhari-hari untuk persetujuan app store. Pengguna menerima update di background, sementara perubahan native tetap di jalur review normal.

Terbaru dari Blog kami

Capgo memberikan insight terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang benar-benar profesional.